Completed
Push — master ( 7e3d04...dc7866 )
by Changwan
06:39
created

BindResolver::getParameters()   C

Complexity

Conditions 8
Paths 18

Size

Total Lines 46
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 23
CRAP Score 8

Importance

Changes 0
Metric Value
cc 8
eloc 27
nc 18
nop 3
dl 0
loc 46
ccs 23
cts 23
cp 1
crap 8
rs 5.5555
c 0
b 0
f 0
1
<?php
2
namespace Wandu\DI\Resolvers;
3
4
use ReflectionClass;
5
use ReflectionException;
6
use ReflectionFunctionAbstract;
7
use Wandu\DI\ContainerInterface;
8
use Wandu\DI\Contracts\ResolverInterface;
9
use Wandu\DI\Exception\CannotFindParameterException;
10
11
class BindResolver implements ResolverInterface
12
{
13
    /** @var string */
14
    protected $className;
15
16 28
    public function __construct($className)
17
    {
18 28
        $this->className = $className;
19 28
    }
20
21
    /**
22
     * {@inheritdoc}
23
     */
24 28
    public function resolve(ContainerInterface $container, array $arguments = [])
25
    {
26 28
        $reflClass = new ReflectionClass($this->className);
27 27
        $reflectionMethod = $reflClass->getConstructor();
28 27
        if (!$reflectionMethod) {
29 19
            $instance = $reflClass->newInstance();
30
        } else {
31 13
            $instance = $reflClass->newInstanceArgs(
32 13
                $this->getParameters($container, $reflectionMethod, $arguments)
33
            );
34
        }
35 23
        return $instance;
36
    }
37
38 13
    protected function getParameters(
39
        ContainerInterface $container,
40
        ReflectionFunctionAbstract $reflectionFunction,
41
        array $arguments = []
42
    ) {
43 13
        $parametersToReturn = static::getSeqArray($arguments);
44
45 13
        $reflectionParameters = array_slice($reflectionFunction->getParameters(), count($parametersToReturn));
46 13
        if (!count($reflectionParameters)) {
47 4
            return $parametersToReturn;
48
        }
49
        /* @var \ReflectionParameter $param */
50 13
        foreach ($reflectionParameters as $param) {
51
            /*
52
             * #1. search in arguments by parameter name
53
             * #1.1. search in arguments by class name
54
             * #2. if parameter has type hint
55
             * #2.1. search in container by class name
56
             * #3. if has default value, insert default value.
57
             * #4. exception
58
             */
59 13
            $paramName = $param->getName();
0 ignored issues
show
Bug introduced by
Consider using $param->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
60
            try {
61 13
                if (array_key_exists($paramName, $arguments)) { // #1.
62 4
                    $parametersToReturn[] = $arguments[$paramName];
63 4
                    continue;
64
                }
65 12
                $paramClass = $param->getClass();
66 12
                if ($paramClass) { // #2.
67 8
                    $paramClassName = $paramClass->getName();
0 ignored issues
show
Bug introduced by
Consider using $paramClass->name. There is an issue with getName() and APC-enabled PHP versions.
Loading history...
68 8
                    if ($container->has($paramClassName)) { // #2.1.
69 8
                        $parametersToReturn[] = $container->get($paramClassName);
70 7
                        continue;
71
                    }
72
                }
73 8
                if ($param->isDefaultValueAvailable()) { // #3.
74 3
                    $parametersToReturn[] = $param->getDefaultValue();
75 3
                    continue;
76
                }
77 6
                throw new CannotFindParameterException($paramName); // #4.
78 7
            } catch (ReflectionException $e) {
79 1
                throw new CannotFindParameterException($paramName);
80
            }
81
        }
82 9
        return $parametersToReturn;
83
    }
84
    
85
    /**
86
     * @param array $array
87
     * @return array
88
     */
89 13
    protected static function getSeqArray(array $array)
90
    {
91 13
        $arrayToReturn = [];
92 13
        foreach ($array as $key => $item) {
93 4
            if (is_int($key)) {
94 4
                $arrayToReturn[] = $item;
95
            }
96
        }
97 13
        return $arrayToReturn;
98
    }
99
}
100