Completed
Pull Request — master (#50)
by Tim
10:14
created

ImportCategoriesCommand::execute()   B

Complexity

Conditions 1
Paths 1

Size

Total Lines 45
Code Lines 25

Duplication

Lines 45
Ratio 100 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 45
loc 45
ccs 0
cts 31
cp 0
rs 8.8571
c 0
b 0
f 0
cc 1
eloc 25
nc 1
nop 2
crap 2
1
<?php
2
3
/**
4
 * TechDivision\Import\Cli\Command\ImportCategoriesCommand
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\Command;
22
23
use Rhumsaa\Uuid\Uuid;
24
use Psr\Log\LogLevel;
25
use Monolog\Logger;
26
use Monolog\Handler\ErrorLogHandler;
27
use JMS\Serializer\SerializerBuilder;
28
use TechDivision\Import\Cli\Simple;
29
use TechDivision\Import\Cli\Configuration;
30
use TechDivision\Import\Cli\Services\ImportProcessorFactory;
31
use TechDivision\Import\Cli\Services\RegistryProcessorFactory;
32
use Symfony\Component\Console\Command\Command;
33
use Symfony\Component\Console\Input\InputOption;
34
use Symfony\Component\Console\Input\InputInterface;
35
use Symfony\Component\Console\Output\OutputInterface;
36
use Symfony\Component\Console\Input\InputArgument;
37
use TechDivision\Import\Cli\Configuration\Database;
38
39
/**
40
 * The import command implementation.
41
 *
42
 * @author    Tim Wagner <[email protected]>
43
 * @copyright 2016 TechDivision GmbH <[email protected]>
44
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
45
 * @link      https://github.com/techdivision/import-cli-simple
46
 * @link      http://www.techdivision.com
47
 */
48 View Code Duplication
class ImportCategoriesCommand extends Command
0 ignored issues
show
Duplication introduced by
This class seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
49
{
50
51
    /**
52
     * Configures the current command.
53
     *
54
     * @return void
55
     * @see \Symfony\Component\Console\Command\Command::configure()
56
     */
57
    protected function configure()
58
    {
59
60
        // initialize the command with the required/optional options
61
        $this->setName('import:categories')
62
             ->setDescription('Imports categories in the configured Magento 2 instance')
63
             ->addArgument(
64
                 InputArgumentKeys::OPERATION_NAME,
65
                 InputArgument::OPTIONAL,
66
                 'The operation that has to be used for the import, one of "add-update", "replace" or "delete"',
67
                 InputArgumentKeys::OPERATION_NAME_ARG_REPLACE
68
             )
69
             ->addOption(
70
                 InputOptionKeys::CONFIGURATION,
71
                 null,
72
                 InputOption::VALUE_REQUIRED,
73
                 'Specify the pathname to the configuration file to use',
74
                 sprintf('%s/techdivision-import.json', getcwd())
75
             )
76
             ->addOption(
77
                 InputOptionKeys::INSTALLATION_DIR,
78
                 null,
79
                 InputOption::VALUE_REQUIRED,
80
                 'The Magento installation directory to which the files has to be imported'
81
             )
82
             ->addOption(
83
                 InputOptionKeys::SOURCE_DIR,
84
                 null,
85
                 InputOption::VALUE_REQUIRED,
86
                 'The directory that has to be watched for new files'
87
             )
88
             ->addOption(
89
                 InputOptionKeys::TARGET_DIR,
90
                 null,
91
                 InputOption::VALUE_REQUIRED,
92
                 'The target directory with the files that has been imported'
93
             )
94
             ->addOption(
95
                 InputOptionKeys::UTILITY_CLASS_NAME,
96
                 null,
97
                 InputOption::VALUE_REQUIRED,
98
                 'The utility class name with the SQL statements'
99
             )
100
             ->addOption(
101
                 InputOptionKeys::PREFIX,
102
                 null,
103
                 InputOption::VALUE_REQUIRED,
104
                 'The prefix of the CSV source file(s) that has/have to be imported'
105
             )
106
             ->addOption(
107
                 InputOptionKeys::MAGENTO_EDITION,
108
                 null,
109
                 InputOption::VALUE_REQUIRED,
110
                 'The Magento edition to be used, either one of CE or EE'
111
             )
112
             ->addOption(
113
                 InputOptionKeys::MAGENTO_VERSION,
114
                 null,
115
                 InputOption::VALUE_REQUIRED,
116
                 'The Magento version to be used, e. g. 2.1.2'
117
             )
118
             ->addOption(
119
                 InputOptionKeys::SOURCE_DATE_FORMAT,
120
                 null,
121
                 InputOption::VALUE_REQUIRED,
122
                 'The date format used in the CSV file(s)'
123
             )
124
             ->addOption(
125
                 InputOptionKeys::USE_DB_ID,
126
                 null,
127
                 InputOption::VALUE_REQUIRED,
128
                 'The explicit database ID used for the actual import process'
129
             )
130
             ->addOption(
131
                 InputOptionKeys::DB_PDO_DSN,
132
                 null,
133
                 InputOption::VALUE_REQUIRED,
134
                 'The DSN used to connect to the Magento database where the data has to be imported, e. g. mysql:host=127.0.0.1;dbname=magento'
135
             )
136
             ->addOption(
137
                 InputOptionKeys::DB_USERNAME,
138
                 null,
139
                 InputOption::VALUE_REQUIRED,
140
                 'The username used to connect to the Magento database'
141
             )
142
             ->addOption(
143
                 InputOptionKeys::DB_PASSWORD,
144
                 null,
145
                 InputOption::VALUE_REQUIRED,
146
                 'The password used to connect to the Magento database'
147
             )
148
             ->addOption(
149
                 InputOptionKeys::LOG_LEVEL,
150
                 null,
151
                 InputOption::VALUE_REQUIRED,
152
                 'The log level to use'
153
             )
154
             ->addOption(
155
                 InputOptionKeys::IGNORE_PID,
156
                 null,
157
                 InputOption::VALUE_REQUIRED,
158
                 'Whether or not an existing PID should be ignored or not'
159
             )
160
             ->addOption(
161
                 InputOptionKeys::DEBUG_MODE,
162
                 null,
163
                 InputOption::VALUE_REQUIRED,
164
                 'Whether use the debug mode or not'
165
             )
166
             ->addOption(
167
                 InputOptionKeys::PID_FILENAME,
168
                 null,
169
                 InputOption::VALUE_REQUIRED,
170
                 'The explicit PID filename to use',
171
                 sprintf('%s/%s', sys_get_temp_dir(), Configuration::PID_FILENAME)
172
             );
173
    }
174
175
    /**
176
     * Factory implementation to create a new initialized configuration instance.
177
     *
178
     * If command line options are specified, they will always override the
179
     * values found in the configuration file.
180
     *
181
     * @param \Symfony\Component\Console\Input\InputInterface $input The Symfony console input instance
182
     *
183
     * @return \TechDivision\Import\Cli\Configuration The configuration instance
184
     * @throws \Exception Is thrown, if the specified configuration file doesn't exist
185
     */
186
    protected function configurationFactory(InputInterface $input)
187
    {
188
189
        // load the configuration filename we want to use
190
        $filename = $input->getOption(InputOptionKeys::CONFIGURATION);
191
192
        // load the JSON data
193
        if (!$jsonData = file_get_contents($filename)) {
194
            throw new \Exception(sprintf('Can\'t load configuration file %s', $filename));
195
        }
196
197
        // initialize the JMS serializer and load the configuration
198
        $serializer = SerializerBuilder::create()->build();
199
        /** @var \TechDivision\Import\Cli\Configuration $instance */
200
        $instance = $serializer->deserialize($jsonData, 'TechDivision\Import\Cli\Configuration', 'json');
201
202
        // query whether or not an operation name has been specified as command line
203
        // option, if yes override the value from the configuration file
204
        if ($input->hasArgument(InputArgumentKeys::OPERATION_NAME)) {
205
            $instance->setOperationName($input->getArgument(InputArgumentKeys::OPERATION_NAME));
206
        }
207
208
        // query whether or not a Magento installation directory has been specified as command line
209
        // option, if yes override the value from the configuration file
210
        if ($installationDir = $input->getOption(InputOptionKeys::INSTALLATION_DIR)) {
211
            $instance->setInstallationDir($installationDir);
212
        }
213
214
        // query whether or not a directory for the source files has been specified as command line
215
        // option, if yes override the value from the configuration file
216
        if ($sourceDir = $input->getOption(InputOptionKeys::SOURCE_DIR)) {
217
            $instance->setSourceDir($sourceDir);
218
        }
219
220
        // query whether or not a directory containing the imported files has been specified as command line
221
        // option, if yes override the value from the configuration file
222
        if ($targetDir = $input->getOption(InputOptionKeys::TARGET_DIR)) {
223
            $instance->setTargetDir($targetDir);
224
        }
225
226
        // query whether or not a source date format has been specified as command
227
        // line  option, if yes override the value from the configuration file
228
        if ($sourceDateFormat = $input->getOption(InputOptionKeys::SOURCE_DATE_FORMAT)) {
229
            $instance->setSourceDateFormat($sourceDateFormat);
230
        }
231
232
        // query whether or not a Magento edition has been specified as command line
233
        // option, if yes override the value from the configuration file
234
        if ($magentoEdition = $input->getOption(InputOptionKeys::MAGENTO_EDITION)) {
235
            $instance->setMagentoEdition($magentoEdition);
236
        }
237
238
        // query whether or not a Magento version has been specified as command line
239
        // option, if yes override the value from the configuration file
240
        if ($magentoVersion = $input->getOption(InputOptionKeys::MAGENTO_VERSION)) {
241
            $instance->setMagentoVersion($magentoVersion);
242
        }
243
244
        // query whether or not a DB ID has been specified as command line
245
        // option, if yes override the value from the configuration file
246
        if ($useDbId = $input->getOption(InputOptionKeys::USE_DB_ID)) {
247
            $instance->setUseDbId($useDbId);
248
        } else {
249
            // query whether or not a PDO DSN has been specified as command line
250
            // option, if yes override the value from the configuration file
251
            if ($dsn = $input->getOption(InputOptionKeys::DB_PDO_DSN)) {
252
                // first REMOVE all other database configurations
253
                $instance->clearDatabases();
254
255
                // initialize a new database configuration
256
                $database = new Database();
257
                $database->setId(Uuid::uuid4()->__toString());
258
                $database->setDefault(true);
259
                $database->setDsn($dsn);
260
261
                // query whether or not a DB username has been specified as command line
262
                // option, if yes override the value from the configuration file
263
                if ($username = $input->getOption(InputOptionKeys::DB_USERNAME)) {
264
                    $database->setUsername($username);
265
                }
266
267
                // query whether or not a DB password has been specified as command line
268
                // option, if yes override the value from the configuration file
269
                if ($password = $input->getOption(InputOptionKeys::DB_PASSWORD)) {
270
                    $database->setPassword($password);
271
                }
272
273
                // add the database configuration
274
                $instance->addDatabase($database);
275
            }
276
        }
277
278
        // query whether or not the debug mode has been specified as command line
279
        // option, if yes override the value from the configuration file
280
        if ($debugMode = $input->getOption(InputOptionKeys::DEBUG_MODE)) {
281
            $instance->setDebugMode($instance->mapBoolean($debugMode));
282
        }
283
284
        // query whether or not the ignore PID flag has been specified as command line
285
        // option, if yes override the value from the configuration file
286
        if ($ignorePid = $input->getOption(InputOptionKeys::IGNORE_PID)) {
287
            $instance->setIgnorePid($instance->mapBoolean($ignorePid));
288
        }
289
290
        // query whether or not the log level has been specified as command line
291
        // option, if yes override the value from the configuration file
292
        if ($logLevel = $input->getOption(InputOptionKeys::LOG_LEVEL)) {
293
            $instance->setLogLevel($logLevel);
294
        }
295
296
        // query whether or not a PID filename has been specified as command line
297
        // option, if yes override the value from the configuration file
298
        if ($pidFilename = $input->getOption(InputOptionKeys::PID_FILENAME)) {
299
            $instance->setPidFilename($pidFilename);
300
        }
301
302
        // extend the plugins with the main configuration instance
303
        /** @var \TechDivision\Import\Cli\Configuration\Subject $subject */
304
        foreach ($instance->getPlugins() as $plugin) {
305
            // set the configuration instance on the plugin
306
            $plugin->setConfiguration($instance);
307
308
            // query whether or not the plugin has subjects configured
309
            if ($subjects = $plugin->getSubjects()) {
310
                // extend the plugin's subjects with the main configuration instance
311
                /** @var \TechDivision\Import\Cli\Configuration\Subject $subject */
312
                foreach ($subjects as $subject) {
313
                    // set the configuration instance on the subject
314
                    $subject->setConfiguration($instance);
315
                }
316
            }
317
        }
318
319
        // query whether or not the debug mode is enabled and log level
320
        // has NOT been overwritten with a commandline option
321
        if ($instance->isDebugMode() && !$input->getOption(InputOptionKeys::LOG_LEVEL)) {
322
            // set debug log level, if log level has NOT been overwritten on command line
323
            $instance->setLogLevel(LogLevel::DEBUG);
324
        }
325
326
        // return the initialized configuration instance
327
        return $instance;
328
    }
329
330
    /**
331
     * Executes the current command.
332
     *
333
     * This method is not abstract because you can use this class
334
     * as a concrete class. In this case, instead of defining the
335
     * execute() method, you set the code to execute by passing
336
     * a Closure to the setCode() method.
337
     *
338
     * @param \Symfony\Component\Console\Input\InputInterface   $input  An InputInterface instance
339
     * @param \Symfony\Component\Console\Output\OutputInterface $output An OutputInterface instance
340
     *
341
     * @return null|int null or 0 if everything went fine, or an error code
342
     * @throws \LogicException When this abstract method is not implemented
343
     * @see \Symfony\Component\Console\Command\Command::execute()
344
     */
345
    protected function execute(InputInterface $input, OutputInterface $output)
346
    {
347
348
        // register the JMS Serializer annotations
349
        \Doctrine\Common\Annotations\AnnotationRegistry::registerAutoloadNamespace(
350
            'JMS\Serializer\Annotation',
351
            dirname(__DIR__).'/../vendor/jms/serializer/src'
352
        );
353
354
        // load the specified configuration
355
        $configuration = $this->configurationFactory($input);
356
357
        // initialize the PDO connection
358
        $dsn = $configuration->getDatabase()->getDsn();
359
        $username = $configuration->getDatabase()->getUsername();
360
        $password = $configuration->getDatabase()->getPassword();
361
        $connection = new \PDO($dsn, $username, $password);
362
        $connection->setAttribute(\PDO::ATTR_ERRMODE, \PDO::ERRMODE_EXCEPTION);
363
364
        // initialize the system logger
365
        $systemLogger = new Logger('techdivision/import');
366
        $systemLogger->pushHandler(
367
            new ErrorLogHandler(
368
                ErrorLogHandler::OPERATING_SYSTEM,
369
                $configuration->getLogLevel()
370
            )
371
        );
372
373
        // initialize the registry/import processor
374
        $registryProcessor = RegistryProcessorFactory::factory($connection, $configuration);
375
        $importProcessor = ImportProcessorFactory::factory($connection, $configuration);
376
377
        // initialize the importer
378
        $importer = new Simple(
379
            $systemLogger,
380
            $registryProcessor,
381
            $importProcessor,
382
            $configuration,
383
            $input,
384
            $output
385
        );
386
387
        // start the process
388
        $importer->process();
389
    }
390
}
391