Completed
Push — master ( 2029c7...31b598 )
by Tim
9s
created

Simple::getOutput()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 4
ccs 0
cts 2
cp 0
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 2
1
<?php
2
3
/**
4
 * TechDivision\Import\Cli\Simple
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 Rhumsaa\Uuid\Uuid;
24
use Psr\Log\LogLevel;
25
use Psr\Log\LoggerInterface;
26
use Symfony\Component\Console\Input\InputInterface;
27
use Symfony\Component\Console\Output\OutputInterface;
28
use Symfony\Component\Console\Helper\FormatterHelper;
29
use TechDivision\Import\Utils\MemberNames;
30
use TechDivision\Import\Utils\RegistryKeys;
31
use TechDivision\Import\ConfigurationInterface;
32
use TechDivision\Import\Subjects\SubjectInterface;
33
use TechDivision\Import\Cli\Callbacks\CallbackVisitor;
34
use TechDivision\Import\Cli\Observers\ObserverVisitor;
35
use TechDivision\Import\Services\ImportProcessorInterface;
36
use TechDivision\Import\Services\RegistryProcessorInterface;
37
38
/**
39
 * A SLSB that handles the product import process.
40
 *
41
 * @author    Tim Wagner <[email protected]>
42
 * @copyright 2016 TechDivision GmbH <[email protected]>
43
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
44
 * @link      https://github.com/techdivision/import-cli-simple
45
 * @link      http://www.techdivision.com
46
 */
