Passed
Push — 8.x ( 63276b...f1fbe2 )
by Tim
02:58 queued 11s
created

SimpleConfigurationLoader::createConfiguration()   A

Complexity

Conditions 5
Paths 4

Size

Total Lines 21
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 5
eloc 7
c 1
b 0
f 0
nc 4
nop 1
dl 0
loc 21
ccs 0
cts 8
cp 0
crap 30
rs 9.6111
1
<?php
2
3
/**
4
 * TechDivision\Import\Cli\SimpleConfigurationLoader
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 2016 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-cli-simple
18
 * @link      http://www.techdivision.com
19
 */
20
21
namespace TechDivision\Import\Cli;
22
23
use Symfony\Component\Console\Input\InputInterface;
24
use Symfony\Component\DependencyInjection\ContainerInterface;
25
use TechDivision\Import\ConfigurationFactoryInterface;
26
use TechDivision\Import\Cli\Command\InputOptionKeys;
27
use TechDivision\Import\Cli\Configuration\LibraryLoader;
28
use TechDivision\Import\Cli\Utils\DependencyInjectionKeys;
29
use TechDivision\Import\Cli\Utils\MagentoConfigurationKeys;
30
use TechDivision\Import\Utils\CommandNames;
31
use TechDivision\Import\Utils\Mappings\CommandNameToEntityTypeCode;
32
33
/**
34
 * The configuration loader implementation.
35
 *
36
 * @author    Tim Wagner <[email protected]>
37
 * @copyright 2016 TechDivision GmbH <[email protected]>
38
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
39
 * @link      https://github.com/techdivision/import-cli-simple
40
 * @link      http://www.techdivision.com
41
 */
