Completed
Push — master ( f9fd5d...ba5e19 )
by Bogdan
01:58
created

ContainerHydrator::populate()   A

Complexity

Conditions 4
Paths 3

Size

Total Lines 14
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 8
CRAP Score 4

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 14
ccs 8
cts 8
cp 1
rs 9.2
cc 4
eloc 7
nc 3
nop 2
crap 4
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
/* Based on League\Container\Container v1.x class (https://github.com/thephpleague/container/blob/1.x/src/Container.php)
18
 * which is authored by Phil Bennett (https://github.com/philipobenito)
19
 * and other contributors (https://github.com/thephpleague/container/contributors).
20
 */
21
22
23
namespace Pinepain\Container\Extras;
24
25
26
use League\Container\ContainerInterface;
27
use League\Container\Definition\ClassDefinition;
28
use League\Container\Definition\DefinitionInterface;
29
use Traversable;
30
31
32
class ContainerHydrator
33
{
34
    /**
35
     * Populate the container with items from config
36
     *
37
     * @param ContainerInterface $container
38
     * @param  array|Traversable $config
39
     */
40 12
    public function populate(ContainerInterface $container, $config)
41
    {
42 12
        if (!is_array($config) && !($config instanceof Traversable)) {
43 1
            throw new \InvalidArgumentException(
44
                'You can only load definitions from an array or an object that implements Traversable interface.'
45 1
            );
46
        }
47
48 11
        if (empty($config)) {
49 1
            return;
50
        }
51
52 10
        $this->populateFromTraversable($container, $config);
53 10
    }
54
55 10
    protected function populateFromTraversable($container, $traversable)
56
    {
57 10
        foreach ($traversable as $alias => $options) {
58 9
            $this->createDefinition($container, $options, $alias);
59 10
        }
60 10
    }
61
62
    /**
63
     * Create a definition from a config entry
64
     *
65
     * @param ContainerInterface $container
66
     * @param  mixed             $options
67
     * @param  string            $alias
68
     *
69
     */
70 9
    protected function createDefinition(ContainerInterface $container, $options, $alias)
71
    {
72 9
        $concrete  = $this->resolveConcrete($options);
73 9
        $share     = false;
74 9
        $arguments = [];
75 9
        $methods   = [];
76
77 9
        if (is_array($options)) {
78 6
            $share     = !empty($options['share']);
79 6
            $arguments = (array_key_exists('arguments', $options)) ? (array)$options['arguments'] : [];
80 6
            $methods   = (array_key_exists('methods', $options)) ? (array)$options['methods'] : [];
81 6
        }
82
83
        // define in the container, with constructor arguments and method calls
84 9
        $definition = $container->add($alias, $concrete, $share);
85
86 9
        if ($definition instanceof DefinitionInterface) {
87 3
            $definition->withArguments($arguments);
88 3
        }
89
90 9
        if ($definition instanceof ClassDefinition) {
91 2
            $definition->withMethodCalls($methods);
92 2
        }
93 9
    }
94
95
    /**
96
     * Resolves the concrete class
97
     *
98
     * @param mixed $concrete
99
     *
100
     * @return mixed
101
     */
102 9
    protected function resolveConcrete($concrete)
103
    {
104 9
        if (is_array($concrete)) {
105 6
            if (array_key_exists('definition', $concrete)) {
106 1
                $concrete = $concrete['definition'];
107 6
            } elseif (array_key_exists('class', $concrete)) {
108 4
                $concrete = $concrete['class'];
109 4
            } else {
110 1
                $concrete = null;
111
            }
112 6
        }
113
114
        // if the concrete doesn't have a class associated with it then it
115
        // must be either a Closure or arbitrary type so we just bind that
116 9
        return $concrete;
117
    }
118
}
119