47
class Simple
48
{
49
50
    /**
51
     * The default style to write messages to the symfony console.
52
     *
53
     * @var string
54
     */
55
    const DEFAULT_STYLE = 'info';
56
57
    /**
58
     * The TechDivision company name as ANSI art.
59
     *
60
     * @var string
61
     */
62
    protected $ansiArt = ' _______        _     _____  _       _     _
63
|__   __|      | |   |  __ \(_)     (_)   (_)
64
   | | ___  ___| |__ | |  | |___   ___ ___ _  ___  _ __
65
   | |/ _ \/ __| \'_ \| |  | | \ \ / / / __| |/ _ \| \'_ \
66
   | |  __/ (__| | | | |__| | |\ V /| \__ \ | (_) | | | |
67
   |_|\___|\___|_| |_|_____/|_| \_/ |_|___/_|\___/|_| |_|
68
';
69
70
    /**
71
     * The log level => console style mapping.
72
     *
73
     * @var array
74
     */
75
    protected $logLevelStyleMapping = array(
76
        LogLevel::INFO      => 'info',
77
        LogLevel::DEBUG     => 'comment',
78
        LogLevel::ERROR     => 'error',
79
        LogLevel::ALERT     => 'error',
80
        LogLevel::CRITICAL  => 'error',
81
        LogLevel::EMERGENCY => 'error',
82
        LogLevel::WARNING   => 'error',
83
        LogLevel::NOTICE    => 'info'
84
    );
85
86
    /**
87
     * The actions unique serial.
88
     *
89
     * @var string
90
     */
91
    protected $serial;
92
93
    /**
94
     * The system logger implementation.
95
     *
96
     * @var \Psr\Log\LoggerInterface
97
     */
98
    protected $systemLogger;
99
100
    /**
101
     * The RegistryProcessor instance to handle running threads.
102
     *
103
     * @var \TechDivision\Import\Services\RegistryProcessorInterface
104
     */
105
    protected $registryProcessor;
106
107
    /**
108
     * The processor to read/write the necessary import data.
109
     *
110
     * @var \TechDivision\Import\Services\ImportProcessorInterface
111
     */
112
    protected $importProcessor;
113
114
    /**
115
     * The system configuration.
116
     *
117
     * @var \TechDivision\Import\ConfigurationInterface
118
     */
119
    protected $configuration;
120
121
    /**
122
     * The input stream to read console information from.
123
     *
124
     * @var \Symfony\Component\Console\Input\InputInterface
125
     */
126
    protected $input;
127
128
    /**
129
     * The output stream to write console information to.
130
     *
131
     * @var \Symfony\Component\Console\Output\OutputInterface
132
     */
133
    protected $output;
134
135
    /**
136
     * Set's the unique serial for this import process.
137
     *
138
     * @param string $serial The unique serial
139
     *
140
     * @return void
141
     */
142
    public function setSerial($serial)
143
    {
144
        $this->serial = $serial;
145
    }
146
147
    /**
148
     * Return's the unique serial for this import process.
149
     *
150
     * @return string The unique serial
151
     */
152
    public function getSerial()
153
    {
154
        return $this->serial;
155
    }
156
157
    /**
158
     * Set's the system logger.
159
     *
160
     * @param \Psr\Log\LoggerInterface $systemLogger The system logger
161
     *
162
     * @return void
163
     */
164
    public function setSystemLogger(LoggerInterface $systemLogger)
165
    {
166
        $this->systemLogger = $systemLogger;
167
    }
168
169
    /**
170
     * Return's the system logger.
171
     *
172
     * @return \Psr\Log\LoggerInterface The system logger instance
173
     */
174
    public function getSystemLogger()
175
    {
176
        return $this->systemLogger;
177
    }
178
179
    /**
180
     * Sets's the RegistryProcessor instance to handle the running threads.
181
     *
182
     * @param \TechDivision\Import\Services\RegistryProcessorInterface $registryProcessor The registry processor instance
183
     *
184
     * @return void
185
     */
186
    public function setRegistryProcessor(RegistryProcessorInterface $registryProcessor)
187
    {
188
        $this->registryProcessor = $registryProcessor;
189
    }
190
191
    /**
192
     * Return's the RegistryProcessor instance to handle the running threads.
193
     *
194
     * @return \TechDivision\Import\Services\RegistryProcessor The registry processor instance
195
     */
196
    public function getRegistryProcessor()
197
    {
198
        return $this->registryProcessor;
199
    }
200
201
    /**
202
     * Set's the import processor instance.
203
     *
204
     * @param \TechDivision\Import\Services\ImportProcessorInterface $importProcessor The import processor instance
205
     *
206
     * @return void
207
     */
208 1
    public function setImportProcessor(ImportProcessorInterface $importProcessor)
209
    {
210 1
        $this->importProcessor = $importProcessor;
211 1
    }
212
213
    /**
214
     * Return's the import processor instance.
215
     *
216
     * @return \TechDivision\Import\Services\ImportProcessorInterface The import processor instance
217
     */
218 1
    public function getImportProcessor()
219
    {
220 1
        return $this->importProcessor;
221
    }
222
223
    /**
224
     * Set's the system configuration.
225
     *
226
     * @param \TechDivision\Import\ConfigurationInterface $configuration The system configuration
227
     *
228
     * @return void
229
     */
230
    public function setConfiguration(ConfigurationInterface $configuration)
231
    {
232
        $this->configuration = $configuration;
233
    }
234
235
    /**
236
     * Return's the system configuration.
237
     *
238
     * @return \TechDivision\Import\ConfigurationInterface The system configuration
239
     */
240
    public function getConfiguration()
241
    {
242
        return $this->configuration;
243
    }
244
245
    /**
246
     * Set's the input stream to read console information from.
247
     *
248
     * @param \Symfony\Component\Console\Input\InputInterface $input An IutputInterface instance
249
     *
250
     * @return void
251
     */
252
    public function setInput(InputInterface $input)
253
    {
254
        $this->input = $input;
255
    }
256
257
    /**
258
     * Return's the input stream to read console information from.
259
     *
260
     * @return \Symfony\Component\Console\Input\InputInterface An IutputInterface instance
261
     */
262
    protected function getInput()
263
    {
264
        return $this->input;
265
    }
266
267
    /**
268
     * Set's the output stream to write console information to.
269
     *
270
     * @param \Symfony\Component\Console\Output\OutputInterface $output An OutputInterface instance
271
     *
272
     * @return void
273
     */
274
    public function setOutput(OutputInterface $output)
275
    {
276
        $this->output = $output;
277
    }
278
279
    /**
280
     * Return's the output stream to write console information to.
281
     *
282
     * @return \Symfony\Component\Console\Output\OutputInterface An OutputInterface instance
283
     */
284
    protected function getOutput()
285
    {
286
        return $this->output;
287
    }
288
289
    /**
290
     * Return's the prefix for the import files.
291
     *
292
     * @return string The prefix
293
     */
294
    protected function getPrefix()
295
    {
296
        return $this->getConfiguration()->getPrefix();
0 ignored issues
show
Bug introduced by
The method getPrefix() does not seem to exist on object<TechDivision\Impo...ConfigurationInterface>.

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...
297
    }
298
299
    /**
300
     * Return's the source directory that has to be watched for new files.
301
     *
302
     * @return string The source directory
303
     */
304
    protected function getSourceDir()
305
    {
306
        return $this->getConfiguration()->getSourceDir();
307
    }
308
309
    /**
310
     * Parse the temporary upload directory for new files to be imported.
311
     *
312
     * @return void
313
     * @throws \Exception Is thrown if the import can't be finished successfully
314
     */
315
    public function import()
316
    {
317
318
        // track the start time
319
        $startTime = microtime(true);
320
321
        try {
322
            // generate the serial for the new job
323
            $this->setSerial(Uuid::uuid4()->__toString());
324
325
            // prepare the global data for the import process
326
            $this->start();
327
            $this->setUp();
328
            $this->processSubjects();
329
            $this->archive();
330
            $this->tearDown();
331
            $this->finish();
332
333
            // track the time needed for the import in seconds
334
            $endTime = microtime(true) - $startTime;
335
336
            // log a message that import has been finished
337
            $this->log(sprintf('Successfully finished import with serial %s in %f s', $this->getSerial(), $endTime), LogLevel::INFO);
338
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
339
        } catch (\Exception $e) {
340
            // tear down
341
            $this->tearDown();
342
            $this->finish();
343
344
            // track the time needed for the import in seconds
345
            $endTime = microtime(true) - $startTime;
346
347
            // log a message that the file import failed
348
            $this->getSystemLogger()->error($e->__toString());
349
350
            // log a message that import has been finished
351
            $this->log(sprintf('Can\'t finish import with serial %s in %f s', $this->getSerial(), $endTime), LogLevel::ERROR);
352
353
            // re-throw the exception
354
            throw $e;
355
        }
356
    }
357
358
    /**
359
     * This method start's the import process by initializing
360
     * the status and appends it to the registry.
361
     *
362
     * @return void
363
     */
364
    protected function start()
365
    {
366
367
        // write the TechDivision ANSI art icon to the console
368
        $this->log($this->ansiArt);
369
370
        // log the debug information, if debug mode is enabled
371
        if ($this->getConfiguration()->isDebugMode()) {
372
            // log the system's PHP configuration
373
            $this->log(sprintf('PHP version: %s', phpversion()), LogLevel::DEBUG);
374
            $this->log('-------------------- Loaded Extensions -----------------------', LogLevel::DEBUG);
375
            $this->log(implode(', ', get_loaded_extensions()), LogLevel::DEBUG);
376
            $this->log('--------------------------------------------------------------', LogLevel::DEBUG);
377
378
            // write a warning for low performance, if XDebug extension is activated
379
            if (in_array('xdebug', $loadedExtensions)) {
0 ignored issues
show
Bug introduced by
The variable $loadedExtensions does not exist. Did you forget to declare it?

This check marks access to variables or properties that have not been declared yet. While PHP has no explicit notion of declaring a variable, accessing it before a value is assigned to it is most likely a bug.

Loading history...
380
                $this->log('Low performance exptected, as result of enabled XDebug extension!', LogLevel::WARNING);
381
            }
382
        }
383
384
        // log a message that import has been started
385
        $this->log(sprintf('Now start import with serial %s', $this->getSerial()), LogLevel::INFO);
386
387
        // initialize the status
388
        $status = array(
389
            RegistryKeys::STATUS => 1,
390
            RegistryKeys::SOURCE_DIRECTORY => $this->getConfiguration()->getSourceDir()
391
        );
392
393
        // initialize the status information for the subjects */
394
        /** @var \TechDivision\Import\Configuration\SubjectInterface $subject */
395
        foreach ($this->getConfiguration()->getSubjects() as $subject) {
396
            $status[$subject->getPrefix()] = array();
397
        }
398
399
        // append it to the registry
400
        $this->getRegistryProcessor()->setAttribute($this->getSerial(), $status);
401
    }
402
403
    /**
404
     * Prepares the global data for the import process.
405
     *
406
     * @return void
407
     */
408
    protected function setUp()
409
    {
410
411
        // load the registry
412
        $importProcessor = $this->getImportProcessor();
413
        $registryProcessor = $this->getRegistryProcessor();
414
415
        // initialize the array for the global data
416
        $globalData = array();
417
418
        // initialize the global data
419
        $globalData[RegistryKeys::STORES] = $importProcessor->getStores();
420
        $globalData[RegistryKeys::LINK_TYPES] = $importProcessor->getLinkTypes();
421
        $globalData[RegistryKeys::TAX_CLASSES] = $importProcessor->getTaxClasses();
422
        $globalData[RegistryKeys::DEFAULT_STORE] = $importProcessor->getDefaultStore();
423
        $globalData[RegistryKeys::STORE_WEBSITES] = $importProcessor->getStoreWebsites();
424
        $globalData[RegistryKeys::LINK_ATTRIBUTES] = $importProcessor->getLinkAttributes();
425
        $globalData[RegistryKeys::ROOT_CATEGORIES] = $importProcessor->getRootCategories();
426
        $globalData[RegistryKeys::CORE_CONFIG_DATA] = $importProcessor->getCoreConfigData();
427
        $globalData[RegistryKeys::ATTRIBUTE_SETS] = $eavAttributeSets = $importProcessor->getEavAttributeSetsByEntityTypeId(4);
428
429
        // prepare the categories
430
        $categories = array();
431
        foreach ($importProcessor->getCategories() as $category) {
432
            // expload the entity IDs from the category path
433
            $entityIds = explode('/', $category[MemberNames::PATH]);
434
435
            // cut-off the root category
436
            array_shift($entityIds);
437
438
            // continue with the next category if no entity IDs are available
439
            if (sizeof($entityIds) === 0) {
440
                continue;
441
            }
442
443
            // initialize the array for the path elements
444
            $path = array();
445
            foreach ($importProcessor->getCategoryVarcharsByEntityIds($entityIds) as $cat) {
446
                $path[] = $cat[MemberNames::VALUE];
447
            }
448
449
            // append the catogory with the string path as key
450
            $categories[implode('/', $path)] = $category;
451
        }
452
453
        // initialize the array with the categories
454
        $globalData[RegistryKeys::CATEGORIES] = $categories;
455
456
        // prepare an array with the EAV attributes grouped by their attribute set name as keys
457
        $eavAttributes = array();
458
        foreach (array_keys($eavAttributeSets) as $eavAttributeSetName) {
459
            $eavAttributes[$eavAttributeSetName] = $importProcessor->getEavAttributesByEntityTypeIdAndAttributeSetName(4, $eavAttributeSetName);
460
        }
461
462
        // initialize the array with the EAV attributes
463
        $globalData[RegistryKeys::EAV_ATTRIBUTES] = $eavAttributes;
464
465
        // add the status with the global data
466
        $registryProcessor->mergeAttributesRecursive(
467
            $this->getSerial(),
468
            array(RegistryKeys::GLOBAL_DATA => $globalData)
469
        );
470
471
        // log a message that the global data has been prepared
472
        $this->log(sprintf('Successfully prepared global data for import with serial %s', $this->getSerial()), LogLevel::INFO);
473
    }
474
475
    /**
476
     * Process all the subjects defined in the system configuration.
477
     *
478
     * @return void
479
     * @throws \Exception Is thrown, if one of the subjects can't be processed
480
     */
481
    protected function processSubjects()
482
    {
483
484
        try {
485
            // load system logger and registry
486
            $importProcessor = $this->getImportProcessor();
487
488
            // load the subjects
489
            $subjects = $this->getConfiguration()->getSubjects();
490
491
            // start the transaction
492
            $importProcessor->getConnection()->beginTransaction();
493
494
            // process all the subjects found in the system configuration
495
            foreach ($subjects as $subject) {
496
                $this->processSubject($subject);
497
            }
498
499
            // commit the transaction
500
            $importProcessor->getConnection()->commit();
501
0 ignored issues
show
Coding Style introduced by
Blank line found at end of control structure
Loading history...
502
        } catch (\Exception $e) {
503
            // rollback the transaction
504
            $importProcessor->getConnection()->rollBack();
505
506
            // re-throw the exception
507
            throw $e;
508
        }
509
    }
510
511
    /**
512
     * Process the subject with the passed name/identifier.
513
     *
514
     * We create a new, fresh and separate subject for EVERY file here, because this would be
515
     * the starting point to parallelize the import process in a multithreaded/multiprocessed
516
     * environment.
517
     *
518
     * @param \TechDivision\Import\Configuration\Subject $subject The subject configuration
519
     *
520
     * @return void
521
     * @throws \Exception Is thrown, if the subject can't be processed
522
     */
523
    protected function processSubject($subject)
524
    {
525
526
        // clear the filecache
527
        clearstatcache();
528
529
        // load the actual status
530
        $status = $this->getRegistryProcessor()->getAttribute($this->getSerial());
531
532
        // query whether or not the configured source directory is available
533 View Code Duplication
        if (!is_dir($sourceDir = $status[RegistryKeys::SOURCE_DIRECTORY])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
534
            throw new \Exception(sprintf('Configured source directory %s is not available!', $sourceDir));
535
        }
536
537
        // initialize the file iterator on source directory
538
        $fileIterator = new \FilesystemIterator($sourceDir);
539
540
        // log a debug message
541
        $this->log(sprintf('Now checking directory %s for files to be imported', $sourceDir), LogLevel::DEBUG);
542
543
        // iterate through all CSV files and process the subjects
544
        foreach ($fileIterator as $filename) {
545
            $this->subjectFactory($subject)->import($this->getSerial(), $filename->getPathname());
546
        }
547
548
        // and and log a message that the subject has been processed
549
        $this->log(sprintf('Successfully processed subject %s!', $subject->getClassName()), LogLevel::DEBUG);
550
    }
551
552
    /**
553
     * Factory method to create new handler instances.
554
     *
555
     * @param \TechDivision\Import\Configuration\Subject $subject The subject configuration
556
     *
557
     * @return object The handler instance
558
     */
559
    public function subjectFactory($subject)
560
    {
561
562
        // load the subject class name
563
        $className = $subject->getClassName();
564
565
        // the database connection to use
566
        $connection = $this->getImportProcessor()->getConnection();
567
568
        // initialize a new handler with the passed class name
569
        $instance = new $className();
570
571
        // $instance the handler instance
572
        $instance->setConfiguration($subject);
573
        $instance->setSystemLogger($this->getSystemLogger());
574
        $instance->setRegistryProcessor($this->getRegistryProcessor());
575
576
        // instanciate and set the product processor, if specified
577
        if ($processorFactory = $subject->getProcessorFactory()) {
578
            $productProcessor = $processorFactory::factory($connection, $subject);
579
            $instance->setProductProcessor($productProcessor);
580
        }
581
582
        // initialize the callbacks/visitors
583
        CallbackVisitor::get()->visit($instance);
584
        ObserverVisitor::get()->visit($instance);
585
586
        // return the subject instance
587
        return $instance;
588
    }
589
590
    /**
591
     * Lifecycle callback that will be inovked after the
592
     * import process has been finished.
593
     *
594
     * @return void
595
     * @throws \Exception Is thrown, if the
596
     */
597
    protected function archive()
598
    {
599
600
        // query whether or not, the import artefacts have to be archived
601
        if (!$this->getConfiguration()->haveArchiveArtefacts()) {
602
            return;
603
        }
604
605
        // clear the filecache
606
        clearstatcache();
607
608
        // load the actual status
609
        $status = $this->getRegistryProcessor()->getAttribute($this->getSerial());
610
611
        // query whether or not the configured source directory is available
612 View Code Duplication
        if (!is_dir($sourceDir = $status[RegistryKeys::SOURCE_DIRECTORY])) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across 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...
613
            throw new \Exception(sprintf('Configured source directory %s is not available!', $sourceDir));
614
        }
615
616
        // init file iterator on source directory
617
        $fileIterator = new \FilesystemIterator($sourceDir);
618
619
        // log the number of files that has to be archived
620
        $fileCounter = iterator_count($fileIterator);
621
622
        // if no files are available, return
623
        if ($fileCounter == 0) {
624
            // log the number of files that has to be archived
625
            $this->log(sprintf('Found no files to archive'), LogLevel::INFO);
626
            return;
627
        }
628
629
        // log the number of files that has to be archived
630
        $this->log(sprintf('Found %d files to archive in directory %s', $fileCounter, $sourceDir), LogLevel::INFO);
631
632
        // initialize the directory to create the archive in
633
        $archiveDir = sprintf('%s/%s', $this->getConfiguration()->getTargetDir(), $this->getConfiguration()->getArchiveDir());
634
635
        // query whether or not the directory already exists
636
        if (!is_dir($archiveDir)) {
637
            mkdir($archiveDir);
638
        }
639
640
        // create the ZIP archive
641
        $archive = new \ZipArchive();
642
        $archive->open($archiveFile = sprintf('%s/%s.zip', $archiveDir, $this->getSerial()), \ZipArchive::CREATE);
643
644
        // iterate through all files and add them to the ZIP archive
645
        foreach ($fileIterator as $filename) {
646
            $archive->addFile($filename);
647
        }
648
649
        // save the ZIP archive
650
        $archive->close();
651
652
        // finally remove the directory with the imported files
653
        $this->removeDir($sourceDir);
654
655
        // and and log a message that the import artefacts have been archived
656
        $this->log(sprintf('Successfully archived imported files to %s!', $archiveFile), LogLevel::INFO);
657
    }
658
659
    /**
660
     * Removes the passed directory recursively.
661
     *
662
     * @param string $src Name of the directory to remove
663
     *
664
     * @return void
665
     */
666
    protected function removeDir($src)
667
    {
668
669
        // open the directory
670
        $dir = opendir($src);
671
672
        // remove files/folders recursively
673
        while (false !== ($file = readdir($dir))) {
674
            if (($file != '.') && ($file != '..')) {
675
                $full = $src . '/' . $file;
676
                if (is_dir($full)) {
677
                    Simple::removeDir($full);
678
                } else {
679
                    unlink($full);
680
                }
681
            }
682
        }
683
684
        // close handle and remove directory itself
685
        closedir($dir);
686
        rmdir($src);
687
    }
688
689
    /**
690
     * Simple method that writes the passed method the the console and the
691
     * system logger, if configured and a log level has been passed.
692
     *
693
     * @param string $msg      The message to log
694
     * @param string $logLevel The log level to use
695
     *
696
     * @return void
697
     */
698
    protected function log($msg, $logLevel = null)
699
    {
700
701
        // initialize the formatter helper
702
        $helper = new FormatterHelper();
703
704
        // map the log level to the console style
705
        $style = $this->mapLogLevelToStyle($logLevel);
706
707
        // format the message, according to the passed log level and write it to the console
708
        $this->getOutput()->writeln($logLevel ? $helper->formatBlock($msg, $style) : $msg);
709
710
        // log the message if a log level has been passed
711
        if ($logLevel && $systemLogger = $this->getSystemLogger()) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $logLevel of type string|null is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
712
            $systemLogger->log($logLevel, $msg);
713
        }
714
    }
715
716
    /**
717
     * Map's the passed log level to a valid symfony console style.
718
     *
719
     * @param string $logLevel The log level to map
720
     *
721
     * @return string The apropriate symfony console style
722
     */
723
    protected function mapLogLevelToStyle($logLevel)
724
    {
725
726
        // query whether or not the log level is mapped
727
        if (isset($this->logLevelStyleMapping[$logLevel])) {
728
            return $this->logLevelStyleMapping[$logLevel];
729
        }
730
731
        // return the default style => info
732
        return Simple::DEFAULT_STYLE;
733
    }
734
735
    /**
736
     * Lifecycle callback that will be inovked after the
737
     * import process has been finished.
738
     *
739
     * @return void
740
     * @throws \Exception Is thrown, if the
741
     */
742
    protected function tearDown()
743
    {
744
    }
745
746
    /**
747
     * This method finishes the import process and cleans the registry.
748
     *
749
     * @return void
750
     */
751
    protected function finish()
752
    {
753
        $this->getRegistryProcessor()->removeAttribute($this->getSerial());
754
    }
755
}
756