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

ConfigurationLoader::getMagentoEnv()   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 1
Bugs 0 Features 0
Metric Value
cc 1
eloc 1
c 1
b 0
f 0
nc 1
nop 1
dl 0
loc 3
ccs 0
cts 1
cp 0
crap 2
rs 10
1
<?php
2
3
/**
4
 * TechDivision\Import\Cli\ConfigurationLoader
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 Psr\Log\LogLevel;
24
use Ramsey\Uuid\Uuid;
25
use TechDivision\Import\ConfigurationInterface;
26
use TechDivision\Import\Configuration\Jms\Configuration\Database;
27
use TechDivision\Import\Cli\Command\InputArgumentKeys;
28
use TechDivision\Import\Cli\Command\InputOptionKeys;
29
use TechDivision\Import\Cli\Utils\DependencyInjectionKeys;
30
use TechDivision\Import\Cli\Utils\MagentoConfigurationKeys;
31
32
/**
33
 * The configuration loader implementation.
34
 *
35
 * @author    Tim Wagner <[email protected]>
36
 * @copyright 2016 TechDivision GmbH <[email protected]>
37
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
38
 * @link      https://github.com/techdivision/import-cli-simple
39
 * @link      http://www.techdivision.com
40
 */
41
class ConfigurationLoader extends SimpleConfigurationLoader
42
{
43
44
    /**
45
     * Factory implementation to create a new initialized configuration instance.
46
     *
47
     * If command line options are specified, they will always override the
48
     * values found in the configuration file.
49
     *
50
     * @return \TechDivision\Import\ConfigurationInterface The configuration instance
51
     * @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
52
     */
53
    public function load()
54
    {
55
56
        // load the configuration instance
57
        $instance = parent::load();
58
59
        // set the serial that has been specified as command line option (or the default value)
60
        $instance->setSerial($this->input->getOption(InputOptionKeys::SERIAL));
61
62
        // query whether or not operation names has been specified as command line
63
        // option, if yes override the value from the configuration file
64
        if ($operationNames = $this->input->getArgument(InputArgumentKeys::OPERATION_NAMES)) {
65
            // append the names of the operations we want to execute to the configuration
66
            foreach ($operationNames as $operationName) {
67
                $instance->addOperationName($operationName);
0 ignored issues
show
Bug introduced by
The method addOperationName() does not exist on TechDivision\Import\ConfigurationInterface. ( Ignorable by Annotation )

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

67
                $instance->/** @scrutinizer ignore-call */ 
68
                           addOperationName($operationName);

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...
68
            }
69
        }
70
71
        // query whether or not a directory containing the imported files has been specified as command line
72
        // option, if yes override the value from the configuration file
73
        if ($targetDir = $this->input->getOption(InputOptionKeys::TARGET_DIR)) {
74
            $instance->setTargetDir($targetDir);
75
        }
76
77
        // query whether or not a directory containing the archived imported files has been specified as command line
78
        // option, if yes override the value from the configuration file
79
        if ($archiveDir = $this->input->getOption(InputOptionKeys::ARCHIVE_DIR)) {
80
            $instance->setArchiveDir($archiveDir);
81
        }
82
83
        // query whether or not the log level has been specified as command line
84
        // option, if yes override the value from the configuration file
85
        if ($logLevel = $this->input->getOption(InputOptionKeys::LOG_LEVEL)) {
86
            $instance->setLogLevel($logLevel);
87
        }
88
89
        // query whether or not a prefix for the move files subject has been specified as command line
90
        // option, if yes override the value from the configuration file
91
        if ($moveFilesPrefix = $this->input->getOption(InputOptionKeys::MOVE_FILES_PREFIX)) {
92
            $instance->setMoveFilesPrefix($moveFilesPrefix);
0 ignored issues
show
Bug introduced by
The method setMoveFilesPrefix() does not exist on TechDivision\Import\ConfigurationInterface. ( Ignorable by Annotation )

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

92
            $instance->/** @scrutinizer ignore-call */ 
93
                       setMoveFilesPrefix($moveFilesPrefix);

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...
93
        }
94
95
        // query whether or not the debug mode has been specified as command line
96
        // option, if yes override the value from the configuration file
97
        if ($this->input->hasOptionSpecified(InputOptionKeys::ARCHIVE_ARTEFACTS)) {
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

97
        if ($this->input->/** @scrutinizer ignore-call */ hasOptionSpecified(InputOptionKeys::ARCHIVE_ARTEFACTS)) {

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...
98
            $instance->setArchiveArtefacts($instance->mapBoolean($this->input->getOption(InputOptionKeys::ARCHIVE_ARTEFACTS)));
99
        }
100
101
        // query whether or not the debug mode has been specified as command line
102
        // option, if yes override the value from the configuration file
103
        if ($this->input->hasOptionSpecified(InputOptionKeys::DEBUG_MODE)) {
104
            $instance->setDebugMode($instance->mapBoolean($this->input->getOption(InputOptionKeys::DEBUG_MODE)));
105
        }
106
107
        // query whether or not the single transaction flag has been specified as command line
108
        // option, if yes override the value from the configuration file
109
        if ($this->input->hasOptionSpecified(InputOptionKeys::SINGLE_TRANSACTION)) {
110
            $instance->setSingleTransaction($instance->mapBoolean($this->input->getOption(InputOptionKeys::SINGLE_TRANSACTION)));
111
        }
112
113
        // query whether or not the cache flag has been specified as command line
114
        // option, if yes override the value from the configuration file
115
        if ($this->input->hasOptionSpecified(InputOptionKeys::CACHE_ENABLED)) {
116
            $instance->setCacheEnabled($instance->mapBoolean($this->input->getOption(InputOptionKeys::CACHE_ENABLED)));
117
        }
118
119
        // query whether or not the move files flag has been specified as command line
120
        // option, if yes override the value from the configuration file
121
        if ($this->input->hasOptionSpecified(InputOptionKeys::MOVE_FILES)) {
122
            $instance->setMoveFiles($instance->mapBoolean($this->input->getOption(InputOptionKeys::MOVE_FILES)));
0 ignored issues
show
Bug introduced by
The method setMoveFiles() does not exist on TechDivision\Import\ConfigurationInterface. ( Ignorable by Annotation )

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

122
            $instance->/** @scrutinizer ignore-call */ 
123
                       setMoveFiles($instance->mapBoolean($this->input->getOption(InputOptionKeys::MOVE_FILES)));

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...
123
        }
124
125
        // query whether or not the configurationfiles flag has been specified as command line
126
        // option, if yes override the value from the configuration file
127
        if ($this->input->hasOptionSpecified(InputOptionKeys::COMPILE)) {
128
            $instance->setCompile($instance->mapBoolean($this->input->getOption(InputOptionKeys::COMPILE)));
0 ignored issues
show
Bug introduced by
The method setCompile() does not exist on TechDivision\Import\ConfigurationInterface. ( Ignorable by Annotation )

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

128
            $instance->/** @scrutinizer ignore-call */ 
129
                       setCompile($instance->mapBoolean($this->input->getOption(InputOptionKeys::COMPILE)));

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...
129
        }
130
131
        // query whether or not we've an valid Magento root directory specified
132
        if ($this->isMagentoRootDir($installationDir = $instance->getInstallationDir())) {
133
            // if yes, add the database configuration
134
            $instance->addDatabase($this->getMagentoDbConnection($installationDir));
0 ignored issues
show
Bug introduced by
$this->getMagentoDbConnection($installationDir) of type array is incompatible with the type TechDivision\Import\Conf...eConfigurationInterface expected by parameter $database of TechDivision\Import\Conf...nterface::addDatabase(). ( Ignorable by Annotation )

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

134
            $instance->addDatabase(/** @scrutinizer ignore-type */ $this->getMagentoDbConnection($installationDir));
Loading history...
135
136
            // add the source directory if NOT specified in the configuration file
137
            if (($sourceDir = $instance->getSourceDir()) === null) {
0 ignored issues
show
introduced by
The condition $sourceDir = $instance->getSourceDir() === null is always false.
Loading history...
138
                $instance->setSourceDir($sourceDir = sprintf('%s/var/importexport', $installationDir));
139
            }
140
141
            // add the target directory if NOT specified in the configuration file
142
            if ($instance->getTargetDir() === null) {
0 ignored issues
show
introduced by
The condition $instance->getTargetDir() === null is always false.
Loading history...
143
                $instance->setTargetDir($sourceDir);
144
            }
145
        }
146
147
        // query whether or not a DB ID has been specified as command line
148
        // option, if yes override the value from the configuration file
149
        if ($useDbId = $this->input->getOption(InputOptionKeys::USE_DB_ID)) {
150
            $instance->setUseDbId($useDbId);
151
        } else {
152
            // query whether or not a PDO DSN has been specified as command line
153
            // option, if yes override the value from the configuration file
154
            if ($dsn = $this->input->getOption(InputOptionKeys::DB_PDO_DSN)) {
155
                // first REMOVE all other database configurations
156
                $instance->clearDatabases();
157
158
                // add the database configuration
159
                $instance->addDatabase(
160
                    $this->newDatabaseConfiguration(
161
                        $dsn,
162
                        $this->input->getOption(InputOptionKeys::DB_USERNAME),
163
                        $this->input->getOption(InputOptionKeys::DB_PASSWORD)
164
                    )
165
                );
166
            }
167
        }
168
169
        // query whether or not a DB ID has been specified as command line
170
        // option, if yes override the value from the configuration file
171
        if ($tablePrefix = $this->input->getOption(InputOptionKeys::DB_TABLE_PREFIX)) {
172
            $instance->getDatabase()->setTablePrefix($tablePrefix);
0 ignored issues
show
Bug introduced by
The method setTablePrefix() does not exist on TechDivision\Import\Conf...eConfigurationInterface. ( Ignorable by Annotation )

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

172
            $instance->getDatabase()->/** @scrutinizer ignore-call */ setTablePrefix($tablePrefix);

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...
173
        }
174
175
        // extend the plugins with the main configuration instance
176
        /** @var \TechDivision\Import\Cli\Configuration\Subject $subject */
177
        foreach ($instance->getPlugins() as $plugin) {
178
            // set the configuration instance on the plugin
179
            $plugin->setConfiguration($instance);
180
181
            // query whether or not the plugin has subjects configured
182
            if ($subjects = $plugin->getSubjects()) {
183
                // extend the plugin's subjects with the main configuration instance
184
                /** @var \TechDivision\Import\Cli\Configuration\Subject $subject */
185
                foreach ($subjects as $subject) {
186
                    // set the configuration instance on the subject
187
                    $subject->setConfiguration($instance);
188
                }
189
            }
190
        }
191
192
        // query whether or not the debug mode is enabled and log level
193
        // has NOT been overwritten with a commandline option
194
        if ($instance->isDebugMode() && !$this->input->getOption(InputOptionKeys::LOG_LEVEL)) {
195
            // set debug log level, if log level has NOT been overwritten on command line
196
            $instance->setLogLevel(LogLevel::DEBUG);
197
        }
198
199
        // prepend the array with the Magento Edition specific core libraries
200
        $instance->setExtensionLibraries(
201
            array_merge(
202
                $this->getDefaultLibraries($instance->getMagentoEdition()),
203
                $instance->getExtensionLibraries()
204
            )
205
        );
206
207
        // load the extension libraries, if configured
208
        $this->libraryLoader->load($instance);
209
210
        // register the configured aliases in the DI container, this MUST
211
        // happen after the libraries have been loaded, else it would not
212
        // be possible to override existing aliases
213
        $this->initializeAliases($instance);
214
215
        // return the initialized configuration instance
216
        return $instance;
217
    }
218
219
    /**
220
     * Return's the requested Magento DB connction data.
221
     *
222
     * @param string $dir            The path to the Magento root directory
223
     * @param string $connectionName The connection name to return the data for
224
     *
225
     * @return array The connection data
226
     * @throws \Exception Is thrown, if the requested DB connection is not available
227
     */
228
    protected function getMagentoDbConnection($dir, $connectionName = 'default')
229
    {
230
231
        // load the magento environment
232
        $env = require $this->getMagentoEnv($dir);
233
234
        // query whether or not, the requested connection is available
235
        if (isset($env[MagentoConfigurationKeys::DB][MagentoConfigurationKeys::CONNECTION][$connectionName])) {
236
            // load the databaase connection
237
            $db = $env[MagentoConfigurationKeys::DB];
238
            // load the connection data
239
            $connection = $db[MagentoConfigurationKeys::CONNECTION][$connectionName];
240
241
            // create and return a new database configuration
242
            return $this->newDatabaseConfiguration(
0 ignored issues
show
Bug Best Practice introduced by
The expression return $this->newDatabas...::TABLE_PREFIX] : null) returns the type TechDivision\Import\Conf...\Configuration\Database which is incompatible with the documented return type array.
Loading history...
243
                $this->newDsn($connection[MagentoConfigurationKeys::HOST], $connection[MagentoConfigurationKeys::DBNAME]),
244
                $connection[MagentoConfigurationKeys::USERNAME],
245
                $connection[MagentoConfigurationKeys::PASSWORD],
246
                false,
247
                null,
248
                isset($db[MagentoConfigurationKeys::TABLE_PREFIX]) ? $db[MagentoConfigurationKeys::TABLE_PREFIX] : null
249
            );
250
        }
251
252
        // throw an execption if not
253
        throw new \Exception(sprintf('Requested Magento DB connection "%s" not found in Magento "%s"', $connectionName, $dir));
254
    }
