Assembler::assemble()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 12

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 0
loc 12
rs 9.8666
c 0
b 0
f 0
1
<?php
2
/**
3
 * @author stev leibelt <[email protected]>
4
 * @since 2015-07-05 
5
 */
6
7
namespace Net\Bazzline\Component\Cli\Readline\Configuration;
8
9
use Closure;
10
use Net\Bazzline\Component\GenericAgreement\Data\AssemblageInterface;
11
use Net\Bazzline\Component\GenericAgreement\Exception\InvalidArgument;
12
use Net\Bazzline\Component\GenericAgreement\Process\ExecutableInterface;
13
14
class Assembler implements AssemblageInterface
15
{
16
    /** @var Executable */
17
    private $executable;
18
19
    /** @var Validator */
20
    private $validator;
21
22
    /**
23
     * @param mixed $data
24
     * @return mixed
25
     * @throws ExecutableInterface
26
     */
27
    public function assemble($data)
28
    {
29
        $validator = $this->validator;
30
31
        if ($validator->isValid($data)) {
32
            $configuration = $this->build($data);
33
        } else {
34
            throw new InvalidArgument($validator->getMessage() . PHP_EOL . $validator->getTrace());
35
        }
36
37
        return $configuration;
38
    }
39
40
    /**
41
     * @param Executable $executable
42
     * @return $this
43
     */
44
    public function setExecutable(Executable $executable)
45
    {
46
        $this->executable = $executable;
47
48
        return $this;
49
    }
50
51
    /**
52
     * @param Validator $validator
53
     * @return $this
54
     */
55
    public function setValidator(Validator $validator)
56
    {
57
        $this->validator = $validator;
58
59
        return $this;
60
    }
61
62
    /**
63
     * @param array $data
64
     * @return array
65
     */
66
    private function build($data)
67
    {
68
        $configuration  = [];
69
70
        foreach ($data as $index => $arrayOrCallable) {
71
            $isCallable = $this->isCallable($arrayOrCallable);
72
73
            if ($isCallable) {
74
                $executable = $this->getNewExecutable();
75
                $executable->setExecutable($arrayOrCallable);
76
                $configuration[$index] = $executable;
77
            } else {
78
                $configuration[$index] = $this->build($arrayOrCallable);
79
            }
80
        }
81
82
        return $configuration;
83
    }
84
85
    /**
86
     * @param string|array $arrayOrCallable
87
     * @return bool
88
     */
89
    private function isCallable($arrayOrCallable)
90
    {
91
        $isCallable = false;
92
93
        if (is_string($arrayOrCallable)) {
94
            $isCallable = is_callable($arrayOrCallable);
95
        } else if ($arrayOrCallable instanceof Closure) {
96
            $isCallable = true;
97
        } else if (is_array($arrayOrCallable)) {
98
            $object     = current($arrayOrCallable);
99
            $isClosure  = ($object instanceof Closure);
100
101
            if ($isClosure) {
102
                $isCallable = false;
103
            } else if (is_object($object)) {
104
                $methodName = $arrayOrCallable[1];
105
                $isCallable = method_exists($object, $methodName);
106
            }
107
        }
108
109
        return $isCallable;
110
    }
111
112
    /**
113
     * @return Executable
114
     */
115
    private function getNewExecutable()
116
    {
117
        return clone $this->executable;
118
    }
119
}
120