Completed
Push — master ( 31d69b...c656e0 )
by Marcus
09:48
created

JsonParser::parse()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 17

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 17
rs 9.7
c 0
b 0
f 0
cc 2
nc 2
nop 3
1
<?php
2
3
/**
4
 * TechDivision\Import\Configuration\Jms\Parsers\JsonParser
5
 *
6
 * NOTICE OF LICENSE
7
 *
8
 * This source file is subject to the Open Software License (OSL 3.0)
9
 * that is available through the world-wide-web at this URL:
10
 * http://opensource.org/licenses/osl-3.0.php
11
 *
12
 * PHP version 5
13
 *
14
 * @author    Tim Wagner <[email protected]>
15
 * @copyright 2019 TechDivision GmbH <[email protected]>
16
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
 * @link      https://github.com/techdivision/import-configuration-jms
18
 * @link      http://www.techdivision.com
19
 */
20
21
namespace TechDivision\Import\Configuration\Jms\Parsers;
22
23
use TechDivision\Import\Configuration\Jms\Iterators\DirnameFilter;
24
use TechDivision\Import\Configuration\Jms\Iterators\FilenameFilter;
25
use TechDivision\Import\Configuration\Jms\Utils\ArrayUtilInterface;
26
use TechDivision\Import\Configuration\Jms\ConfigurationParserInterface;
27
28
/**
29
 * The JSON configuration parser implementation.
30
 *
31
 * @author    Tim Wagner <[email protected]>
32
 * @copyright 2019 TechDivision GmbH <[email protected]>
33
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
34
 * @link      https://github.com/techdivision/import-configuration-jms
35
 * @link      http://www.techdivision.com
36
 */
