ResourceBuilder   A
last analyzed

Complexity

Total Complexity 27

Size/Duplication

Total Lines 190
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 6

Importance

Changes 0
Metric Value
dl 0
loc 190
rs 10
c 0
b 0
f 0
wmc 27
lcom 1
cbo 6

9 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 10 3
A normalize() 0 11 3
A mergeImported() 0 11 3
A merge() 0 10 2
A computeMergedValue() 0 8 4
B process() 0 20 5
A loadResources() 0 11 3
A getResourceFile() 0 11 2
A getBundlePath() 0 12 2
1
<?php
2
/*
3
 * This file is part of the Borobudur-Kernel package.
4
 *
5
 * (c) Hexacodelabs <http://hexacodelabs.com>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Borobudur\Kernel;
12
13
use Borobudur\Config\FileLoader\FileLoaderInterface;
14
use Borobudur\Config\FileLoader\FileLocator;
15
use Borobudur\DependencyInjection\ContainerBuilder;
16
use Borobudur\DependencyInjection\ParameterBag\Resolver;
17
use Borobudur\Kernel\Bundling\BundleInterface;
18
19
/**
20
 * @author      Iqbal Maulana <[email protected]>
21
 * @created     8/16/15
22
 */
23
class ResourceBuilder
24
{
25
    /**
26
     * @var Resolver
27
     */
28
    private $resolver;
29
30
    /**
31
     * @var array
32
     */
33
    private $bundlesPath = array();
34
35
    /**
36
     * Constructor.
37
     *
38
     * @param ContainerBuilder $container
39
     * @param array            $bundles
40
     */
41
    public function __construct(ContainerBuilder $container, array $bundles)
42
    {
43
        $this->resolver = $container->getParameterBag()->getResolver();
44
45
        foreach ($bundles as $bundle) {
46
            if ($bundle instanceof BundleInterface) {
47
                $this->bundlesPath['@' . $bundle->getName()] = $bundle->getPath();
48
            }
49
        }
50
    }
51
52
    /**
53
     * Normalize array configs.
54
     *
55
     * @param array $configs
56
     *
57
     * @return array
58
     */
59
    private static function normalize(array $configs)
60
    {
61
        $normalized = array();
62
63
        if (isset($configs['imports']) && is_array($configs['imports'])) {
64
            $normalized = self::mergeImported($configs);
65
            unset($configs['imports']);
66
        }
67
68
        return self::merge($normalized, $configs);
69
    }
70
71
    /**
72
     * Merge imported resources.
73
     *
74
     * @param array $configs
75
     *
76
     * @return array
77
     */
78
    private static function mergeImported(array $configs)
79
    {
80
        $normalized = array();
81
        foreach ($configs['imports'] as $config) {
82
            if (is_array($config)) {
83
                $normalized = self::merge($normalized, $config);
84
            }
85
        }
86
87
        return $normalized;
88
    }
89
90
    /**
91
     * Merge distinct between two array recursively.
92
     *
93
     * @param array $array1
94
     * @param array $array2
95
     *
96
     * @return array
97
     */
98
    private static function merge(array $array1, array $array2)
99
    {
100
        $merged = $array1;
101
102
        foreach ($array2 as $key => $value) {
103
            $merged[$key] = self::computeMergedValue($merged, $key, $value);
104
        }
105
106
        return $merged;
107
    }
108
109
    /**
110
     * Compute merged value.
111
     *
112
     * @param array      $merged
113
     * @param string|int $key
114
     * @param mixed      $value
115
     *
116
     * @return array
117
     */
118
    private static function computeMergedValue(array $merged, $key, $value)
119
    {
120
        if (is_array($value) && isset ($merged[$key]) && is_array($merged[$key])) {
121
            return self::merge($merged[$key], $value);
122
        }
123
124
        return $value;
125
    }
126
127
    /**
128
     * @param FileLoaderInterface $loader
129
     * @param array               $configs
130
     *
131
     * @return array
132
     */
133
    public function process(FileLoaderInterface $loader, array $configs)
134
    {
135
        foreach ($configs as $name => $config) {
136
            if ('imports' === $name) {
137
                $configs[$name] = $this->process($loader, $config);
138
                continue;
139
            }
140
141
            if (null !== $resource = $this->loadResources($loader, $config)) {
142
                $configs[$name] = array_merge($resource, $config);
143
                continue;
144
            }
145
146
            if (is_array($config)) {
147
                $configs[$name] = $this->process($loader, $config);
148
            }
149
        }
150
151
        return self::normalize($configs);
152
    }
153
154
    /**
155
     * Import resource.
156
     *
157
     * @param FileLoaderInterface $loader
158
     * @param mixed               $config
159
     *
160
     * @return array|null
161
     */
162
    private function loadResources(FileLoaderInterface $loader, &$config)
163
    {
164
        if (isset($config['resource']) && null !== $file = $this->getResourceFile($config['resource'])) {
165
            $resource = $this->process($loader, $loader->import(new FileLocator($file)));
166
            unset($config['resource']);
167
168
            return $resource;
169
        }
170
171
        return null;
172
    }
173
174
    /**
175
     * Get resource file.
176
     *
177
     * @param string $resource
178
     *
179
     * @return string
180
     */
181
    private function getResourceFile($resource)
182
    {
183
        $resource = $this->resolver->resolveString($resource);
184
        $resource = $this->getBundlePath($resource);
185
186
        if (file_exists($resource)) {
187
            return $resource;
188
        }
189
190
        return null;
191
    }
192
193
    /**
194
     * Get bundle path resource.
195
     *
196
     * @param string $resource
197
     *
198
     * @return string
199
     */
200
    private function getBundlePath($resource)
201
    {
202
        $parts = explode('/', $resource);
203
204
        if (isset($this->bundlesPath[$parts[0]])) {
205
            $parts[0] = $this->bundlesPath[$parts[0]];
206
207
            return implode('/', $parts);
208
        }
209
210
        return $resource;
211
    }
212
}
213