ContainerDelegatorFactory::__invoke()   A
last analyzed

Complexity

Conditions 4
Paths 1

Size

Total Lines 18
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 13
CRAP Score 4

Importance

Changes 1
Bugs 0 Features 1
Metric Value
eloc 10
c 1
b 0
f 1
dl 0
loc 18
ccs 13
cts 13
cp 1
rs 9.9332
cc 4
nc 1
nop 2
crap 4
1
<?php
2
3
declare(strict_types=1);
4
5
namespace Antidot\Container;
6
7
use Closure;
8
use Psr\Container\ContainerInterface;
9
use function array_reduce;
10
use function is_callable;
11
12
/**
13
 * Map an instance of this:
14
 *
15
 * <code>
16
 * $container->set(
17
 *     $serviceName,
18
 *     $container->lazyGetCall(
19
 *         $delegatorFactoryInstance,
20
 *         'build',
21
 *         $container,
22
 *         $serviceName
23
 *     )
24
 * )
25
 * </code>
26
 *
27
 * Instances receive the list of delegator factory names or instances, and a
28
 * closure that can create the initial service instance to pass to the first
29
 * delegator.
30
 */
31
final class ContainerDelegatorFactory
32
{
33
    /** @var array<mixed> */
34
    private array $delegators;
35
    /** @var callable  */
36
    private $factory;
37
38
    /**
39
     * @param array<mixed> $delegators Array of delegator factory names or instances.
40
     * @param callable $factory Callable that can return the initial instance.
41
     */
42 1
    public function __construct(array $delegators, callable $factory)
43
    {
44 1
        $this->delegators = $delegators;
45 1
        $this->factory = $factory;
46 1
    }
47
48
    /**
49
     * Build the instance, invoking each delegator with the result of the previous.
50
     *
51
     * @param ContainerInterface $container
52
     * @param string $serviceName
53
     * @return mixed
54
     */
55 1
    public function __invoke(ContainerInterface $container, $serviceName)
56
    {
57 1
        $factory = $this->factory;
58
59 1
        return array_reduce(
60 1
            $this->delegators,
61 1
            static function ($instance, $delegatorName) use ($serviceName, $container) {
62 1
                if (is_string($delegatorName) && $container->has($delegatorName)) {
63 1
                    $delegatorName = $container->get($delegatorName);
64
                }
65
66 1
                $delegator = is_callable($delegatorName) ? $delegatorName : new $delegatorName();
67
68 1
                return $delegator($container, $serviceName, static function () use ($instance) {
69 1
                    return $instance;
70 1
                });
71 1
            },
72 1
            $factory($container)
73
        );
74
    }
75
}
76