Completed
Push — master ( 9ec1a0...60bd1e )
by Bogdan
04:10
created

Configurator::addDefinitionArguments()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 10
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 3

Importance

Changes 0
Metric Value
dl 0
loc 10
ccs 7
cts 7
cp 1
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 5
nc 3
nop 2
crap 3
1
<?php
2
3
/*
4
  +----------------------------------------------------------------------+
5
  | This file is part of the pinepain/container-extras PHP library.      |
6
  |                                                                      |
7
  | Copyright (c) 2015-2016 Bogdan Padalko <[email protected]>          |
8
  |                                                                      |
9
  | Licensed under the MIT license: http://opensource.org/licenses/MIT   |
10
  |                                                                      |
11
  | For the full copyright and license information, please view the      |
12
  | LICENSE file that was distributed with this source or visit          |
13
  | http://opensource.org/licenses/MIT                                   |
14
  +----------------------------------------------------------------------+
15
*/
16
17
18
namespace Pinepain\Container\Extras;
19
20
21
use League\Container\ContainerInterface;
22
use League\Container\Definition\ClassDefinition;
23
use League\Container\Definition\DefinitionInterface;
24
use Pinepain\Container\Extras\Exceptions\InvalidConfigException;
25
use Traversable;
26
27
28
class Configurator implements ConfiguratorInterface
29
{
30
    /**
31
     * @var ContainerInterface
32
     */
33
    private $container;
34
35
    /**
36
     * @param ContainerInterface $container
37
     */
38 12
    public function __construct(ContainerInterface $container)
39
    {
40 12
        $this->container = $container;
41 12
    }
42
43
    /**
44
     * {@inheritdoc}
45
     */
46 12
    public function configure($config)
47
    {
48 12
        if (!is_array($config) && !($config instanceof Traversable)) {
49 1
            throw new InvalidConfigException(
50
                'You can only load definitions from an array or an object that implements Traversable interface.'
51 1
            );
52
        }
53
54 11
        if (empty($config)) {
55 1
            return;
56
        }
57
58 10
        $this->populateFromTraversable($this->container, $config);
59 10
    }
60
61
    /**
62
     * @param ContainerInterface  $container
63
     * @param array | Traversable $traversable
64
     */
65 10
    protected function populateFromTraversable(ContainerInterface $container, $traversable)
66
    {
67 10
        foreach ($traversable as $alias => $options) {
68 9
            $this->createDefinition($container, $options, $alias);
69 10
        }
70 10
    }
71
72
    /**
73
     * Create a definition from a config entry
74
     *
75
     * @param ContainerInterface $container
76
     * @param  mixed             $options
77
     * @param  string            $alias
78
     *
79
     */
80 9
    protected function createDefinition(ContainerInterface $container, $options, $alias)
81
    {
82 9
        $concrete = $this->resolveConcrete($options);
83
84 9
        $share = is_array($options) && !empty($options['share']);
85
86
        // define in the container, with constructor arguments and method calls
87 9
        $definition = $container->add($alias, $concrete, $share);
88
89 9
        if ($definition instanceof DefinitionInterface) {
90 3
            $this->addDefinitionArguments($definition, $options);
91 3
        }
92
93 9
        if ($definition instanceof ClassDefinition) {
94 2
            $this->addDefinitionMethods($definition, $options);
95 2
        }
96 9
    }
97
98 3
    protected function addDefinitionArguments(DefinitionInterface $definition, $options)
99
    {
100 3
        $arguments = [];
101
102 3
        if (is_array($options)) {
103 3
            $arguments = (array_key_exists('arguments', $options)) ? (array)$options['arguments'] : [];
104 3
        }
105
106 3
        $definition->withArguments($arguments);
107 3
    }
108
109 2
    protected function addDefinitionMethods(ClassDefinition $definition, $options)
110
    {
111 2
        $methods = [];
112
113 2
        if (is_array($options)) {
114 2
            $methods = (array_key_exists('methods', $options)) ? (array)$options['methods'] : [];
115 2
        }
116
117 2
        $definition->withMethodCalls($methods);
118 2
    }
119
120
    /**
121
     * Resolves the concrete class
122
     *
123
     * @param mixed $concrete
124
     *
125
     * @return mixed
126
     */
127 9
    protected function resolveConcrete($concrete)
128
    {
129 9
        if (is_array($concrete)) {
130 6
            if (array_key_exists('definition', $concrete)) {
131 1
                $concrete = $concrete['definition'];
132 6
            } elseif (array_key_exists('class', $concrete)) {
133 4
                $concrete = $concrete['class'];
134 4
            } else {
135 1
                $concrete = null;
136
            }
137 6
        }
138
139
        // if the concrete doesn't have a class associated with it then it
140
        // must be either a Closure or arbitrary type so we just bind that
141 9
        return $concrete;
142
    }
143
144
145
}
146