Passed
Push — master ( ef8c69...a86aba )
by Alexey
07:15 queued 03:20
created

ServiceDecorator::apply()   B

Complexity

Conditions 5
Paths 7

Size

Total Lines 19
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 11
CRAP Score 5

Importance

Changes 0
Metric Value
cc 5
eloc 11
nc 7
nop 3
dl 0
loc 19
ccs 11
cts 11
cp 1
crap 5
rs 8.8571
c 0
b 0
f 0
1
<?php declare(strict_types = 1);
2
3
namespace Venta\Container;
4
5
use InvalidArgumentException;
6
use Venta\Contracts\Container\Container as ContainerContract;
7
use Venta\Contracts\Container\Invoker as InvokerContract;
8
use Venta\Contracts\Container\ServiceDecorator as ServiceDecoratorContract;
9
use Venta\Contracts\Container\ServiceInflector as ServiceInflectorContract;
10
11
/**
12
 * Class ServiceDecorator
13
 *
14
 * @package Venta\Contracts\Container
15
 */
16
final class ServiceDecorator implements ServiceDecoratorContract
17
{
18
    /**
19
     * @var ContainerContract
20
     */
21
    private $container;
22
23
    /**
24
     * Array of decorator definitions.
25
     *
26
     * @var Invokable[][]|string[][]
27
     */
28
    private $decorators = [];
29
30
    /**
31
     * @var ServiceInflectorContract
32
     */
33
    private $inflector;
34
35
    /**
36
     * @var InvokerContract
37
     */
38
    private $invoker;
39
40
    /**
41
     * ServiceDecorator constructor.
42
     *
43
     * @param ContainerContract $container
44
     * @param ServiceInflectorContract $inflector
45
     * @param InvokerContract $invoker
46
     */
47 36
    public function __construct(
48
        ContainerContract $container,
49
        ServiceInflectorContract $inflector,
50
        InvokerContract $invoker
51
    ) {
52 36
        $this->container = $container;
53 36
        $this->inflector = $inflector;
54 36
        $this->invoker = $invoker;
55 36
    }
56
57
    /**
58
     * @inheritdoc
59
     */
60 8
    public function add(string $id, $decorator)
61
    {
62 8
        if (is_string($decorator)) {
63 3
            if (!class_exists($decorator)) {
64 3
                throw new InvalidArgumentException(sprintf('Invalid decorator class "%s" provided.', $decorator));
65
            }
66
        } else {
67 5
            $decorator = new Invokable($decorator);
68
        }
69
70 7
        $this->decorators[$id][] = $decorator;
71 7
    }
72
73
    /**
74
     *
75
     * @param string $id
76
     * @param $object
77
     * @param bool $once
78
     * @return mixed
79
     */
80 24
    public function apply(string $id, $object, bool $once = false)
81
    {
82 24
        if (empty($this->decorators[$id])) {
83 20
            return $object;
84
        }
85
86 7
        foreach ($this->decorators[$id] as $decorator) {
87 7
            $object = $decorator instanceof Invokable
88 5
                ? $this->invoker->invoke($decorator, [$object])
89 7
                : $this->container->get($decorator, [$object]);
90 7
            $this->inflector->apply($object);
91
        }
92
93 7
        if ($once) {
94 4
            unset($this->decorators[$id]);
95
        }
96
97 7
        return $object;
98
    }
99
}