AbstractDelegateBuilder   A
last analyzed

Complexity

Total Complexity 3

Size/Duplication

Total Lines 49
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 0
Metric Value
wmc 3
dl 0
loc 49
ccs 8
cts 8
cp 1
rs 10
c 0
b 0
f 0

2 Methods

Rating   Name   Duplication   Size   Complexity  
A getDelegate() 0 9 2
A build() 0 5 1
1
<?php
2
/**
3
 * Incoming
4
 *
5
 * @author    Trevor Suarez (Rican7)
6
 * @copyright (c) Trevor Suarez
7
 * @link      https://github.com/Rican7/incoming
8
 * @license   MIT
9
 */
10
11
declare(strict_types=1);
12
13
namespace Incoming\Hydrator;
14
15
use Incoming\Hydrator\Exception\InvalidDelegateException;
16
17
/**
18
 * An abstract builder that allows for the building to be delegated to another
19
 * callable. By default, a named method is attempted to be found, but any
20
 * callable could be returned through overrides.
21
 *
22
 * This enables a lot of interesting uses, most notably this allows builders to
23
 * be created that have strongly type-hinted building arguments while still
24
 * perfectly satisfying the `Builder`. Essentially this allows the bypassing of
25
 * the type variance rules enforced by PHP in a way that provides a
26
 * generics-like definition. Ultimately, if/when PHP gets generics this will no
27
 * longer be necessary, as one could simply implement a builder using typed
28
 * arguments like: `Builder<IncomingDataType, ModelType>`.
29
 *
30
 * @link http://en.wikipedia.org/wiki/Covariance_and_contravariance_(computer_science)
31
 * @link http://en.wikipedia.org/wiki/Generic_programming
32
 */
33
abstract class AbstractDelegateBuilder implements Builder
34
{
35
36
    /**
37
     * Constants
38
     */
39
40
    /**
41
     * The name of the default delegate method.
42
     *
43
     * @var string
44
     */
45
    const DEFAULT_DELEGATE_METHOD_NAME = 'buildModel';
46
47
48
    /**
49
     * Methods
50
     */
51
52
    /**
53
     * {@inheritdoc}
54
     *
55
     * @param mixed $incoming The input data.
56
     * @return mixed The built model.
57
     */
58 9
    public function build($incoming)
59
    {
60 9
        $callable = $this->getDelegate();
61
62 6
        return $callable($incoming);
63
    }
64
65
    /**
66
     * Get the delegate building callable.
67
     *
68
     * Override this method if a custom delegate is desired.
69
     *
70
     * @return callable The delegate builder callable.
71
     * @throws InvalidDelegateException If the delegate isn't callable.
72
     */
73 15
    protected function getDelegate(): callable
74
    {
75 15
        $delegate = [$this, static::DEFAULT_DELEGATE_METHOD_NAME];
76
77 15
        if (!is_callable($delegate, false, $callable_name)) {
78 3
            throw InvalidDelegateException::forNonCallable($callable_name);
79
        }
80
81 12
        return $delegate;
82
    }
83
84
    /**
85
     * The delegate build method.
86
     *
87
     * This doc-block and commented out abstract method is provided here to show
88
     * what the delegate method signature WOULD be if PHP allowed the proper
89
     * typing support to enable a generic definition in this manner.
90
     *
91
     * See the class description for more info.
92
     *
93
     * @param IncomingDataType $incoming The input data.
94
     * @return ModelType The built model.
95
     */
96
    // abstract protected function buildModel(IncomingDataType $incoming): ModelType;
97
}
98