Completed
Push — master ( d4177d...478de1 )
by Marcus
04:46
created

getConsoleOptionLoader()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 1
nc 1
nop 0
dl 0
loc 3
ccs 0
cts 3
cp 0
crap 2
rs 10
c 0
b 0
f 0
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\ConsoleOptionLoaderInterface;
26
use TechDivision\Import\Cli\Configuration\LibraryLoader;
27
use TechDivision\Import\Cli\Utils\DependencyInjectionKeys;
28
use TechDivision\Import\Cli\Utils\MagentoConfigurationKeys;
29
use TechDivision\Import\Utils\CommandNames;
30
use TechDivision\Import\Utils\EditionNamesInterface;
31
use TechDivision\Import\Utils\InputOptionKeysInterface;
32
use TechDivision\Import\Utils\Mappings\CommandNameToEntityTypeCode;
33
use TechDivision\Import\Configuration\ConfigurationFactoryInterface;
34
35
/**
36
 * The configuration loader implementation.
37
 *
38
 * @author    Tim Wagner <[email protected]>
39
 * @copyright 2016 TechDivision GmbH <[email protected]>
40
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
41
 * @link      https://github.com/techdivision/import-cli-simple
42
 * @link      http://www.techdivision.com
43
 */
44
class SimpleConfigurationLoader implements ConfigurationLoaderInterface
45
{
46
47
    /**
48
     * The key for the Magento Edition in the metadata extracted from the Composer configuration.
49
     *
50
     * @var string
51
     */
52
    const EDITION = 'edition';
53
54
    /**
55
     * The key for the Magento Version in the metadata extracted from the Composer configuration.
56
     *
57
     * @var string
58
     */
59
    const VERSION = 'version';
60
61
    /**
62
     * The container instance.
63
     *
64
     * @var \Symfony\Component\DependencyInjection\ContainerInterface
65
     */
66
    protected $container;
67
68
    /**
69
     * The actual input instance.
70
     *
71
     * @var \Symfony\Component\Console\Input\InputInterface
72
     */
73
    protected $input;
74
75
    /**
76
     * The library loader instance.
77
     *
78
     * @param \TechDivision\Import\Cli\LibraryLoader
79
     */
80
    protected $libraryLoader;
81
82
    /**
83
     * The configuration factory instance.
84
     *
85
     * @var \TechDivision\Import\Configuration\ConfigurationFactoryInterface
86
     */
87
    protected $configurationFactory;
88
89
    /**
90
     * The available command names.
91
     *
92
     * @var \TechDivision\Import\Utils\CommandNames
93
     */
94
    protected $commandNames;
95
96
    /**
97
     * The mapping of the command names to the entity type codes
98
     *
99
     * @var \TechDivision\Import\Utils\Mappings\CommandNameToEntityTypeCode
100
     */
101
    protected $commandNameToEntityTypeCode;
102
103
    /**
104
     * The console option loader instance.
105
     *
106
     * @var \TechDivision\Import\ConsoleOptionLoaderInterface
107
     */
108
    protected $consoleOptionLoader;
109
110
    /**
111
     * The default sorting for the edition detection.
112
     *
113
     * @var array
114
     */
115
    protected $editionSortOrder = array(
116
        EditionNamesInterface::EE,
117
        EditionNamesInterface::CE
118
    );
119
120
    /**
121
     * Initializes the configuration loader.
122
     *
123
     * @param \Symfony\Component\Console\Input\InputInterface                  $input                        The input instance
124
     * @param \Symfony\Component\DependencyInjection\ContainerInterface        $container                    The container instance
125
     * @param \TechDivision\Import\Cli\Configuration\LibraryLoader             $libraryLoader                The configuration loader instance
126
     * @param \TechDivision\Import\Configuration\ConfigurationFactoryInterface $configurationFactory         The configuration factory instance
127
     * @param \TechDivision\Import\Utils\CommandNames                          $commandNames                 The available command names
128
     * @param \TechDivision\Import\Utils\Mappings\CommandNameToEntityTypeCode  $commandNameToEntityTypeCodes The mapping of the command names to the entity type codes
129
     * @param \TechDivision\Import\ConsoleOptionLoaderInterface                $consoleOptionLoader          The console option loader instance
130
     */
131
    public function __construct(
132
        InputInterface $input,
133
        ContainerInterface $container,
134
        LibraryLoader $libraryLoader,
135
        ConfigurationFactoryInterface $configurationFactory,
136
        CommandNames $commandNames,
137
        CommandNameToEntityTypeCode $commandNameToEntityTypeCodes,
138
        ConsoleOptionLoaderInterface $consoleOptionLoader
139
    ) {
140
141
        // set the passed instances
142
        $this->input = $input;
143
        $this->container = $container;
144
        $this->libraryLoader = $libraryLoader;
145
        $this->configurationFactory = $configurationFactory;
146
        $this->commandNames = $commandNames;
147
        $this->commandNameToEntityTypeCode = $commandNameToEntityTypeCodes;
148
        $this->consoleOptionLoader = $consoleOptionLoader;
149
    }
150
151
    /**
152
     * Factory implementation to create a new initialized configuration instance.
153
     *
154
     * If command line options are specified, they will always override the
155
     * values found in the configuration file.
156
     *
157
     * @return \TechDivision\Import\Configuration\ConfigurationInterface The configuration instance
158
     */
159
    public function load()
160
    {
161
162
        // initially try to create the configuration instance
163
        $instance = $this->createInstance();
164
165
        // we have to set the entity type code at least
166
        $instance->setEntityTypeCode($this->getEntityTypeCode());
167
168
        // load and merge the console options
169
        $this->getConsoleOptionLoader()->load($instance);
170
171
        // return the initialized configuration instance
172
        return $instance;
173
    }
174
175
    /**
176
     * This method create the configuration instance from the configuration file
177
     * defined by the commandline args and options.
178
     *
179
     * @return \TechDivision\Import\Configuration\ConfigurationInterface The configuration instance loaded from the configuration file
180
     * @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
181
     */
182
    protected function createInstance()
183
    {
184
185
        // load the actual vendor directory and entity type code
186
        $vendorDir = $this->getVendorDir();
187
188
        // the path of the JMS serializer directory, relative to the vendor directory
189
        $jmsDir = DIRECTORY_SEPARATOR . 'jms' . DIRECTORY_SEPARATOR . 'serializer' . DIRECTORY_SEPARATOR . 'src';
190
191
        // try to find the path to the JMS Serializer annotations
192
        if (!file_exists($annotationDir = $vendorDir . DIRECTORY_SEPARATOR . $jmsDir)) {
193
            // stop processing, if the JMS annotations can't be found
194
            throw new \Exception(
195
                sprintf(
196
                    'The jms/serializer libarary can not be found in one of "%s"',
197
                    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

197
                    implode(', ', /** @scrutinizer ignore-type */ $vendorDir)
Loading history...
198
                )
199
            );
200
        }
201
202
        // register the autoloader for the JMS serializer annotations
203
        \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. Annotations will be autoloaded in 2.0. ( Ignorable by Annotation )

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

203
        /** @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...
204
            'JMS\Serializer\Annotation',
205
            $annotationDir
206
        );
207
208
        // try to load the Magento installation directory
209
        $installationDir = $this->input->getOption(InputOptionKeysInterface::INSTALLATION_DIR);
210
211
        // query whether or not, a configuration file has been specified
212
        $configuration = $this->input->getOption(InputOptionKeysInterface::CONFIGURATION);
213
214
        // load the configuration from the file with the given filename
215
        $instance = $configuration ? $this->createConfiguration($configuration) : $this->createConfiguration();
216
217
        // query whether or not the installation directory is a valid Magento root directory
218
        if ($this->isMagentoRootDir($installationDir)) {
0 ignored issues
show
Bug introduced by
It seems like $installationDir 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

218
        if ($this->isMagentoRootDir(/** @scrutinizer ignore-type */ $installationDir)) {
Loading history...
219
            // if yes, try to load the Magento Edition from the Composer configuration file
220
            $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

220
            $metadata = $this->getEditionMapping(/** @scrutinizer ignore-type */ $installationDir);
Loading history...
221
            // initialize/override the Magento edition/version with the values from the Magento installation
222
            $instance->setMagentoEdition($metadata[SimpleConfigurationLoader::EDITION]);
223
            $instance->setMagentoVersion($metadata[SimpleConfigurationLoader::VERSION]);
224
        }
