Completed
Push — 8.x ( 8f4f77...63276b )
by Tim
03:16
created

getDefaultConfigurationFile()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 16
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 1
Bugs 0 Features 0
Metric Value
cc 2
eloc 7
c 1
b 0
f 0
nc 2
nop 1
dl 0
loc 16
ccs 0
cts 2
cp 0
crap 6
rs 10
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();
0 ignored issues
show
Bug introduced by
Are you sure the assignment to $instance is correct as $this->createInstanceFromDirectories() targeting TechDivision\Import\Cli\...stanceFromDirectories() seems to always return null.

This check looks for function or method calls that always return null and whose return value is assigned to a variable.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
$object = $a->getObject();

The method getObject() can return nothing but null, so it makes no sense to assign that value to a variable.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

Loading history...
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;
0 ignored issues
show
Bug Best Practice introduced by
The expression return $instance returns the type void which is incompatible with the documented return type TechDivision\Import\ConfigurationInterface.
Loading history...
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
Are you sure the usage of $this->configurationFact...rectories($directories) targeting TechDivision\Import\Conf...actoryFromDirectories() seems to always return null.

This check looks for function or method calls that always return null and whose return value is used.

class A
{
    function getObject()
    {
        return null;
    }

}

$a = new A();
if ($a->getObject()) {

The method getObject() can return nothing but null, so it makes no sense to use the return value.

The reason is most likely that a function or method is imcomplete or has been reduced for debug purposes.

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
261
            // return the configuration intance
262
            return $instance;
263
        }
264
265
        // finally, query whether or not the installation directory is a valid Magento root directory
266
        if (!$this->isMagentoRootDir($installationDir = $this->input->getOption(InputOptionKeys::INSTALLATION_DIR))) {
0 ignored issues
show
introduced by
The method isMagentoRootDir() does not exist on TechDivision\Import\Cli\SimpleConfigurationLoader. Maybe you want to declare this class abstract? ( Ignorable by Annotation )

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

266
        if (!$this->/** @scrutinizer ignore-call */ isMagentoRootDir($installationDir = $this->input->getOption(InputOptionKeys::INSTALLATION_DIR))) {
Loading history...
267
            throw new \Exception(
268
                sprintf(
269
                    'Directory "%s" specified with option "--installation-dir" is not a valid Magento root directory',
270
                    $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

270
                    /** @scrutinizer ignore-type */ $installationDir
Loading history...
271
                )
272
            );
273
        }
274
275
        // load the Magento Edition from the Composer configuration file
276
        $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

276
        $metadata = $this->getEditionMapping(/** @scrutinizer ignore-type */ $installationDir);
Loading history...
277
278
        // extract edition & version from the metadata
279
        $magentoEdition = $metadata[SimpleConfigurationLoader::EDITION];
280
        $magentoVersion = $metadata[SimpleConfigurationLoader::VERSION];
281
282
        // use the Magento Edition that has been detected by the installation directory
283
        $instance = $this->createConfiguration($this->getDefaultConfiguration($magentoEdition, $magentoVersion, $this->getEntityTypeCode()));
284
285
        // override the Magento Edition/Version
286
        $instance->setMagentoEdition($magentoEdition);
287
        $instance->setMagentoVersion($magentoVersion);
288
289
        // return the configuration intance
290
        return $instance;
291
    }
292
293
    /**
294
     * Create and return a new configuration instance from the passed configuration filename
295
     * after merging additional specified params from the commandline.
296
     *
297
     * @param string $filename The configuration filename to use
298
     *
299
     * @return \TechDivision\Import\ConfigurationInterface The configuration instance
300
     */
301
    protected function createConfiguration($filename)
302
    {
303
304
        // initialize the params specified with the --params parameter
305
        $params = null;
306
307
        // try to load the params from the commandline
308
        if ($this->input->hasOptionSpecified(InputOptionKeys::PARAMS) && $this->input->getOption(InputOptionKeys::PARAMS)) {
309
            $params = $this->input->getOption(InputOptionKeys::PARAMS);
310
        }
311
312
        // initialize the params file specified with the --params-file parameter
313
        $paramsFile = null;
314
315
        // try to load the path of the params file from the commandline
316
        if ($this->input->hasOptionSpecified(InputOptionKeys::PARAMS_FILE) && $this->input->getOption(InputOptionKeys::PARAMS_FILE)) {
317
            $paramsFile = $this->input->getOption(InputOptionKeys::PARAMS_FILE);
318
        }
319
320
        // create the configuration and return it
321
        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

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

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