Completed
Push — master ( 7ad7bf...051c2a )
by Tim
12s
created

Simple   C

Complexity

Total Complexity 58

Size/Duplication

Total Lines 743
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 10

Importance

Changes 0
Metric Value
wmc 58
lcom 1
cbo 10
dl 0
loc 743
rs 5
c 0
b 0
f 0

29 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 20 1
A setContainer() 0 4 1
A getContainer() 0 4 1
A setOutput() 0 4 1
A getOutput() 0 4 1
A setConfiguration() 0 4 1
A getConfiguration() 0 4 1
A setRegistryProcessor() 0 4 1
A getRegistryProcessor() 0 4 1
A setImportProcessor() 0 4 1
A getImportProcessor() 0 4 1
A setSystemLoggers() 0 4 1
A getSystemLogger() 0 16 2
A hasSystemLogger() 0 4 1
A getSystemLoggers() 0 4 1
A getSerial() 0 4 1
A shutdown() 0 19 4
B lock() 0 24 4
C unlock() 0 26 7
B removeLineFromFile() 0 42 6
B process() 0 103 6
A stop() 0 9 1
A isStopped() 0 4 1
A pluginFactory() 0 5 1
A setUp() 0 48 3
A tearDown() 0 4 1
A log() 0 17 4
A mapLogLevelToStyle() 0 11 2
A getPidFilename() 0 4 1

How to fix   Complexity   

Complex Class

Complex classes like Simple often do a lot of different things. To break such a class down, we need to identify a cohesive component within that class. A common approach to find such a component is to look for fields/methods that share the same prefixes, or suffixes. You can also have a look at the cohesion graph to spot any un-connected, or weakly-connected components.

Once you have determined the fields that belong together, you can apply the Extract Class refactoring. If the component makes sense as a sub-class, Extract Subclass is also a candidate, and is often faster.

While breaking up the class, it is a good idea to analyze how other classes use Simple, and based on these observations, apply Extract Interface, too.

1
<?php
2
3
/**
4
 * TechDivision\Import\App\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-app-simple
18
 * @link      http://www.techdivision.com
19
 */
20
21
namespace TechDivision\Import\App;
22
23
use Rhumsaa\Uuid\Uuid;
24
use Monolog\Logger;
25
use Psr\Log\LogLevel;
26
use Symfony\Component\Console\Output\OutputInterface;
27
use Symfony\Component\Console\Helper\FormatterHelper;
28
use Symfony\Component\DependencyInjection\TaggedContainerInterface;
29
use TechDivision\Import\Utils\LoggerKeys;
30
use TechDivision\Import\Utils\RegistryKeys;
31
use TechDivision\Import\App\Utils\SynteticServiceKeys;
32
use TechDivision\Import\ApplicationInterface;
33
use TechDivision\Import\ConfigurationInterface;
34
use TechDivision\Import\Exceptions\LineNotFoundException;
35
use TechDivision\Import\Exceptions\FileNotFoundException;
36
use TechDivision\Import\Exceptions\ImportAlreadyRunningException;
37
use TechDivision\Import\Configuration\PluginConfigurationInterface;
38
use TechDivision\Import\Services\ImportProcessorInterface;
39
use TechDivision\Import\Services\RegistryProcessorInterface;
40
41
/**
42
 * The M2IF - Simple Application implementation.
43
 *
44
 * This is a example application implementation that should give developers an impression
45
 * on how the M2IF could be used to implement their own Magento 2 importer.
46
 *
47
 * @author    Tim Wagner <[email protected]>
48
 * @copyright 2016 TechDivision GmbH <[email protected]>
49
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
50
 * @link      https://github.com/techdivision/import-app-simple
51
 * @link      http://www.techdivision.com
52
 */