37
class JsonParser implements ConfigurationParserInterface
38
{
39
40
    /**
41
     * The key for the configuration snippet that contains the additional vendor directory configuration.
42
     *
43
     * @var string
44
     */
45
    const ADDITIONAL_VENDOR_DIRS = 'additional-vendor-dirs';
46
47
    /**
48
     * The key with the libraries of the additional vendor directory.
49
     *
50
     * @var string
51
     */
52
    const LIBRARIES = 'libraries';
53
54
    /**
55
     * The key with the absolut/relative path to the vendor directory.
56
     *
57
     * @var string
58
     */
59
    const VENDOR_DIR = 'vendor-dir';
60
61
    /**
62
     * The key for the flag to decide whether or not the vendor is relative to the installation directory.
63
     *
64
     * @var string
65
     */
66
    const RELATIVE = 'relative';
67
68
    /**
69
     * The utility class that provides array handling functionality.
70
     *
71
     * @var \TechDivision\Import\Configuration\Jms\Utils\ArrayUtilInterface
72
     */
73
    protected $arrayUtil;
74
75
    /**
76
     * Initializes the parser with the array utility instance.
77
     *
78
     * @param \TechDivision\Import\Configuration\Jms\Utils\ArrayUtilInterface $arrayUtil The utility instance
79
     */
80
    public function __construct(ArrayUtilInterface $arrayUtil)
81
    {
82
        $this->arrayUtil = $arrayUtil;
83
    }
84
85
    /**
86
     * Parsing the configuration and merge it recursively.
87
     *
88
     * @param string $installationDir         The assumed Magento installation directory
89
     * @param string $defaultConfigurationDir The default configuration directory
90
     * @param array  $directories             An array with diretories to parse
91
     *
92
     * @return string The parsed configuration as string
93
     */
94
    public function parse(string $installationDir, string $defaultConfigurationDir, array $directories) : string
95
    {
96
97
        // initialize the array that'll contain the configuration structure
98
        $main = array();
99
100
        // iterate over the found directories to parse them for configuration files
101
        foreach ($directories as $directory) {
102
            $this->process($main, $directory);
103
        }
104
105
        // process the additional vendor directories, if available
106
        $this->processAdditionalVendorDirs($main, $installationDir, $defaultConfigurationDir);
107
108
        // return the JSON encoded configuration
109
        return json_encode($main, JSON_PRETTY_PRINT);
110
    }
111
112
    /**
113
     * Process the passed directory and merges/replaces the found
114
     * configurations into the passed main configuration.
115
     *
116
     * @param array  $main      The main configuration to merge/replace the found configurations into
117
     * @param string $directory The directory to be parsed for addtional configuration files
118
     *
119
     * @return void
120
     * @throws \Exception Is thrown if the configuration can not be loaded from the configuration files
121
     */
122
    protected function process(array &$main, string $directory) : void
123
    {
124
125
        // load the configuration filenames
126
        $filenames = $this->listContents($directory, 'json');
127
128
        // load the content of each found configuration file and merge it
129
        foreach ($filenames as $filename) {
130
            if (is_file($filename) && $content = json_decode(file_get_contents($filename), true)) {
131
                $main = $this->replace($main, $content);
132
            } else {
133
                throw new \Exception(sprintf('Can\'t load content of file %s', $filename));
134
            }
135
        }
136
    }
137
138
    /**
139
     * Process the configuration files found in the additional vendor directories
140
     * and merge/replace its content in the also passed main configuration file.
141
     *
142
     * @param array  $main                    The main configuration to merge/replace the additional configuration files to
143
     * @param string $installationDir         The assumed Magento installation directory
144
     * @param string $defaultConfigurationDir The default configuration directory
145
     *
146
     * @return void
147
     */
148
    protected function processAdditionalVendorDirs(array &$main, string $installationDir, string $defaultConfigurationDir) : void
149
    {
150
151
        // query whether or not additional vendor directories has been registered in the configuration
152
        if (isset($main[JsonParser::ADDITIONAL_VENDOR_DIRS]) && is_array($main[JsonParser::ADDITIONAL_VENDOR_DIRS])) {
153
            // iterate over the additional vendor directory configurations
154
            foreach ($main[JsonParser::ADDITIONAL_VENDOR_DIRS] as $additionalVendorDir) {
155
                // make sure the vendor directory has been set
156
                if (isset($additionalVendorDir[JsonParser::VENDOR_DIR])) {
157
                    // extract the relative path to the additional vendor directory
158
                    $vendorDir = $additionalVendorDir[JsonParser::VENDOR_DIR];
159
                    // extract the flag if the additional vendor directory is relative to the installation directory
160
                    $isRelative = isset($additionalVendorDir[JsonParser::RELATIVE]) ?? true;
161
                    // query whether or not libraries have been configured
162
                    if (isset($additionalVendorDir[JsonParser::LIBRARIES]) && is_array($additionalVendorDir[JsonParser::LIBRARIES])) {
163
                        // process the configuration found in the library directories
164
                        foreach ($additionalVendorDir[JsonParser::LIBRARIES] as $library) {
165
                            // concatenate the directory for the library
166
                            $libDir = sprintf('%s/%s/%s', $vendorDir, $library, $defaultConfigurationDir);
167
                            // prepend the installation directory, if the vendor is relative to it
168
                            if ($isRelative) {
169
                                $libDir = sprintf('%s/%s', $installationDir, $libDir);
170
                            }
171
172
                            // create the canonicalized absolute pathname and try to load the configuration
173
                            if (is_dir($libraryDir = realpath($libDir))) {
174
                                $this->process($main, $libraryDir);
175
                            } else {
176
                                throw new \Exception(sprintf('Can\'t find find library directory "%s"', $libDir));
177
                            }
178
                        }
179
                    }
180
                }
181
            }
182
        }
183
    }
184
185
    /**
186
     * Return's the array utility instance.
187
     *
188
     * @return \TechDivision\Import\Configuration\Jms\Utils\ArrayUtilInterface The utility instance
189
     */
190
    protected function getArrayUtil() : ArrayUtilInterface
191
    {
192
        return $this->arrayUtil;
193
    }
194
195
    /**
196
     * Replaces the values of the first array with the ones from the arrays
197
     * that has been passed as additional arguments.
198
     *
199
     * @param array ...$arrays The arrays with the values that has to be replaced
200
     *
201
     * @return array The array with the replaced values
202
     */
203
    protected function replace(...$arrays)
204
    {
205
        return $this->getArrayUtil()->replace(...$arrays);
206
    }
207
208
    /**
209
     * List the filenames of a directory.
210
     *
211
     * @param string $directory The directory to list
212
     * @param string $suffix    The suffix of the files to list
213
     *
214
     * @return array A list of filenames
215
     */
216
    protected function listContents($directory = '', $suffix = '.*')
217
    {
218
219
        // initialize the recursive directory iterator
220
        $directory = new \RecursiveDirectoryIterator($directory);
221
        $directory->setFlags(\RecursiveDirectoryIterator::SKIP_DOTS);
222
223
        // initialize the filters for file- and dirname
224
        $filter = new DirnameFilter($directory, '/^(?!\.Trash)/');
0 ignored issues
show
Unused Code introduced by
$filter is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
225
        $filter = new FilenameFilter($directory, sprintf('/\.(?:%s)$/', $suffix));
226
227
        // initialize the array for the files
228
        $files = array();
229
230
        // load the files
231
        foreach (new \RecursiveIteratorIterator($filter) as $file) {
232
            array_unshift($files, $file);
233
        }
234
235
        // sort the files ascending
236
        usort($files, function ($a, $b) {
237
            return strcmp($a, $b);
238
        });
239
240
        // return the array with the files
241
        return $files;
242
    }
243
}
244