Completed
Push — master ( a2317a...424983 )
by Greg
01:31
created

ConfigProcessor::arrayFillRecursive()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 11
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 7
nc 3
nop 2
1
<?php
2
3
namespace Consolidation\Config\Loader;
4
5
use Grasmash\YamlExpander\Expander;
6
use Consolidation\Config\Util\ArrayUtil;
7
8
/**
9
 * The config processor combines multiple configuration
10
 * files together, and processes them as necessary.
11
 */
12
class ConfigProcessor
13
{
14
    protected $processedConfig = [];
15
    protected $unprocessedConfig = [];
16
17
    /**
18
     * Extend the configuration to be processed with the
19
     * configuration provided by the specified loader.
20
     *
21
     * @param ConfigLoaderInterface $loader
22
     */
23
    public function extend(ConfigLoaderInterface $loader)
24
    {
25
        return $this->addFromSource($loader->export(), $loader->getSourceName());
26
    }
27
28
    /**
29
     * Extend the configuration to be processed with
30
     * the provided nested array.
31
     *
32
     * @param array $data
33
     */
34
    public function add($data)
35
    {
36
        $this->unprocessedConfig[] = $data;
37
        return $this;
38
    }
39
40
    /**
41
     * Extend the configuration to be processed with
42
     * the provided nested array. Also record the name
43
     * of the data source, if applicable.
44
     *
45
     * @param array $data
46
     * @param string $source
47
     */
48
    protected function addFromSource($data, $source = '')
49
    {
50
        if (empty($source)) {
51
            return $this->add($data);
52
        }
53
        $this->unprocessedConfig[$source] = $data;
54
        return $this;
55
    }
56
57
    /**
58
     * Process all of the configuration that has been collected,
59
     * and return a nested array.
60
     *
61
     * @return array
62
     */
63
    public function export($referenceArray = [])
64
    {
65
        if (!empty($this->unprocessedConfig)) {
66
            $this->processedConfig = $this->process(
67
                $this->processedConfig,
68
                $this->fetchUnprocessed(),
69
                $referenceArray
70
            );
71
        }
72
        return $this->processedConfig;
73
    }
74
75
    /**
76
     * To aid in debugging: return the source of each configuration item.
77
     * n.b. Must call this function *before* export and save the result
78
     * if persistence is desired.
79
     */
80
    public function sources()
81
    {
82
        $sources = [];
83
        foreach ($this->unprocessedConfig as $sourceName => $config) {
84
            if (!empty($sourceName)) {
85
                $configSources = ArrayUtil::fillRecursive($config, $sourceName);
86
                $sources = ArrayUtil::mergeRecursiveDistinct($sources, $configSources);
87
            }
88
        }
89
        return $sources;
90
    }
91
92
    /**
93
     * Get the configuration to be processed, and clear out the
94
     * 'unprocessed' list.
95
     *
96
     * @return array
97
     */
98
    protected function fetchUnprocessed()
99
    {
100
        $toBeProcessed = $this->unprocessedConfig;
101
        $this->unprocessedConfig = [];
102
        return $toBeProcessed;
103
    }
104
105
    /**
106
     * Use a map-reduce to evaluate the items to be processed,
107
     * and merge them into the processed array.
108
     *
109
     * @param array $processed
110
     * @param array $toBeProcessed
111
     * @return array
112
     */
113
    protected function process(array $processed, array $toBeProcessed, $referenceArray = [])
114
    {
115
        $toBeReduced = array_map([$this, 'preprocess'], $toBeProcessed);
116
        $reduced = array_reduce($toBeReduced, [$this, 'reduceOne'], $processed);
117
        return $this->evaluate($reduced, $referenceArray);
118
    }
119
120
    /**
121
     * Process a single configuration file from the 'to be processed'
122
     * list. By default this is a no-op. Override this method to
123
     * provide any desired configuration preprocessing, e.g. dot-notation
124
     * expansion of the configuration keys, etc.
125
     *
126
     * @param array $config
127
     * @return array
128
     */
129
    protected function preprocess(array $config)
130
    {
131
        return $config;
132
    }
133
134
    /**
135
     * Evaluate one item in the 'to be evaluated' list, and then
136
     * merge it into the processed configuration (the 'carry').
137
     *
138
     * @param array $processed
139
     * @param array $config
140
     * @return array
141
     */
142
    protected function reduceOne(array $processed, array $config)
143
    {
144
        return ArrayUtil::mergeRecursiveDistinct($processed, $config);
145
    }
146
147
    /**
148
     * Evaluate one configuration item.
149
     *
150
     * @param array $processed
0 ignored issues
show
Bug introduced by
There is no parameter named $processed. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
151
     * @param array $config
152
     * @return array
153
     */
154
    protected function evaluate(array $config, $referenceArray = [])
155
    {
156
        return Expander::expandArrayProperties(
157
            $config,
158
            $referenceArray
159
        );
160
    }
161
}
162