Passed
Pull Request — master (#6)
by Sergei
02:50 queued 13s
created

CallableDefinition   A

Complexity

Total Complexity 7

Size/Duplication

Total Lines 52
Duplicated Lines 0 %

Test Coverage

Coverage 100%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 16
dl 0
loc 52
ccs 18
cts 18
cp 1
rs 10
c 1
b 0
f 0
wmc 7

3 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 3 1
A prepareClosure() 0 11 4
A resolve() 0 16 2
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Yiisoft\Definitions;
6
7
use Closure;
8
use ReflectionException;
9
use ReflectionFunction;
10
use ReflectionMethod;
11
use Yiisoft\Definitions\Contract\DefinitionInterface;
12
use Yiisoft\Definitions\Contract\DependencyResolverInterface;
13
use Yiisoft\Definitions\Exception\NotInstantiableException;
14
use Yiisoft\Definitions\Infrastructure\DefinitionExtractor;
15
use Yiisoft\Definitions\Infrastructure\DefinitionResolver;
16
17
use function is_array;
18
use function is_object;
19
20
final class CallableDefinition implements DefinitionInterface
21
{
22
    /**
23
     * @var array|callable
24
     * @psalm-var callable|array{0:class-string,1:string}
25
     */
26
    private $callable;
27
28
    /**
29
     * @param array|callable $callable
30
     *
31
     * @psalm-param callable|array{0:class-string,1:string} $callable
32
     */
33 5
    public function __construct($callable)
34
    {
35 5
        $this->callable = $callable;
36 5
    }
37
38 5
    public function resolve(DependencyResolverInterface $dependencyResolver)
39
    {
40
        try {
41 5
            $reflection = new ReflectionFunction(
42 5
                $this->prepareClosure($this->callable, $dependencyResolver)
43
            );
44 1
        } catch (ReflectionException $e) {
45 1
            throw new NotInstantiableException(
46 1
                'Can not instantiate callable definition. Got ' . var_export($this->callable, true)
47
            );
48
        }
49
50 4
        $dependencies = DefinitionExtractor::getInstance()->fromFunction($reflection);
51 4
        $arguments = DefinitionResolver::resolveArray($dependencyResolver, $dependencies);
52
53 4
        return $reflection->invokeArgs($arguments);
54
    }
55
56
    /**
57
     * @param array|callable $callable
58
     *
59
     * @psalm-param callable|array{0:class-string,1:string} $callable
60
     */
61 5
    private function prepareClosure($callable, DependencyResolverInterface $dependencyResolver): Closure
62
    {
63 5
        if (is_array($callable) && !is_object($callable[0])) {
64 3
            $reflection = new ReflectionMethod($callable[0], $callable[1]);
65 2
            if (!$reflection->isStatic()) {
66
                /** @var mixed */
67 1
                $callable[0] = $dependencyResolver->resolve($callable[0]);
68
            }
69
        }
70
71 4
        return Closure::fromCallable($callable);
72
    }
73
}
74