255
256
    /**
257
     * Create's and return's a new database configuration instance, initialized with
258
     * the passed values.
259
     *
260
     * @param string      $dsn         The DSN to use
261
     * @param string      $username    The username to  use
262
     * @param string|null $password    The passed to use
263
     * @param boolean     $default     TRUE if this should be the default connection
264
     * @param string      $id          The ID to use
265
     * @param string      $tablePrefix The table prefix to use
266
     *
267
     * @return \TechDivision\Import\Configuration\Jms\Configuration\Database The database configuration instance
268
     */
269
    protected function newDatabaseConfiguration($dsn, $username = 'root', $password = null, $default = true, $id = null, $tablePrefix = null)
270
    {
271
272
        // initialize a new database configuration
273
        $database = new Database();
274
        $database->setDsn($dsn);
275
        $database->setDefault($default);
276
        $database->setUsername($username);
277
278
        // query whether or not an ID has been passed
279
        if ($id === null) {
280
            $id = Uuid::uuid4()->__toString();
0 ignored issues
show
Bug introduced by
The method __toString() does not exist on Ramsey\Uuid\UuidInterface. Did you maybe mean toString()? ( Ignorable by Annotation )

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

280
            $id = Uuid::uuid4()->/** @scrutinizer ignore-call */ __toString();

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...
281
        }
282
283
        // set the ID
284
        $database->setId($id);
285
286
        // query whether or not a password has been passed
287
        if ($password) {
288
            $database->setPassword($password);
289
        }
290
291
        // query whether or not a table prefix has been passed
292
        if ($tablePrefix) {
293
            $database->setTablePrefix($tablePrefix);
0 ignored issues
show
Bug introduced by
The method setTablePrefix() does not exist on TechDivision\Import\Conf...\Configuration\Database. ( Ignorable by Annotation )

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

293
            $database->/** @scrutinizer ignore-call */ 
294
                       setTablePrefix($tablePrefix);

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...
294
        }
295
296
        // return the database configuration
297
        return $database;
298
    }