225
226
        // initialize/override the Magento edition with the value from the command line
227
        if ($magentoEdition = $this->input->getOption(InputOptionKeysInterface::MAGENTO_EDITION)) {
228
            $instance->setMagentoEdition($magentoEdition);
229
        }
230
231
        // initialize/override the Magento version with the value from the command line
232
        if ($magentoVersion = $this->input->getOption(InputOptionKeysInterface::MAGENTO_VERSION)) {
233
            $instance->setMagentoVersion($magentoVersion);
234
        }
235
236
        // set the actual command name in the configuration
237
        $instance->setCommandName($this->input->getFirstArgument());
238
239
        // return the instance
240
        return $instance;
241
    }
242
243
    /**
244
     * Create and return a new configuration instance from the passed configuration filename
245
     * after merging additional specified params from the commandline.
246
     *
247
     * @param string|null $filename The configuration filename to use
248
     *
249
     * @return \TechDivision\Import\Configuration\ConfigurationInterface The configuration instance
250
     */
251
    protected function createConfiguration($filename = null)
252
    {
253
254
        // initialize the params specified with the --params parameter
255
        $params = null;
256
257
        // try to load the params from the commandline
258
        if ($this->input->hasOptionSpecified(InputOptionKeysInterface::PARAMS) && $this->input->getOption(InputOptionKeysInterface::PARAMS)) {
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

258
        if ($this->input->/** @scrutinizer ignore-call */ hasOptionSpecified(InputOptionKeysInterface::PARAMS) && $this->input->getOption(InputOptionKeysInterface::PARAMS)) {

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...
259
            $params = $this->input->getOption(InputOptionKeysInterface::PARAMS);
260
        }
261
262
        // initialize the params file specified with the --params-file parameter
263
        $paramsFile = null;
264
265
        // try to load the path of the params file from the commandline
266
        if ($this->input->hasOptionSpecified(InputOptionKeysInterface::PARAMS_FILE) && $this->input->getOption(InputOptionKeysInterface::PARAMS_FILE)) {
267
            $paramsFile = $this->input->getOption(InputOptionKeysInterface::PARAMS_FILE);
268
        }
269
270
        // if a filename has been passed, try to load the configuration from the file
271
        if (is_file($filename)) {
272
            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

272
            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...
273
        }
274
275
        // initialize the array for the directories
276
        $directories = array();
277
278
        // set the default file format
279
        $format = 'json';
280
281
        // load the actual vendor directory and entity type code
282
        $vendorDir = $this->getVendorDir();
283
284
        // load the default configuration directory from the DI configuration
285
        $defaultConfigurationDir = $this->getContainer()->getParameter(DependencyInjectionKeys::APPLICATION_DEFAULT_CONFIGURATION_DIR);
286
287
        // load the directories that has to be parsed for configuration files1
288
        foreach ($this->getDefaultLibraries() as $defaultLibrary) {
289
            // initialize the directory name
290
            $directory = implode(
291
                DIRECTORY_SEPARATOR,
292
                array_merge(
293
                    array($vendorDir),
294
                    explode('/', $defaultLibrary),
295
                    explode('/', $defaultConfigurationDir)
296
                )
297
            );
298
299
            // query whether or not the directory is available1
300
            if (is_dir($directory)) {
301
                $directories[] = $directory;
302
            }
303
        }
304
305
        // load the assumed installation directory
306
        $installationDir = $this->input->getOption(InputOptionKeysInterface::INSTALLATION_DIR);
307
308
        // initialize the default custom configuration directory
309
        $customConfigurationDir = implode(
310
            DIRECTORY_SEPARATOR,
311
            array_merge(
312
                array($installationDir),
313
                explode('/', $this->getContainer()->getParameter(DependencyInjectionKeys::APPLICATION_CUSTOM_CONFIGURATION_DIR))
314
            )
315
        );
316
317
        // query whether or not a custom configuration directory has been speified, if yes override the default one
318
        if ($this->input->hasOptionSpecified(InputOptionKeysInterface::CUSTOM_CONFIGURATION_DIR) && $this->input->getOption(InputOptionKeysInterface::CUSTOM_CONFIGURATION_DIR)) {
319
            $customConfigurationDir = $this->input->getOption(InputOptionKeysInterface::CUSTOM_CONFIGURATION_DIR);
320
        }
321
322
        // specify the default directory for custom configuration files
323
        if (is_dir($customConfigurationDir)) {
0 ignored issues
show
Bug introduced by
It seems like $customConfigurationDir can also be of type string[]; however, parameter $filename of is_dir() 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

323
        if (is_dir(/** @scrutinizer ignore-type */ $customConfigurationDir)) {
Loading history...
324
            $directories[] = $customConfigurationDir;
325
        }
326
327
        // load and return the configuration from the files found in the passed directories
328
        $instance = $this->configurationFactory->factoryFromDirectories($installationDir, $defaultConfigurationDir, $directories, $format, $params, $paramsFile);
0 ignored issues
show
Bug introduced by
It seems like $paramsFile can also be of type string[]; however, parameter $paramsFile of TechDivision\Import\Conf...actoryFromDirectories() 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

328
        $instance = $this->configurationFactory->factoryFromDirectories($installationDir, $defaultConfigurationDir, $directories, $format, $params, /** @scrutinizer ignore-type */ $paramsFile);
Loading history...
Bug introduced by
It seems like $params can also be of type string[]; however, parameter $params of TechDivision\Import\Conf...actoryFromDirectories() 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

328
        $instance = $this->configurationFactory->factoryFromDirectories($installationDir, $defaultConfigurationDir, $directories, $format, /** @scrutinizer ignore-type */ $params, $paramsFile);
Loading history...
Bug introduced by
It seems like $installationDir can also be of type string[]; however, parameter $installationDir of TechDivision\Import\Conf...actoryFromDirectories() 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

328
        $instance = $this->configurationFactory->factoryFromDirectories(/** @scrutinizer ignore-type */ $installationDir, $defaultConfigurationDir, $directories, $format, $params, $paramsFile);
Loading history...
Bug introduced by
Are you sure the assignment to $instance is correct as $this->configurationFact..., $params, $paramsFile) 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 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...
329
330
        // query whether or not we've an valid Magento root directory specified
331
        if ($this->isMagentoRootDir($installationDir)) {
0 ignored issues
show
Bug introduced by
It seems like $installationDir 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

331
        if ($this->isMagentoRootDir(/** @scrutinizer ignore-type */ $installationDir)) {
Loading history...
332
            // add the source directory if NOT specified in the configuration file
333
            if (($sourceDir = $instance->getSourceDir()) === null) {
334
                $instance->setSourceDir($sourceDir = sprintf('%s/var/importexport', $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

334
                $instance->setSourceDir($sourceDir = sprintf('%s/var/importexport', /** @scrutinizer ignore-type */ $installationDir));
Loading history...
335
            }
336
337
            // add the target directory if NOT specified in the configuration file
338
            if ($instance->getTargetDir() === null) {
339
                $instance->setTargetDir($sourceDir);
340
            }
341
        }
342
343
        // return the configuration instance
344
        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\Conf...\ConfigurationInterface.
Loading history...
345
    }
346
347
    /**
348
     * Return's the DI container instance.
349
     *
350
     * @return \Symfony\Component\DependencyInjection\ContainerInterface The DI container instance
351
     */
352
    protected function getContainer()
353
    {
354
        return $this->container;
355
    }
356
357
    /**
358
     * The console option loader instance.
359
     *
360
     * @return \TechDivision\Import\ConsoleOptionLoaderInterface The instance
361
     */
362
    protected function getConsoleOptionLoader()
363
    {
364
        return $this->consoleOptionLoader;
365
    }
366
367
    /**
368
     * Return's the absolute path to the actual vendor directory.
369
     *
370
     * @return string The absolute path to the actual vendor directory
371
     * @throws \Exception Is thrown, if none of the possible vendor directories can be found
372
     */
373
    protected function getVendorDir()
374
    {
375
        return $this->getContainer()->getParameter(DependencyInjectionKeys::CONFIGURATION_VENDOR_DIR);
376
    }
377
378
    /**
379
     * Return's the actual command name.
380
     *
381
     * @return string The actual command name
382
     */
383
    protected function getCommandName()
384
    {
385
        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...
386
    }
387
388
    /**
389
     * Return's the command's entity type code.
390
     *
391
     * @return string The command's entity type code
392
     * @throws \Exception Is thrown, if the command name can not be mapped
393
     */
394
    protected function getEntityTypeCode()
395
    {
396
397
        // try to map the command name to a entity type code
398
        if (array_key_exists($commandName = $this->getCommandName(), (array) $this->commandNameToEntityTypeCode)) {
399
            return $this->commandNameToEntityTypeCode[$commandName];
400
        }
401
402
        // throw an exception if not possible
403
        throw new \Exception(sprintf('Can\'t map command name %s to a entity type', $commandName));
404
    }
405
406
    /**
407
     * Returns the mapped Magento Edition from the passed Magento installation.
408
     *
409
     * @param string $installationDir The Magento installation directory
410
     *
411
     * @return array The array with the mapped Magento Edition (either CE or EE) + the Version
412
     * @throws \Exception Is thrown, if the passed installation directory doesn't contain a valid Magento installation
413
     */
414
    protected function getEditionMapping($installationDir)
415
    {
416
417
        // load the default edition mappings from the configuration
418
        $editionMappings = $this->getContainer()->getParameter(DependencyInjectionKeys::APPLICATION_EDITION_MAPPINGS);
419
420
        // load the composer file from the Magento root directory
421
        $composer = json_decode(file_get_contents($composerFile = sprintf('%s/composer.lock', $installationDir)), true);
422
423
        // initialize the array that contains the packages to identify the Magento edition
424
        $packages = array();
425
426
        // query whether or not packages are available in the composer file
427
        if (isset($composer[MagentoConfigurationKeys::COMPOSER_PACKAGES])) {
428
            // iterate over the available packages to figure out the ones that allows us to identify the Magento edition
429
            foreach ($composer[MagentoConfigurationKeys::COMPOSER_PACKAGES] as $package) {
430
                // try to load and explode the Magento Edition identifier from the Composer name
431
                $possibleEdition = $package[MagentoConfigurationKeys::COMPOSER_EDITION_NAME_ATTRIBUTE];
432
433
                // try to load and explode the Magento Edition from the Composer configuration
434
                if (isset($editionMappings[$possibleEdition])) {
435
                    // try to load and explode the Magento Version from the Composer configuration
436
                    if (isset($package[MagentoConfigurationKeys::COMPOSER_EDITION_VERSION_ATTRIBUTE])) {
437
                        // add Magento edition => version mapping and continue
438
                        $packages[$editionMappings[$possibleEdition]] = $package[MagentoConfigurationKeys::COMPOSER_EDITION_VERSION_ATTRIBUTE];
439
                        continue;
440
                    }
441
442
                    // throw an exception if the package has NO version defineds
443
                    throw new \Exception(
444
                        sprintf(
445
                            'Can\'t detect a valid Magento version for package "%s" in "%s", please set Magento Version with the "--magento-version" option',
446
                            $possibleEdition,
447
                            $composerFile
448
                        )
449
                    );
450
                }
451
            }
452
        }
453
454
        // create the default sort order for the edition detection
455
        $editionSortOrder = array_flip($this->editionSortOrder);
456
457
        // sort the packages according the default sort order
458
        uksort($packages, function ($a, $b) use ($editionSortOrder) {
459
            return $editionSortOrder[$a] <=> $editionSortOrder[$b];
460
        });
461
462
        // return the array with the Magento Version/Edition data
463
        foreach ($packages as $edition => $version) {
464
            return array(
465
                SimpleConfigurationLoader::EDITION => $edition,
466
                SimpleConfigurationLoader::VERSION => $version
467
            );
468
        }
469
470
        // throw an exception if NO edition information can be found in the composer.lock file
471
        throw new \Exception(
472
            sprintf(
473
                'Can\'t detect a valid Magento edition/version in "%s", please pass them with the "--magento-edition" and "--magento-version" options',
474
                $composerFile
475
            )
476
        );
477
    }
478
479
480
    /**
481
     * Return's the application's default libraries.
482
     *
483
     * @return array The default libraries
484
     */
485
    protected function getDefaultLibraries()
486
    {
487
488
        // load the default libraries from the configuration
489
        $defaultLibraries = $this->getContainer()->getParameter(DependencyInjectionKeys::APPLICATION_DEFAULT_LIBRARIES);
490
491
        // initialize the array for the libraries
492
        $libraries = array();
493
494
        // append each library only ONCE
495
        foreach ($defaultLibraries as $libraries) {
496
            foreach ($libraries as $library) {
497
                if (in_array($library, $libraries)) {
498
                    continue;
499
                }
500
                // append the library
501
                $libraries[] = $library;
502
            }
503
        }
504
505
        // return the array with the libraries
506
        return $libraries;
507
    }
508
509
    /**
510
     * Query whether or not, the passed directory is a Magento root directory.
511
     *
512
     * @param string $dir The directory to query
513
     *
514
     * @return boolean TRUE if the directory is a Magento root directory, else FALSE
515
     */
516
    protected function isMagentoRootDir($dir)
517
    {
518
        return is_file($this->getMagentoEnv($dir));
519
    }
520
521
    /**
522
     * Return's the path to the Magento file with the environment configuration.
523
     *
524
     * @param string $dir The path to the Magento root directory
525
     *
526
     * @return string The path to the Magento file with the environment configuration
527
     */
528
    protected function getMagentoEnv($dir)
529
    {
530
        return sprintf('%s/app/etc/env.php', $dir);
531
    }
532
}
533