Completed
Push — master ( d7e590...c64771 )
by Johannes
02:22
created

ExpressiveAuraConfig::modify()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 3
rs 10
cc 1
eloc 1
nc 1
nop 1
1
<?php
2
3
/**
4
 * Lichtenwallner  (https://lichtenwallner.at)
5
 *
6
 * @see https://github.com/jolicht/markdown-cms for the canonical source repository
7
 * @license https://github.com/jolicht/markdown-cms/blob/master/LICENSE MIT
8
 * @copyright Copyright (c) Johannes Lichtenwallner
9
 */
10
declare(strict_types = 1);
11
namespace JolichtTest\MarkdownCms;
12
13
use ArrayObject;
14
use Aura\Di\Container;
15
use Aura\Di\ContainerConfigInterface;
16
17
/**
18
 * Configuration for the Aura.Di container.
19
 *
20
 * This class provides functionality for the following service types:
21
 *
22
 * - Aliases
23
 * - Delegators
24
 * - Factories
25
 * - Invokable classes
26
 * - Services (known instances)
27
 */
28
class ExpressiveAuraConfig implements ContainerConfigInterface
29
{
30
    /**
31
     * @var array
32
     */
33
    private $config;
34
35
    /**
36
     * @param array $config
37
     */
38
    public function __construct(array $config)
39
    {
40
        $this->config = $config;
41
    }
42
43
    /**
44
     * Configure the container
45
     *
46
     * - Adds the 'config' service.
47
     * - If delegators are defined, maps the service to lazyGetCall an
48
     *   ExpressiveAuraDelegatorFactory::build invocation using the configured
49
     *   delegator and whatever factory was responsible for it.
50
     * - If factories are defined, maps each factory class as a lazily
51
     *   instantiable service, and the service to lazyGetCall the factory to
52
     *   create the instance.
53
     * - If invokables are defined, maps each to lazyNew the target.
54
     * - If aliases are defined, maps each to lazyGet the target.
55
     *
56
     * @param Container $container
57
     * @return void
58
     */
59
    public function define(Container $container)
60
    {
61
        // Convert config to an object and inject it
62
        $container->set('config', new ArrayObject($this->config, ArrayObject::ARRAY_AS_PROPS));
0 ignored issues
show
Documentation introduced by
new \ArrayObject($this->...Object::ARRAY_AS_PROPS) is of type object<ArrayObject>, but the function expects a callable.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
63
64
        if (empty($this->config['dependencies'])) {
65
            return;
66
        }
67
68
        $dependencies = $this->config['dependencies'];
69
70
        // Inject delegator factories
71
        // This is done early because Aura.Di does not allow modification of a
72
        // service after creation. As such, we need to create custom factories
73
        // for each service with delegators.
74
        if (isset($dependencies['delegators'])) {
75
            $dependencies = $this->marshalDelegators($container, $dependencies);
76
        }
77
78
        // Inject services
79
        if (isset($dependencies['services'])) {
80
            foreach ($dependencies['services'] as $name => $service) {
81
                $container->set($name, $service);
82
            }
83
        }
84
85
        // Inject factories
86
        if (isset($dependencies['factories'])) {
87
            foreach ($dependencies['factories'] as $service => $factory) {
88
                $container->set($factory, $container->lazyNew($factory));
89
                $container->set($service, $container->lazyGetCall($factory, '__invoke', $container));
90
            }
91
        }
92
93
        // Inject invokables
94
        if (isset($dependencies['invokables'])) {
95
            foreach ($dependencies['invokables'] as $service => $class) {
96
                $container->set($service, $container->lazyNew($class));
97
            }
98
        }
99
100
        // Inject aliases
101
        if (isset($dependencies['aliases'])) {
102
            foreach ($dependencies['aliases'] as $alias => $target) {
103
                $container->set($alias, $container->lazyGet($target));
104
            }
105
        }
106
    }
107
108
    /**
109
     * This method is purposely a no-op.
110
     *
111
     * @param Container $container
112
     * @return void
113
     */
114
    public function modify(Container $container)
115
    {
116
    }
117
118
    /**
119
     * Marshal all services with delegators.
120
     *
121
     * @param Container $container
122
     * @param array $dependencies
123
     * @return array List of dependencies minus any services, factories, or
124
     *     invokables that match services using delegator factories.
125
     */
126
    private function marshalDelegators(Container $container, array $dependencies)
127
    {
128
        foreach ($dependencies['delegators'] as $service => $delegatorNames) {
129
            $factory = null;
130
131 View Code Duplication
            if (isset($dependencies['services'][$service])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
132
                // Marshal from service
133
                $instance = $dependencies['services'][$service];
134
                $factory = function () use ($instance) {
135
                    return $instance;
136
                };
137
                unset($dependencies['service'][$service]);
138
            }
139
140 View Code Duplication
            if (isset($dependencies['factories'][$service])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
141
                // Marshal from factory
142
                $serviceFactory = $dependencies['factories'][$service];
143
                $factory = function () use ($service, $serviceFactory, $container) {
144
                    return $serviceFactory($container, $service);
145
                };
146
                unset($dependencies['factories'][$service]);
147
            }
148
149 View Code Duplication
            if (isset($dependencies['invokables'][$service])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
150
                // Marshal from invokable
151
                $class = $dependencies['invokables'][$service];
152
                $factory = function () use ($class) {
153
                    return new $class();
154
                };
155
                unset($dependencies['invokables'][$service]);
156
            }
157
158
            if (! is_callable($factory)) {
159
                continue;
160
            }
161
162
            $delegatorFactory = new ExpressiveAuraDelegatorFactory($delegatorNames, $factory);
163
            $container->set(
164
                $service,
165
                $container->lazyGetCall($delegatorFactory, 'build', $container, $service)
166
            );
167
        }
168
169
        return $dependencies;
170
    }
171
}
172