42
class SimpleConfigurationLoader implements ConfigurationLoaderInterface
43
{
44
45
    /**
46
     * The key for the Magento Edition in the metadata extracted from the Composer configuration.
47
     *
48
     * @var string
49
     */
50
    const EDITION = 'edition';
51
52
    /**
53
     * The key for the Magento Version in the metadata extracted from the Composer configuration.
54
     *
55
     * @var string
56
     */
57
    const VERSION = 'version';
58
59
    /**
60
     * The container instance.
61
     *
62
     * @var \Symfony\Component\DependencyInjection\ContainerInterface
63
     */
64
    protected $container;
65
66
    /**
67
     * The actual input instance.
68
     *
69
     * @var \Symfony\Component\Console\Input\InputInterface
70
     */
71
    protected $input;
72
73
    /**
74
     * The library loader instance.
75
     *
76
     * @param \TechDivision\Import\Cli\LibraryLoader
77
     */
78
    protected $libraryLoader;
79
80
    /**
81
     * The configuration factory instance.
82
     *
83
     * @var \TechDivision\Import\ConfigurationFactoryInterface
84
     */
85
    protected $configurationFactory;
86
87
    /**
88
     * The available command names.
89
     *
90
     * @var \TechDivision\Import\Utils\CommandNames
91
     */
92
    protected $commandNames;
93
94
    /**
95
     * The mapping of the command names to the entity type codes
96
     *
97
     * @var \TechDivision\Import\Utils\Mappings\CommandNameToEntityTypeCode
98
     */
99
    protected $commandNameToEntityTypeCode;
100
101
    /**
102
     * Initializes the configuration loader.
103
     *
104
     * @param \Symfony\Component\Console\Input\InputInterface                 $input                        The input instance
105
     * @param \Symfony\Component\DependencyInjection\ContainerInterface       $container                    The container instance
106
     * @param \TechDivision\Import\Cli\Configuration\LibraryLoader            $libraryLoader                The configuration loader instance
107
     * @param \TechDivision\Import\ConfigurationFactoryInterface              $configurationFactory         The configuration factory instance
108
     * @param \TechDivision\Import\Utils\CommandNames                         $commandNames                 The available command names
109
     * @param \TechDivision\Import\Utils\Mappings\CommandNameToEntityTypeCode $commandNameToEntityTypeCodes The mapping of the command names to the entity type codes
110
     */
111
    public function __construct(
112
        InputInterface $input,
113
        ContainerInterface $container,
114
        LibraryLoader $libraryLoader,
115
        ConfigurationFactoryInterface $configurationFactory,
116
        CommandNames $commandNames,
117
        CommandNameToEntityTypeCode $commandNameToEntityTypeCodes
118
    ) {
119
120
        // set the passed instances
121
        $this->input = $input;
122
        $this->container = $container;
123
        $this->libraryLoader = $libraryLoader;
124
        $this->configurationFactory = $configurationFactory;
125
        $this->commandNames = $commandNames;
126
        $this->commandNameToEntityTypeCode = $commandNameToEntityTypeCodes;
127
    }
128
129
    /**
130
     * Factory implementation to create a new initialized configuration instance.
131
     *
132
     * If command line options are specified, they will always override the
133
     * values found in the configuration file.
134
     *
135
     * @return \TechDivision\Import\ConfigurationInterface The configuration instance
136
     */
137
    public function load()
138
    {
139
140
        // initially try to create the configuration instance
141
        // $instance = $this->createInstance();
142
        $instance = $this->createInstanceFromDirectories();
143
144
        // we have to set the entity type code at least
145
        $instance->setEntityTypeCode($this->getEntityTypeCode());
146
147
        // query whether or not a system name has been specified as command line option, if yes override the value from the configuration file
148
        if (($this->input->hasOptionSpecified(InputOptionKeys::SYSTEM_NAME) && $this->input->getOption(InputOptionKeys::SYSTEM_NAME)) || $instance->getSystemName() === null) {
0 ignored issues
show
Bug introduced by
The method hasOptionSpecified() does not exist on Symfony\Component\Console\Input\InputInterface. Did you maybe mean hasOption()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

148
        if (($this->input->/** @scrutinizer ignore-call */ hasOptionSpecified(InputOptionKeys::SYSTEM_NAME) && $this->input->getOption(InputOptionKeys::SYSTEM_NAME)) || $instance->getSystemName() === null) {

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
149
            $instance->setSystemName($this->input->getOption(InputOptionKeys::SYSTEM_NAME));
150
        }
151
152
        // query whether or not a PID filename has been specified as command line option, if yes override the value from the configuration file
153
        if (($this->input->hasOptionSpecified(InputOptionKeys::PID_FILENAME) && $this->input->getOption(InputOptionKeys::PID_FILENAME)) || $instance->getPidFilename() === null) {
154
            $instance->setPidFilename($this->input->getOption(InputOptionKeys::PID_FILENAME));
155
        }
156
157
        // query whether or not a Magento installation directory has been specified as command line option, if yes override the value from the configuration file
158
        if (($this->input->hasOptionSpecified(InputOptionKeys::INSTALLATION_DIR) && $this->input->getOption(InputOptionKeys::INSTALLATION_DIR)) || $instance->getInstallationDir() === null) {
159
            $instance->setInstallationDir($this->input->getOption(InputOptionKeys::INSTALLATION_DIR));
160
        }
161
162
        // query whether or not a Magento Edition has been specified as command line option, if yes override the value from the configuration file
163
        if (($this->input->hasOptionSpecified(InputOptionKeys::MAGENTO_EDITION) && $this->input->getOption(InputOptionKeys::MAGENTO_EDITION)) || $instance->getMagentoEdition() === null) {
164
            $instance->setMagentoEdition($this->input->getOption(InputOptionKeys::MAGENTO_EDITION));
165
        }
166
167
        // query whether or not a Magento Version has been specified as command line option, if yes override the value from the configuration file
168
        if (($this->input->hasOptionSpecified(InputOptionKeys::MAGENTO_VERSION) && $this->input->getOption(InputOptionKeys::MAGENTO_VERSION)) || $instance->getMagentoVersion() === null) {
169
            $instance->setMagentoVersion($this->input->getOption(InputOptionKeys::MAGENTO_VERSION));
170
        }
171
172
        // query whether or not a directory for the source files has been specified as command line option, if yes override the value from the configuration file
173
        if (($this->input->hasOptionSpecified(InputOptionKeys::SOURCE_DIR) && $this->input->getOption(InputOptionKeys::SOURCE_DIR)) || $instance->getSourceDir() === null) {
174
            $instance->setSourceDir($this->input->getOption(InputOptionKeys::SOURCE_DIR));
175
        }
176
177
        // return the initialized configuration instance
178
        return $instance;
179
    }
180
181
    protected function createInstanceFromDirectories()
182
    {
183
184
        // load the actual vendor directory and entity type code
185
        $vendorDir = $this->getVendorDir();
186
187
        // the path of the JMS serializer directory, relative to the vendor directory
188
        $jmsDir = DIRECTORY_SEPARATOR . 'jms' . DIRECTORY_SEPARATOR . 'serializer' . DIRECTORY_SEPARATOR . 'src';
189
190
        // try to find the path to the JMS Serializer annotations
191
        if (!file_exists($annotationDir = $vendorDir . DIRECTORY_SEPARATOR . $jmsDir)) {
192
            // stop processing, if the JMS annotations can't be found
193
            throw new \Exception(
194
                sprintf(
195
                    'The jms/serializer libarary can not be found in one of "%s"',
196
                    implode(', ', $vendorDir)
0 ignored issues
show
Bug introduced by
$vendorDir of type string is incompatible with the type array expected by parameter $pieces of implode(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

196
                    implode(', ', /** @scrutinizer ignore-type */ $vendorDir)
Loading history...
197
                    )
198
                );
199
        }
200
201
        // register the autoloader for the JMS serializer annotations
202
        \Doctrine\Common\Annotations\AnnotationRegistry::registerAutoloadNamespace(
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\Common\Annotati...sterAutoloadNamespace() has been deprecated: this method is deprecated and will be removed in doctrine/annotations 2.0 autoloading should be deferred to the globally registered autoloader by then. For now, use @example AnnotationRegistry::registerLoader('class_exists') ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

202
        /** @scrutinizer ignore-deprecated */ \Doctrine\Common\Annotations\AnnotationRegistry::registerAutoloadNamespace(

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
203
            'JMS\Serializer\Annotation',
204
            $annotationDir
205
        );
206
207
        // load the actual vendor directory and entity type code
208
        $directories = array(
209
            implode(DIRECTORY_SEPARATOR, array($vendorDir, 'techdivision', 'import-configuration-jms', 'etc')),
210
            implode(DIRECTORY_SEPARATOR, array(getcwd(), 'etc'))
211
        );
212
213
        return $this->configurationFactory->factoryFromDirectories($directories);
0 ignored issues
show
Bug introduced by
The method factoryFromDirectories() does not exist on TechDivision\Import\ConfigurationFactoryInterface. Did you maybe mean factory()? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

213
        return $this->configurationFactory->/** @scrutinizer ignore-call */ factoryFromDirectories($directories);

This check looks for calls to methods that do not seem to exist on a given type. It looks for the method on the type itself as well as in inherited classes or implemented interfaces.

This is most likely a typographical error or the method has been renamed.

Loading history...
214
    }
215
216
    /**
217
     * This method create the configuration instance from the configuration file
218
     * defined by the commandline args and options.
219
     *
220
     * @return \TechDivision\Import\ConfigurationInterface The configuration instance loaded from the configuration file
221
     * @throws \Exception Is thrown, if the specified configuration file doesn't exist or the mandatory arguments/options to run the requested operation are not available
222
     */
223
    protected function createInstance()
224
    {
225
226
        // load the actual vendor directory and entity type code
227
        $vendorDir = $this->getVendorDir();
228
229
        // the path of the JMS serializer directory, relative to the vendor directory
230
        $jmsDir = DIRECTORY_SEPARATOR . 'jms' . DIRECTORY_SEPARATOR . 'serializer' . DIRECTORY_SEPARATOR . 'src';
231
232
        // try to find the path to the JMS Serializer annotations
233
        if (!file_exists($annotationDir = $vendorDir . DIRECTORY_SEPARATOR . $jmsDir)) {
234
            // stop processing, if the JMS annotations can't be found
235
            throw new \Exception(
236
                sprintf(
237
                    'The jms/serializer libarary can not be found in one of "%s"',
238
                    implode(', ', $vendorDir)
0 ignored issues
show
Bug introduced by
$vendorDir of type string is incompatible with the type array expected by parameter $pieces of implode(). ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

238
                    implode(', ', /** @scrutinizer ignore-type */ $vendorDir)
Loading history...
239
                )
240
            );
241
        }
242
243
        // register the autoloader for the JMS serializer annotations
244
        \Doctrine\Common\Annotations\AnnotationRegistry::registerAutoloadNamespace(
0 ignored issues
show
Deprecated Code introduced by
The function Doctrine\Common\Annotati...sterAutoloadNamespace() has been deprecated: this method is deprecated and will be removed in doctrine/annotations 2.0 autoloading should be deferred to the globally registered autoloader by then. For now, use @example AnnotationRegistry::registerLoader('class_exists') ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-deprecated  annotation

244
        /** @scrutinizer ignore-deprecated */ \Doctrine\Common\Annotations\AnnotationRegistry::registerAutoloadNamespace(

This function has been deprecated. The supplier of the function has supplied an explanatory message.

The explanatory message should give you some clue as to whether and when the function will be removed and what other function to use instead.

Loading history...
245
            'JMS\Serializer\Annotation',
246
            $annotationDir
247
        );
248
249
        // query whether or not, a configuration file has been specified
250
        if ($configuration = $this->input->getOption(InputOptionKeys::CONFIGURATION)) {
251
            // load the configuration from the file with the given filename
252
            return $this->createConfiguration($configuration);
253
        } elseif (($magentoEdition = $this->input->getOption(InputOptionKeys::MAGENTO_EDITION)) && ($magentoVersion = $this->input->getOption(InputOptionKeys::MAGENTO_VERSION))) {
254
            // use the Magento Edition that has been specified as option
255
            $instance = $this->createConfiguration($this->getDefaultConfiguration($magentoEdition, $magentoVersion, $this->getEntityTypeCode()));
256
257
            // override the Magento Edition/Version
258
            $instance->setMagentoEdition($magentoEdition);
259
            $instance->setMagentoVersion($magentoVersion);
260
        } else {
261
            // finally, query whether or not the installation directory is a valid Magento root directory
262
            if (!$this->isMagentoRootDir($installationDir = $this->input->getOption(InputOptionKeys::INSTALLATION_DIR))) {
0 ignored issues
show
Bug introduced by
It seems like $installationDir = $this...Keys::INSTALLATION_DIR) can also be of type string[]; however, parameter $dir of TechDivision\Import\Cli\...der::isMagentoRootDir() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

262
            if (!$this->isMagentoRootDir(/** @scrutinizer ignore-type */ $installationDir = $this->input->getOption(InputOptionKeys::INSTALLATION_DIR))) {
Loading history...
263
                throw new \Exception(
264
                    sprintf(
265
                        'Directory "%s" is not a valid Magento root directory, please use option "--installation-dir" to specify it',
266
                        $installationDir
0 ignored issues
show
Bug introduced by
It seems like $installationDir can also be of type string[]; however, parameter $args of sprintf() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

266
                        /** @scrutinizer ignore-type */ $installationDir
Loading history...
267
                    )
268
                );
269
            }
270
271
            // load the Magento Edition from the Composer configuration file
272
            $metadata = $this->getEditionMapping($installationDir);
0 ignored issues
show
Bug introduced by
It seems like $installationDir can also be of type string[]; however, parameter $installationDir of TechDivision\Import\Cli\...er::getEditionMapping() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

272
            $metadata = $this->getEditionMapping(/** @scrutinizer ignore-type */ $installationDir);
Loading history...
273
274
            // extract edition & version from the metadata
275
            $magentoEdition = $metadata[SimpleConfigurationLoader::EDITION];
276
            $magentoVersion = $metadata[SimpleConfigurationLoader::VERSION];
277
278
            // use the Magento Edition that has been detected by the installation directory
279
            $instance = $this->createConfiguration($this->getDefaultConfiguration($magentoEdition, $magentoVersion, $this->getEntityTypeCode()));
280
281
            // override the Magento Edition/Version
282
            $instance->setMagentoEdition($magentoEdition);
283
            $instance->setMagentoVersion($magentoVersion);
284
        }
285
    }
286
287
    /**
288
     * Create and return a new configuration instance from the passed configuration filename
289
     * after merging additional specified params from the commandline.
290
     *
291
     * @param string $filename The configuration filename to use
292
     *
293
     * @return \TechDivision\Import\ConfigurationInterface The configuration instance
294
     */
295
    protected function createConfiguration($filename)
296
    {
297
298
        // initialize the params specified with the --params parameter
299
        $params = null;
300
301
        // try to load the params from the commandline
302
        if ($this->input->hasOptionSpecified(InputOptionKeys::PARAMS) && $this->input->getOption(InputOptionKeys::PARAMS)) {
303
            $params = $this->input->getOption(InputOptionKeys::PARAMS);
304
        }
305
306
        // initialize the params file specified with the --params-file parameter
307
        $paramsFile = null;
308
309
        // try to load the path of the params file from the commandline
310
        if ($this->input->hasOptionSpecified(InputOptionKeys::PARAMS_FILE) && $this->input->getOption(InputOptionKeys::PARAMS_FILE)) {
311
            $paramsFile = $this->input->getOption(InputOptionKeys::PARAMS_FILE);
312
        }
313
314
        // create the configuration and return it
315
        return $this->configurationFactory->factory($filename, pathinfo($filename, PATHINFO_EXTENSION), $params, $paramsFile);
0 ignored issues
show
Unused Code introduced by
The call to TechDivision\Import\Conf...oryInterface::factory() has too many arguments starting with $params. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

315
        return $this->configurationFactory->/** @scrutinizer ignore-call */ factory($filename, pathinfo($filename, PATHINFO_EXTENSION), $params, $paramsFile);

This check compares calls to functions or methods with their respective definitions. If the call has more arguments than are defined, it raises an issue.

If a function is defined several times with a different number of parameters, the check may pick up the wrong definition and report false positives. One codebase where this has been known to happen is Wordpress. Please note the @ignore annotation hint above.

Loading history...
316
    }
317
318
    /**
319
     * Return's the DI container instance.
320
     *
321
     * @return \Symfony\Component\DependencyInjection\ContainerInterface The DI container instance
322
     */
323
    protected function getContainer()
324
    {
325
        return $this->container;
326
    }
327
328
    /**
329
     * Return's the absolute path to the actual vendor directory.
330
     *
331
     * @return string The absolute path to the actual vendor directory
332
     * @throws \Exception Is thrown, if none of the possible vendor directories can be found
333
     */
334
    protected function getVendorDir()
335
    {
336
        return $this->getContainer()->getParameter(DependencyInjectionKeys::CONFIGURATION_VENDOR_DIR);
337
    }
338
339
    /**
340
     * Return's the actual command name.
341
     *
342
     * @return string The actual command name
343
     */
344
    protected function getCommandName()
345
    {
346
        return $this->input->getArgument('command');
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->input->getArgument('command') also could return the type string[] which is incompatible with the documented return type string.
Loading history...
347
    }
348
349
    /**
350
     * Return's the command's entity type code.
351
     *
352
     * @return string The command's entity type code
353
     * @throws \Exception Is thrown, if the command name can not be mapped
354
     */
355
    protected function getEntityTypeCode()
356
    {
357
358
        // try to map the command name to a entity type code
359
        if (array_key_exists($commandName = $this->getCommandName(), (array) $this->commandNameToEntityTypeCode)) {
360
            return $this->commandNameToEntityTypeCode[$commandName];
361
        }
362
363
        // throw an exception if not possible
364
        throw new \Exception(sprintf('Can\'t map command name %s to a entity type', $commandName));
365
    }
366
367
    /**
368
     * Returns the mapped Magento Edition from the passed Magento installation.
369
     *
370
     * @param string $installationDir The Magento installation directory
371
     *
372
     * @return array The array with the mapped Magento Edition (either CE or EE) + the Version
373
     * @throws \Exception Is thrown, if the passed installation directory doesn't contain a valid Magento installation
374
     */
375
    protected function getEditionMapping($installationDir)
376
    {
377
378
        // load the default edition mappings from the configuration
379
        $editionMappings = $this->getContainer()->getParameter(DependencyInjectionKeys::APPLICATION_EDITION_MAPPINGS);
380
381
        // load the composer file from the Magento root directory
382
        $composer = json_decode(file_get_contents($composerFile = sprintf('%s/composer.json', $installationDir)), true);
383
384
        // try to load and explode the Magento Edition identifier from the Composer name
385
        $explodedEdition = explode('/', $composer[MagentoConfigurationKeys::COMPOSER_EDITION_NAME_ATTRIBUTE]);
386
387
        // try to load and explode the Magento Edition from the Composer configuration
388
        if (!isset($editionMappings[$possibleEdition = end($explodedEdition)])) {
389
            throw new \Exception(
390
                sprintf(
391
                    '"%s" detected in "%s" is not a valid Magento Edition, please set Magento Edition with the "--magento-edition" option',
392
                    $possibleEdition,
393
                    $composerFile
394
                )
395
            );
396
        }
397
398
        // try to load and explode the Magento Version from the Composer configuration
399
        if (!isset($composer[MagentoConfigurationKeys::COMPOSER_EDITION_VERSION_ATTRIBUTE])) {
400
            throw new \Exception(
401
                sprintf(
402
                    'Can\'t detect a version in "%s", please set Magento Version with the "--magento-version" option',
403
                    $composerFile
404
                )
405
            );
406
        }
407
408
        // return the array with the Magento Version/Edition data
409
        return array(
410
            SimpleConfigurationLoader::VERSION => $composer[MagentoConfigurationKeys::COMPOSER_EDITION_VERSION_ATTRIBUTE],
411
            SimpleConfigurationLoader::EDITION => $editionMappings[$possibleEdition]
412
        );
413
    }
414
415
    /**
416
     * Return's the default configuration for the passed Magento Edition/Version and the actual entity type.
417
     *
418
     * @param string $magentoEdition The Magento Edition to return the configuration for
419
     * @param string $magentoVersion The Magento Version to return the configuration for
420
     * @param string $entityTypeCode The entity type code to use
421
     *
422
     * @return string The path to the default configuration
423
     */
424
    protected function getDefaultConfiguration($magentoEdition, $magentoVersion, $entityTypeCode)
425
    {
426
427
        // load the components the filename has to be concatenated with
428
        $vendorDir = $this->getVendorDir();
429
        $libraryDir = $this->getDefaultConfigurationLibrary($magentoEdition, $entityTypeCode);
430
        $filename = $this->getDefaultConfigurationFile($entityTypeCode);
431
432
        // load the directories that equals the versions custom configuration files are available for
433
        $versions = glob(sprintf('%s/%s/etc/*', $vendorDir, $libraryDir), GLOB_ONLYDIR);
434
435
        // sort the directories descending by their version
436
        usort($versions, 'version_compare');
0 ignored issues
show
Bug introduced by
It seems like $versions can also be of type false; however, parameter $array of usort() does only seem to accept array, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

436
        usort(/** @scrutinizer ignore-type */ $versions, 'version_compare');
Loading history...
437
        krsort($versions);
438
439
        // explode the Magento version
440
        $explodedMagentoVersion = explode('.', $magentoVersion);
441
442
        // initialize the proposed filename with the default file in the library's root directory
443
        $proposedfilename = $filename;
444
445
        // iterate over the magento versions, try to find the matching configuration file
446
        for ($i = sizeof($explodedMagentoVersion); $i > 0; $i--) {
447
            foreach ($versions as $version) {
448
                // create a version number
449
                $level = implode('.', array_slice($explodedMagentoVersion, 0, $i));
450
                // try to match the version number against the directory
451
                if (version_compare($versionBasname = basename($version), $level, '<=') && is_file(sprintf('%s/%s.json', $version, $filename))) {
452
                    // we found the apropriate version directory and stop here
453
                    $proposedfilename = sprintf('%s/%s', $versionBasname, $filename);
454
                    break 2;
455
                }
456
            }
457
        }
458
459
        // return the default configuration file
460
        return sprintf('%s/%s/etc/%s.json', $vendorDir, $libraryDir, $proposedfilename);
461
    }
462
463
    /**
464
     * Return's the name of the default configuration file.
465
     *
466
     * @param string $entityTypeCode The entity type code to return the default configuration file for
467
     *
468
     * @return string The name of the entity type's default configuration file
469
     * @throws \Exception
470
     */
471
    protected function getDefaultConfigurationFile($entityTypeCode)
472
    {
473
474
        // load the default configuration file mappings from the configuration
475
        $defaultConfigurationFileMappings = $this->getContainer()->getParameter(DependencyInjectionKeys::APPLICATION_DEFAULT_CONFIGURATION_FILE_MAPPINGS);
476
477
        // query whether or not a default configuration file for the passed entity type code exists
478
        if (isset($defaultConfigurationFileMappings[$entityTypeCode])) {
479
            return $defaultConfigurationFileMappings[$entityTypeCode];
480
        }
481
482
        // throw an exception, if no default configuration file for the passed entity type is available
483
        throw new \Exception(
484
            sprintf(
485
                'Can\'t find a default configuration file for entity Type Code \'%s\' (MUST be one of catalog_product, catalog_product_price, catalog_product_inventory, catalog_category or eav_attribute)',
486
                $entityTypeCode
487
            )
488
        );
489
    }
490
491
    /**
492
     * Return's the Magento Edition and entity type's specific default library that contains
493
     * the configuration file.
494
     *
495
     * @param string $magentoEdition The Magento Edition to return the default library for
496
     * @param string $entityTypeCode The entity type code to return the default library file for
497
     *
498
     * @return string The name of the library that contains the default configuration file for the passed Magento Edition and entity type code
499
     * @throws \Exception Is thrown, if no default configuration for the passed entity type code is available
500
     */
501
    protected function getDefaultConfigurationLibrary($magentoEdition, $entityTypeCode)
502
    {
503
504
        // load the default configuration file mappings from the configuration
505
        $defaultConfigurations = $this->getContainer()->getParameter(DependencyInjectionKeys::APPLICATION_DEFAULT_CONFIGURATIONS);
506
507
        // query whether or not, a default configuration file for the passed entity type is available
508
        if (isset($defaultConfigurations[$edition = strtolower($magentoEdition)])) {
509
            if (isset($defaultConfigurations[$edition][$entityTypeCode])) {
510
                return $defaultConfigurations[$edition][$entityTypeCode];
511
            }
512
513
            // throw an exception, if the passed entity type is not supported
514
            throw new \Exception(
515
                sprintf(
516
                    'Entity Type Code \'%s\' not supported by entity type code \'%s\' (MUST be one of catalog_product, catalog_category or eav_attribute)',
517
                    $edition,
518
                    $entityTypeCode
519
                )
520
            );
521
        }
522
523
        // throw an exception, if the passed edition is not supported
524
        throw new \Exception(
525
            sprintf(
526
                'Default configuration for Magento \'%s\' not supported (MUST be one of CE or EE)',
527
                $magentoEdition
528
            )
529
        );
530
    }
531
532
    /**
533
     * Query whether or not, the passed directory is a Magento root directory.
534
     *
535
     * @param string $dir The directory to query
536
     *
537
     * @return boolean TRUE if the directory is a Magento root directory, else FALSE
538
     */
539
    protected function isMagentoRootDir($dir)
540
    {
541
        return is_file($this->getMagentoEnv($dir));
542
    }
543
544
    /**
545
     * Return's the path to the Magento file with the environment configuration.
546
     *
547
     * @param string $dir The path to the Magento root directory
548
     *
549
     * @return string The path to the Magento file with the environment configuration
550
     */
551
    protected function getMagentoEnv($dir)
552
    {
553
        return sprintf('%s/app/etc/env.php', $dir);
554
    }
555
}
556