53
class Simple implements ApplicationInterface
54
{
55
56
    /**
57
     * The default style to write messages to the symfony console.
58
     *
59
     * @var string
60
     */
61
    const DEFAULT_STYLE = 'info';
62
63
    /**
64
     * The TechDivision company name as ANSI art.
65
     *
66
     * @var string
67
     */
68
    protected $ansiArt = ' _______        _     _____  _       _     _
69
|__   __|      | |   |  __ \(_)     (_)   (_)
70
   | | ___  ___| |__ | |  | |___   ___ ___ _  ___  _ __
71
   | |/ _ \/ __| \'_ \| |  | | \ \ / / / __| |/ _ \| \'_ \
72
   | |  __/ (__| | | | |__| | |\ V /| \__ \ | (_) | | | |
73
   |_|\___|\___|_| |_|_____/|_| \_/ |_|___/_|\___/|_| |_|
74
';
75
76
    /**
77
     * The log level => console style mapping.
78
     *
79
     * @var array
80
     */
81
    protected $logLevelStyleMapping = array(
82
        LogLevel::INFO      => 'info',
83
        LogLevel::DEBUG     => 'comment',
84
        LogLevel::ERROR     => 'error',
85
        LogLevel::ALERT     => 'error',
86
        LogLevel::CRITICAL  => 'error',
87
        LogLevel::EMERGENCY => 'error',
88
        LogLevel::WARNING   => 'error',
89
        LogLevel::NOTICE    => 'info'
90
    );
91
92
    /**
93
     * The PID for the running processes.
94
     *
95
     * @var array
96
     */
97
    protected $pid;
98
99
    /**
100
     * The actions unique serial.
101
     *
102
     * @var string
103
     */
104
    protected $serial;
105
106
    /**
107
     * The array with the system logger instances.
108
     *
109
     * @var array
110
     */
111
    protected $systemLoggers;
112
113
    /**
114
     * The RegistryProcessor instance to handle running threads.
115
     *
116
     * @var \TechDivision\Import\Services\RegistryProcessorInterface
117
     */
118
    protected $registryProcessor;
119
120
    /**
121
     * The processor to read/write the necessary import data.
122
     *
123
     * @var \TechDivision\Import\Services\ImportProcessorInterface
124
     */
125
    protected $importProcessor;
126
127
    /**
128
     * The DI container builder instance.
129
     *
130
     * @var \Symfony\Component\DependencyInjection\TaggedContainerInterface
131
     */
132
    protected $container;
133
134
    /**
135
     * The system configuration.
136
     *
137
     * @var \TechDivision\Import\ConfigurationInterface
138
     */
139
    protected $configuration;
140
141
    /**
142
     * The output stream to write console information to.
143
     *
144
     * @var \Symfony\Component\Console\Output\OutputInterface
145
     */
146
    protected $output;
147
148
    /**
149
     * The plugins to be processed.
150
     *
151
     * @var array
152
     */
153
    protected $plugins = array();
154
155
    /**
156
     * The flag that stop's processing the operation.
157
     *
158
     * @var boolean
159
     */
160
    protected $stopped = false;
161
162
    /**
163
     * The filehandle for the PID file.
164
     *
165
     * @var resource
166
     */
167
    protected $fh;
168
169
    /**
170
     * The constructor to initialize the instance.
171
     *
172
     * @param \Symfony\Component\DependencyInjection\TaggedContainerInterface $container         The DI container instance
173
     * @param \TechDivision\Import\Services\RegistryProcessorInterface        $registryProcessor The registry processor instance
174
     * @param \TechDivision\Import\Services\ImportProcessorInterface          $importProcessor   The import processor instance
175
     * @param \TechDivision\Import\ConfigurationInterface                     $configuration     The system configuration
176
     * @param \Symfony\Component\Console\Output\OutputInterface               $output            An OutputInterface instance
177
     * @param array                                                           $systemLoggers     The array with the system logger instances
178
     */
179
    public function __construct(
180
        TaggedContainerInterface $container,
181
        RegistryProcessorInterface $registryProcessor,
182
        ImportProcessorInterface $importProcessor,
183
        ConfigurationInterface $configuration,
184
        OutputInterface $output,
185
        array $systemLoggers
186
    ) {
187
188
        // register the shutdown function
189
        register_shutdown_function(array($this, 'shutdown'));
190
191
        // initialize the instance with the passed values
192
        $this->setOutput($output);
193
        $this->setContainer($container);
194
        $this->setConfiguration($configuration);
195
        $this->setSystemLoggers($systemLoggers);
196
        $this->setImportProcessor($importProcessor);
197
        $this->setRegistryProcessor($registryProcessor);
198
    }
199
200
    /**
201
     * Set's the container instance.
202
     *
203
     * @param \Symfony\Component\DependencyInjection\TaggedContainerInterface $container The container instance
204
     *
205
     * @return void
206
     */
207
    public function setContainer(TaggedContainerInterface $container)
208
    {
209
        $this->container = $container;
210
    }
211
212
    /**
213
     * Return's the container instance.
214
     *
215
     * @return \Symfony\Component\DependencyInjection\TaggedContainerInterface The container instance
216
     */
217
    public function getContainer()
218
    {
219
        return $this->container;
220
    }
221
222
    /**
223
     * Set's the output stream to write console information to.
224
     *
225
     * @param \Symfony\Component\Console\Output\OutputInterface $output The output stream
226
     *
227
     * @return void
228
     */
229
    public function setOutput(OutputInterface $output)
230
    {
231
        $this->output = $output;
232
    }
233
234
    /**
235
     * Return's the output stream to write console information to.
236
     *
237
     * @return \Symfony\Component\Console\Output\OutputInterface The output stream
238
     */
239
    public function getOutput()
240
    {
241
        return $this->output;
242
    }
243
244
    /**
245
     * Set's the system configuration.
246
     *
247
     * @param \TechDivision\Import\ConfigurationInterface $configuration The system configuration
248
     *
249
     * @return void
250
     */
251
    public function setConfiguration(ConfigurationInterface $configuration)
252
    {
253
        $this->configuration = $configuration;
254
    }
255
256
    /**
257
     * Return's the system configuration.
258
     *
259
     * @return \TechDivision\Import\ConfigurationInterface The system configuration
260
     */
261
    public function getConfiguration()
262
    {
263
        return $this->configuration;
264
    }
265
266
    /**
267
     * Set's the RegistryProcessor instance to handle the running threads.
268
     *
269
     * @param \TechDivision\Import\Services\RegistryProcessor $registryProcessor The registry processor instance
270
     *
271
     * @return void
272
     */
273
    public function setRegistryProcessor(RegistryProcessorInterface $registryProcessor)
274
    {
275
        $this->registryProcessor = $registryProcessor;
276
    }
277
278
    /**
279
     * Return's the RegistryProcessor instance to handle the running threads.
280
     *
281
     * @return \TechDivision\Import\Services\RegistryProcessor The registry processor instance
282
     */
283
    public function getRegistryProcessor()
284
    {
285
        return $this->registryProcessor;
286
    }
287
288
    /**
289
     * Set's the import processor instance.
290
     *
291
     * @param \TechDivision\Import\Services\ImportProcessorInterface $importProcessor The import processor instance
292
     *
293
     * @return void
294
     */
295
    public function setImportProcessor(ImportProcessorInterface $importProcessor)
296
    {
297
        $this->importProcessor = $importProcessor;
298
    }
299
300
    /**
301
     * Return's the import processor instance.
302
     *
303
     * @return \TechDivision\Import\Services\ImportProcessorInterface The import processor instance
304
     */
305
    public function getImportProcessor()
306
    {
307
        return $this->importProcessor;
308
    }
309
310
    /**
311
     * The array with the system loggers.
312
     *
313
     * @param array $systemLoggers The system logger instances
314
     *
315
     * @return void
316
     */
317
    public function setSystemLoggers(array $systemLoggers)
318
    {
319
        $this->systemLoggers = $systemLoggers;
320
    }
321
322
    /**
323
     * Return's the logger with the passed name, by default the system logger.
324
     *
325
     * @param string $name The name of the requested system logger
326
     *
327
     * @return \Psr\Log\LoggerInterface The logger instance
328
     * @throws \Exception Is thrown, if the requested logger is NOT available
329
     */
330
    public function getSystemLogger($name = LoggerKeys::SYSTEM)
331
    {
332
333
        // query whether or not, the requested logger is available
334
        if (isset($this->systemLoggers[$name])) {
335
            return $this->systemLoggers[$name];
336
        }
337
338
        // throw an exception if the requested logger is NOT available
339
        throw new \Exception(
340
            sprintf(
341
                'The requested logger \'%s\' is not available',
342
                $name
343
            )
344
        );
345
    }
346
347
    /**
348
     * Query whether or not the system logger with the passed name is available.
349
     *
350
     * @param string $name The name of the requested system logger
351
     *
352
     * @return boolean TRUE if the logger with the passed name exists, else FALSE
353
     */
354
    public function hasSystemLogger($name = LoggerKeys::SYSTEM)
355
    {
356
        return isset($this->systemLoggers[$name]);
357
    }
358
359
    /**
360
     * Return's the array with the system logger instances.
361
     *
362
     * @return array The logger instance
363
     */
364
    public function getSystemLoggers()
365
    {
366
        return $this->systemLoggers;
367
    }
368
369
    /**
370
     * Return's the unique serial for this import process.
371
     *
372
     * @return string The unique serial
373
     */
374
    public function getSerial()
375
    {
376
        return $this->serial;
377
    }
378
379
    /**
380
     * The shutdown handler to catch fatal errors.
381
     *
382
     * This method is need to make sure, that an existing PID file will be removed
383
     * if a fatal error has been triggered.
384
     *
385
     * @return void
386
     */
387
    public function shutdown()
388
    {
389
390
        // check if there was a fatal error caused shutdown
391
        if ($lastError = error_get_last()) {
392
            // initialize error type and message
393
            $type = 0;
394
            $message = '';
395
            // extract the last error values
396
            extract($lastError);
397
            // query whether we've a fatal/user error
398
            if ($type === E_ERROR || $type === E_USER_ERROR) {
399
                // clean-up the PID file
400
                $this->unlock();
401
                // log the fatal error message
402
                $this->log($message, LogLevel::ERROR);
403
            }
404
        }
405
    }
406
407
    /**
408
     * Persist the UUID of the actual import process to the PID file.
409
     *
410
     * @return void
411
     * @throws \Exception Is thrown, if the PID can not be locked or the PID can not be added
412
     * @throws \TechDivision\Import\Exceptions\ImportAlreadyRunningException Is thrown, if a import process is already running
413
     */
414
    public function lock()
415
    {
416
417
        // query whether or not, the PID has already been set
418
        if ($this->pid === $this->getSerial()) {
419
            return;
420
        }
421
422
        // if not, initialize the PID
423
        $this->pid = $this->getSerial();
0 ignored issues
show
Documentation Bug introduced by
It seems like $this->getSerial() of type string is incompatible with the declared type array of property $pid.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
424
425
        // open the PID file
426
        $this->fh = fopen($filename = $this->getPidFilename(), 'a+');
427
428
        // try to lock the PID file exclusive
429
        if (!flock($this->fh, LOCK_EX|LOCK_NB)) {
430
            throw new ImportAlreadyRunningException(sprintf('PID file %s is already in use', $filename));
431
        }
432
433
        // append the PID to the PID file
434
        if (fwrite($this->fh, $this->pid . PHP_EOL) === false) {
435
            throw new \Exception(sprintf('Can\'t write PID %s to PID file %s', $this->pid, $filename));
436
        }
437
    }
438
439
    /**
440
     * Remove's the UUID of the actual import process from the PID file.
441
     *
442
     * @return void
443
     * @throws \Exception Is thrown, if the PID can not be removed
444
     */
445
    public function unlock()
446
    {
447
        try {
448
            // remove the PID from the PID file if set
449
            if ($this->pid === $this->getSerial() && is_resource($this->fh)) {
450
                // remove the PID from the file
451
                $this->removeLineFromFile($this->pid, $this->fh);
452
453
                // finally unlock/close the PID file
454
                flock($this->fh, LOCK_UN);
455
                fclose($this->fh);
456
457
                // if the PID file is empty, delete the file
458
                if (filesize($filename = $this->getPidFilename()) === 0) {
459
                    unlink($filename);
460
                }
461
            }
462
463
        } catch (FileNotFoundException $fnfe) {
464
            $this->getSystemLogger()->notice(sprintf('PID file %s doesn\'t exist', $this->getPidFilename()));
465
        } catch (LineNotFoundException $lnfe) {
466
            $this->getSystemLogger()->notice(sprintf('PID %s is can not be found in PID file %s', $this->pid, $this->getPidFilename()));
467
        } catch (\Exception $e) {
468
            throw new \Exception(sprintf('Can\'t remove PID %s from PID file %s', $this->pid, $this->getPidFilename()), null, $e);
469
        }
470
    }
471
472
    /**
473
     * Remove's the passed line from the file with the passed name.
474
     *
475
     * @param string   $line The line to be removed
476
     * @param resource $fh   The file handle of the file the line has to be removed
477
     *
478
     * @return void
479
     * @throws \Exception Is thrown, if the file doesn't exists, the line is not found or can not be removed
480
     */
481
    public function removeLineFromFile($line, $fh)
482
    {
483
484
        // initialize the array for the PIDs found in the PID file
485
        $lines = array();
486
487
        // initialize the flag if the line has been found
488
        $found = false;
489
490
        // rewind the file pointer
491
        rewind($fh);
492
493
        // read the lines with the PIDs from the PID file
494
        while (($buffer = fgets($fh, 4096)) !== false) {
495
            // remove the new line
496
            $buffer = trim($buffer);
497
            // if the line is the one to be removed, ignore the line
498
            if ($line === $buffer) {
499
                $found = true;
500
                continue;
501
            }
502
503
            // add the found PID to the array
504
            $lines[] = $buffer;
505
        }
506
507
        // query whether or not, we found the line
508
        if (!$found) {
509
            throw new LineNotFoundException(sprintf('Line %s can not be found', $line));
510
        }
511
512
        // empty the file and rewind the file pointer
513
        ftruncate($fh, 0);
514
        rewind($fh);
515
516
        // append the existing lines to the file
517
        foreach ($lines as $ln) {
518
            if (fwrite($fh, $ln . PHP_EOL) === false) {
519
                throw new \Exception(sprintf('Can\'t write %s to file', $ln));
520
            }
521
        }
522
    }
523
524
    /**
525
     * Process the given operation.
526
     *
527
     * @return void
528
     * @throws \Exception Is thrown if the operation can't be finished successfully
529
     */
530
    public function process()
531
    {
532
533
        try {
534
            // track the start time
535
            $startTime = microtime(true);
536
537
            // start the transaction
538
            $this->getImportProcessor()->getConnection()->beginTransaction();
539
540
            // prepare the global data for the import process
541
            $this->setUp();
542
543
            // process the plugins defined in the configuration
544
            foreach ($this->getConfiguration()->getPlugins() as $pluginConfiguration) {
545
                // query whether or not the operation has been stopped
546
                if ($this->isStopped()) {
547
                    break;
548
                }
549
                // process the plugin if not
550
                $this->pluginFactory($pluginConfiguration)->process();
551
            }
552
553
            // tear down the  instance
554
            $this->tearDown();
555
556
            // commit the transaction
557
            $this->getImportProcessor()->getConnection()->commit();
558
559
            // track the time needed for the import in seconds
560
            $endTime = microtime(true) - $startTime;
561
562
            // log a message that import has been finished
563
            $this->log(
564
                sprintf(
565
                    'Successfully finished import with serial %s in %f s',
566
                    $this->getSerial(),
567
                    $endTime
568
                ),
569
                LogLevel::INFO
570
            );
571
572
        } catch (ImportAlreadyRunningException $iare) {
573
            // tear down
574
            $this->tearDown();
575
576
            // rollback the transaction
577
            $this->getImportProcessor()->getConnection()->rollBack();
578
579
            // finally, if a PID has been set (because CSV files has been found),
580
            // remove it from the PID file to unlock the importer
581
            $this->unlock();
582
583
            // track the time needed for the import in seconds
584
            $endTime = microtime(true) - $startTime;
585
586
            // log a warning, because another import process is already running
587
            $this->getSystemLogger()->warning($iare->__toString());
588
589
            // log a message that import has been finished
590
            $this->getSystemLogger()->info(
591
                sprintf(
592
                    'Can\'t finish import with serial because another import process is running %s in %f s',
593
                    $this->getSerial(),
594
                    $endTime
595
                )
596
            );
597
598
            // re-throw the exception
599
            throw $iare;
600
601
        } catch (\Exception $e) {
602
            // tear down
603
            $this->tearDown();
604
605
            // rollback the transaction
606
            $this->getImportProcessor()->getConnection()->rollBack();
607
608
            // finally, if a PID has been set (because CSV files has been found),
609
            // remove it from the PID file to unlock the importer
610
            $this->unlock();
611
612
            // track the time needed for the import in seconds
613
            $endTime = microtime(true) - $startTime;
614
615
            // log a message that the file import failed
616
            foreach ($this->systemLoggers as $systemLogger) {
617
                $systemLogger->error($e->__toString());
618
            }
619
620
            // log a message that import has been finished
621
            $this->getSystemLogger()->info(
622
                sprintf(
623
                    'Can\'t finish import with serial %s in %f s',
624
                    $this->getSerial(),
625
                    $endTime
626
                )
627
            );
628
629
            // re-throw the exception
630
            throw $e;
631
        }
632
    }
633
634
    /**
635
     * Stop processing the operation.
636
     *
637
     * @param string $reason The reason why the operation has been stopped
638
     *
639
     * @return void
640
     */
641
    public function stop($reason)
642
    {
643
644
        // log a message that the operation has been stopped
645
        $this->log($reason, LogLevel::INFO);
646
647
        // stop processing the plugins by setting the flag to TRUE
648
        $this->stopped = true;
649
    }
650
651
    /**
652
     * Return's TRUE if the operation has been stopped, else FALSE.
653
     *
654
     * @return boolean TRUE if the process has been stopped, else FALSE
655
     */
656
    public function isStopped()
657
    {
658
        return $this->stopped;
659
    }
660
661
    /**
662
     * Factory method to create new plugin instances.
663
     *
664
     * @param \TechDivision\Import\Configuration\PluginConfigurationInterface $pluginConfiguration The plugin configuration instance
665
     *
666
     * @return object The plugin instance
667
     */
668
    protected function pluginFactory(PluginConfigurationInterface $pluginConfiguration)
669
    {
670
        $this->getContainer()->set(sprintf('configuration.%s', $id = $pluginConfiguration->getId()), $pluginConfiguration);
0 ignored issues
show
Bug introduced by
The method getId() 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...
671
        return $this->getContainer()->get($id);
672
    }
673
674
    /**
675
     * Lifecycle callback that will be inovked before the
676
     * import process has been started.
677
     *
678
     * @return void
679
     */
680
    protected function setUp()
681
    {
682
683
        // generate the serial for the new job
684
        $this->serial = Uuid::uuid4()->__toString();
685
686
        // write the TechDivision ANSI art icon to the console
687
        $this->log($this->ansiArt);
688
689
        // log the debug information, if debug mode is enabled
690
        if ($this->getConfiguration()->isDebugMode()) {
691
            // load the application from the DI container
692
            /** @var TechDivision\Import\App\Application $application */
693
            $application = $this->getContainer()->get(SynteticServiceKeys::APPLICATION);
694
            // log the system's PHP configuration
695
            $this->log(sprintf('PHP version: %s', phpversion()), LogLevel::DEBUG);
696
            $this->log(sprintf('App version: %s', $application->getVersion()), LogLevel::DEBUG);
697
            $this->log('-------------------- Loaded Extensions -----------------------', LogLevel::DEBUG);
698
            $this->log(implode(', ', $loadedExtensions = get_loaded_extensions()), LogLevel::DEBUG);
699
            $this->log('--------------------------------------------------------------', LogLevel::DEBUG);
700
701
            // write a warning for low performance, if XDebug extension is activated
702
            if (in_array('xdebug', $loadedExtensions)) {
703
                $this->log('Low performance exptected, as result of enabled XDebug extension!', LogLevel::WARNING);
704
            }
705
        }
706
707
        // log a message that import has been started
708
        $this->log(
709
            sprintf(
710
                'Now start import with serial %s (operation: %s)',
711
                $this->getSerial(),
712
                $this->getConfiguration()->getOperationName()
713
            ),
714
            LogLevel::INFO
715
        );
716
717
        // initialize the status
718
        $status = array(
719
            RegistryKeys::STATUS => 1,
720
            RegistryKeys::BUNCHES => 0,
721
            RegistryKeys::SOURCE_DIRECTORY => $this->getConfiguration()->getSourceDir(),
722
            RegistryKeys::MISSING_OPTION_VALUES => array()
723
        );
724
725
        // append it to the registry
726
        $this->getRegistryProcessor()->setAttribute($this->getSerial(), $status);
727
    }
728
729
    /**
730
     * Lifecycle callback that will be inovked after the
731
     * import process has been finished.
732
     *
733
     * @return void
734
     */
735
    protected function tearDown()
736
    {
737
        $this->getRegistryProcessor()->removeAttribute($this->getSerial());
738
    }
739
740
    /**
741
     * Simple method that writes the passed method the the console and the
742
     * system logger, if configured and a log level has been passed.
743
     *
744
     * @param string $msg      The message to log
745
     * @param string $logLevel The log level to use
746
     *
747
     * @return void
748
     */
749
    protected function log($msg, $logLevel = null)
750
    {
751
752
        // initialize the formatter helper
753
        $helper = new FormatterHelper();
754
755
        // map the log level to the console style
756
        $style = $this->mapLogLevelToStyle($logLevel);
757
758
        // format the message, according to the passed log level and write it to the console
759
        $this->getOutput()->writeln($logLevel ? $helper->formatBlock($msg, $style) : $msg);
760
761
        // log the message if a log level has been passed
762
        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...
763
            $systemLogger->log($logLevel, $msg);
764
        }
765
    }
766
767
    /**
768
     * Map's the passed log level to a valid symfony console style.
769
     *
770
     * @param string $logLevel The log level to map
771
     *
772
     * @return string The apropriate symfony console style
773
     */
774
    protected function mapLogLevelToStyle($logLevel)
775
    {
776
777
        // query whether or not the log level is mapped
778
        if (isset($this->logLevelStyleMapping[$logLevel])) {
779
            return $this->logLevelStyleMapping[$logLevel];
780
        }
781
782
        // return the default style => info
783
        return Simple::DEFAULT_STYLE;
784
    }
785
786
    /**
787
     * Return's the PID filename to use.
788
     *
789
     * @return string The PID filename
790
     */
791
    protected function getPidFilename()
792
    {
793
        return $this->getConfiguration()->getPidFilename();
794
    }
795
}
796