299
300
    /**
301
     * Create's and return's a new DSN from the passed values.
302
     *
303
     * @param string $host    The host to use
304
     * @param string $dbName  The database name to use
305
     * @param string $charset The charset to use
306
     *
307
     * @return string The DSN
308
     */
309
    protected function newDsn($host, $dbName, $charset = 'utf8')
310
    {
311
        return sprintf('mysql:host=%s;dbname=%s;charset=%s', $host, $dbName, $charset);
312
    }
313
314
    /**
315
     * Return's the Magento Edition specific default libraries. Supported Magento Editions are CE or EE.
316
     *
317
     * @param string $magentoEdition The Magento Edition to return the libraries for
318
     *
319
     * @return array The Magento Edition specific default libraries
320
     * @throws \Exception Is thrown, if the passed Magento Edition is NOT supported
321
     */
322
    protected function getDefaultLibraries($magentoEdition)
323
    {
324
325
        // load the default libraries from the configuration
326
        $defaultLibraries = $this->getContainer()->getParameter(DependencyInjectionKeys::APPLICATION_DEFAULT_LIBRARIES);
327
328
        // query whether or not, default libraries for the passed edition are available
329
        if (isset($defaultLibraries[$edition = strtolower($magentoEdition)])) {
330
            return $defaultLibraries[$edition];
331
        }
332
333
        // throw an exception, if the passed edition is not supported
334
        throw new \Exception(
335
            sprintf(
336
                'Default libraries for Magento \'%s\' not supported (MUST be one of CE or EE)',
337
                $magentoEdition
338
            )
339
        );
340
    }
341
342
    /**
343
     * Registers the configured aliases in the DI container.
344
     *
345
     * @param \TechDivision\Import\ConfigurationInterface $configuration The configuration with the aliases to register
346
     *
347
     * @return void
348
     */
349
    protected function initializeAliases(ConfigurationInterface $configuration)
350
    {
351
352
        // load the DI aliases
353
        $aliases = $configuration->getAliases();
354
355
        // register the DI aliases
356
        foreach ($aliases as $alias) {
357
            $this->getContainer()->setAlias($alias->getId(), $alias->getTarget());
0 ignored issues
show
Bug introduced by
The method setAlias() does not exist on Symfony\Component\Depend...tion\ContainerInterface. It seems like you code against a sub-type of Symfony\Component\Depend...tion\ContainerInterface such as Symfony\Component\Depend...ection\ContainerBuilder or Symfony\Component\Depend...ection\ContainerBuilder. ( Ignorable by Annotation )

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

357
            $this->getContainer()->/** @scrutinizer ignore-call */ setAlias($alias->getId(), $alias->getTarget());
Loading history...
358
        }
359
    }
360
}
361