Passed
Branch cake4 (6bfeea)
by n
02:11
created

Invoker::complement()   A

Complexity

Conditions 5
Paths 5

Size

Total Lines 31
Code Lines 19

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 19
CRAP Score 5

Importance

Changes 0
Metric Value
eloc 19
c 0
b 0
f 0
dl 0
loc 31
ccs 19
cts 19
cp 1
rs 9.3222
cc 5
nc 5
nop 2
crap 5
1
<?php
2
declare(strict_types=1);
3
4
namespace N1215\CakeCandle\Invoker;
5
6
use N1215\CakeCandle\Invoker\Exceptions\InsufficientArgumentsException;
7
use N1215\CakeCandle\Invoker\Exceptions\ReflectionFailedException;
8
use N1215\CakeCandle\Reflection\ReflectionCallable;
9
use Psr\Container\ContainerInterface;
10
use ReflectionException;
11
12
final class Invoker implements InvokerInterface
13
{
14
    /**
15
     * @var ContainerInterface
16
     */
17
    private $container;
18
19
    /**
20
     * @param ContainerInterface $container
21
     */
22 15
    public function __construct(ContainerInterface $container)
23
    {
24 15
        $this->container = $container;
25 15
    }
26
27
    /**
28
     * @inheritdoc
29
     */
30 4
    public function invoke(callable $callable, array $args = [])
31
    {
32 4
        $complementedArguments = $this->complement($callable, $args);
33 1
        return $callable(...$complementedArguments);
34
    }
35
36
    /**
37
     * @inheritDoc
38
     */
39 4
    public function complement(callable $callable, array $args = []): array
40
    {
41 4
        $originalArguments = array_values($args);
42
        try {
43 4
            $reflectionCallable = new ReflectionCallable($callable);
44 1
        } catch (ReflectionException $e) {
45 1
            throw new ReflectionFailedException('failed to get reflection of the callable', 0, $e);
46
        }
47
48 3
        $parameters = $reflectionCallable->getParameters();
49
50 3
        $complementedArguments = [];
51 3
        foreach ($parameters as $parameter) {
52 3
            $class = $parameter->getClass();
53 3
            if ($class !== null) {
54 3
                $complementedArguments[] = $this->container->get($class->getName());
55 3
                continue;
56
            }
57
58 3
            if (count($originalArguments) === 0) {
59 1
                $position = $parameter->getPosition() + 1;
60 1
                $name = $parameter->getName();
61 1
                throw new InsufficientArgumentsException(
62 1
                    "Unable to fill the argument {$position} `{$name}`."
63
                );
64
            }
65
66 3
            $complementedArguments[] = array_shift($originalArguments);
67
        }
68
69 1
        return $complementedArguments;
70
    }
71
}
72