Completed
Push — master ( 0b7838...a62ab3 )
by Tim
11s
created

Simple::getPluginFactory()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 4
rs 10
c 0
b 0
f 0
cc 1
eloc 2
nc 1
nop 0
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\DependencyInjectionKeys;
32
use TechDivision\Import\ApplicationInterface;
33
use TechDivision\Import\ConfigurationInterface;
34
use TechDivision\Import\Plugins\PluginFactoryInterface;
35
use TechDivision\Import\Exceptions\LineNotFoundException;
36
use TechDivision\Import\Exceptions\FileNotFoundException;
37
use TechDivision\Import\Exceptions\ImportAlreadyRunningException;
38
use TechDivision\Import\Configuration\PluginConfigurationInterface;
39
use TechDivision\Import\Services\ImportProcessorInterface;
40
use TechDivision\Import\Services\RegistryProcessorInterface;
41
42
/**
43
 * The M2IF - Simple Application implementation.
44
 *
45
 * This is a example application implementation that should give developers an impression
46
 * on how the M2IF could be used to implement their own Magento 2 importer.
47
 *
48
 * @author    Tim Wagner <[email protected]>
49
 * @copyright 2016 TechDivision GmbH <[email protected]>
50
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
51
 * @link      https://github.com/techdivision/import-app-simple
52
 * @link      http://www.techdivision.com
53
 */
54
class Simple implements ApplicationInterface
55
{
56
57
    /**
58
     * The default style to write messages to the symfony console.
59
     *
60
     * @var string
61
     */
62
    const DEFAULT_STYLE = 'info';
63
64
    /**
65
     * The TechDivision company name as ANSI art.
66
     *
67
     * @var string
68
     */
69
    protected $ansiArt = ' _______        _     _____  _       _     _
70
|__   __|      | |   |  __ \(_)     (_)   (_)
71
   | | ___  ___| |__ | |  | |___   ___ ___ _  ___  _ __
72
   | |/ _ \/ __| \'_ \| |  | | \ \ / / / __| |/ _ \| \'_ \
73
   | |  __/ (__| | | | |__| | |\ V /| \__ \ | (_) | | | |
74
   |_|\___|\___|_| |_|_____/|_| \_/ |_|___/_|\___/|_| |_|
75
';
76
77
    /**
78
     * The log level => console style mapping.
79
     *
80
     * @var array
81
     */
82
    protected $logLevelStyleMapping = array(
83
        LogLevel::INFO      => 'info',
84
        LogLevel::DEBUG     => 'comment',
85
        LogLevel::ERROR     => 'error',
86
        LogLevel::ALERT     => 'error',
87
        LogLevel::CRITICAL  => 'error',
88
        LogLevel::EMERGENCY => 'error',
89
        LogLevel::WARNING   => 'error',
90
        LogLevel::NOTICE    => 'info'
91
    );
92
93
    /**
94
     * The PID for the running processes.
95
     *
96
     * @var array
97
     */
98
    protected $pid;
99
100
    /**
101
     * The actions unique serial.
102
     *
103
     * @var string
104
     */
105
    protected $serial;
106
107
    /**
108
     * The array with the system logger instances.
109
     *
110
     * @var array
111
     */
112
    protected $systemLoggers;
113
114
    /**
115
     * The RegistryProcessor instance to handle running threads.
116
     *
117
     * @var \TechDivision\Import\Services\RegistryProcessorInterface
118
     */
119
    protected $registryProcessor;
120
121
    /**
122
     * The processor to read/write the necessary import data.
123
     *
124
     * @var \TechDivision\Import\Services\ImportProcessorInterface
125
     */
126
    protected $importProcessor;
127
128
    /**
129
     * The DI container builder instance.
130
     *
131
     * @var \Symfony\Component\DependencyInjection\TaggedContainerInterface
132
     */
133
    protected $container;
134
135
    /**
136
     * The system configuration.
137
     *
138
     * @var \TechDivision\Import\ConfigurationInterface
139
     */
140
    protected $configuration;
141
142
    /**
143
     * The output stream to write console information to.
144
     *
145
     * @var \Symfony\Component\Console\Output\OutputInterface
146
     */
147
    protected $output;
148
149
    /**
150
     * The plugins to be processed.
151
     *
152
     * @var array
153
     */
154
    protected $plugins = array();
155
156
    /**
157
     * The flag that stop's processing the operation.
158
     *
159
     * @var boolean
160
     */
161
    protected $stopped = false;
162
163
    /**
164
     * The filehandle for the PID file.
165
     *
166
     * @var resource
167
     */
168
    protected $fh;
169
170
    /**
171
     * The plugin factory instance.
172
     *
173
     * @var \TechDivision\Import\Plugins\PluginFactoryInterface
174
     */
175
    protected $pluginFactory;
176
177
    /**
178
     * The constructor to initialize the instance.
179
     *
180
     * @param \Symfony\Component\DependencyInjection\TaggedContainerInterface $container         The DI container instance
181
     * @param \TechDivision\Import\Services\RegistryProcessorInterface        $registryProcessor The registry processor instance
182
     * @param \TechDivision\Import\Services\ImportProcessorInterface          $importProcessor   The import processor instance
183
     * @param \TechDivision\Import\ConfigurationInterface                     $configuration     The system configuration
184
     * @param \TechDivision\Import\Plugins\PluginFactoryInterface             $pluginFactory     The plugin factory instance
185
     * @param \Symfony\Component\Console\Output\OutputInterface               $output            The output instance
186
     * @param array                                                           $systemLoggers     The array with the system logger instances
187
     */
188
    public function __construct(
189
        TaggedContainerInterface $container,
190
        RegistryProcessorInterface $registryProcessor,
191
        ImportProcessorInterface $importProcessor,
192
        ConfigurationInterface $configuration,
193
        PluginFactoryInterface $pluginFactory,
194
        OutputInterface $output,
195
        array $systemLoggers
196
    ) {
197
198
        // register the shutdown function
199
        register_shutdown_function(array($this, 'shutdown'));
200
201
        // initialize the instance with the passed values
202
        $this->setOutput($output);
203
        $this->setContainer($container);
204
        $this->setConfiguration($configuration);
205
        $this->setSystemLoggers($systemLoggers);
206
        $this->setPluginFactory($pluginFactory);
207
        $this->setImportProcessor($importProcessor);
208
        $this->setRegistryProcessor($registryProcessor);
209
    }
210
211
    /**
212
     * Set's the container instance.
213
     *
214
     * @param \Symfony\Component\DependencyInjection\TaggedContainerInterface $container The container instance
215
     *
216
     * @return void
217
     */
218
    public function setContainer(TaggedContainerInterface $container)
219
    {
220
        $this->container = $container;
221
    }
222
223
    /**
224
     * Return's the container instance.
225
     *
226
     * @return \Symfony\Component\DependencyInjection\TaggedContainerInterface The container instance
227
     */
228
    public function getContainer()
229
    {
230
        return $this->container;
231
    }
232
233
    /**
234
     * Set's the output stream to write console information to.
235
     *
236
     * @param \Symfony\Component\Console\Output\OutputInterface $output The output stream
237
     *
238
     * @return void
239
     */
240
    public function setOutput(OutputInterface $output)
241
    {
242
        $this->output = $output;
243
    }
244
245
    /**
246
     * Return's the output stream to write console information to.
247
     *
248
     * @return \Symfony\Component\Console\Output\OutputInterface The output stream
249
     */
250
    public function getOutput()
251
    {
252
        return $this->output;
253
    }
254
255
    /**
256
     * Set's the system configuration.
257
     *
258
     * @param \TechDivision\Import\ConfigurationInterface $configuration The system configuration
259
     *
260
     * @return void
261
     */
262
    public function setConfiguration(ConfigurationInterface $configuration)
263
    {
264
        $this->configuration = $configuration;
265
    }
266
267
    /**
268
     * Return's the system configuration.
269
     *
270
     * @return \TechDivision\Import\ConfigurationInterface The system configuration
271
     */
272
    public function getConfiguration()
273
    {
274
        return $this->configuration;
275
    }
276
277
    /**
278
     * Set's the RegistryProcessor instance to handle the running threads.
279
     *
280
     * @param \TechDivision\Import\Services\RegistryProcessor $registryProcessor The registry processor instance
281
     *
282
     * @return void
283
     */
284
    public function setRegistryProcessor(RegistryProcessorInterface $registryProcessor)
285
    {
286
        $this->registryProcessor = $registryProcessor;
287
    }
288
289
    /**
290
     * Return's the RegistryProcessor instance to handle the running threads.
291
     *
292
     * @return \TechDivision\Import\Services\RegistryProcessor The registry processor instance
293
     */
294
    public function getRegistryProcessor()
295
    {
296
        return $this->registryProcessor;
297
    }
298
299
    /**
300
     * Set's the import processor instance.
301
     *
302
     * @param \TechDivision\Import\Services\ImportProcessorInterface $importProcessor The import processor instance
303
     *
304
     * @return void
305
     */
306
    public function setImportProcessor(ImportProcessorInterface $importProcessor)
307
    {
308
        $this->importProcessor = $importProcessor;
309
    }
310
311
    /**
312
     * Return's the import processor instance.
313
     *
314
     * @return \TechDivision\Import\Services\ImportProcessorInterface The import processor instance
315
     */
316
    public function getImportProcessor()
317
    {
318
        return $this->importProcessor;
319
    }
320
321
    /**
322
     * The array with the system loggers.
323
     *
324
     * @param array $systemLoggers The system logger instances
325
     *
326
     * @return void
327
     */
328
    public function setSystemLoggers(array $systemLoggers)
329
    {
330
        $this->systemLoggers = $systemLoggers;
331
    }
332
333
    /**
334
     * Set's the plugin factory instance.
335
     *
336
     * @param \TechDivision\Import\Plugins\PluginFactoryInterface $pluginFactory The plugin factory instance
337
     *
338
     * @return void
339
     */
340
    public function setPluginFactory(PluginFactoryInterface $pluginFactory)
341
    {
342
        $this->pluginFactory = $pluginFactory;
343
    }
344
345
    /**
346
     * Return's the plugin factory instance.
347
     *
348
     * @return \TechDivision\Import\Plugins\PluginFactoryInterface The plugin factory instance
349
     */
350
    public function getPluginFactory()
351
    {
352
        return $this->pluginFactory;
353
    }
354
355
    /**
356
     * Return's the logger with the passed name, by default the system logger.
357
     *
358
     * @param string $name The name of the requested system logger
359
     *
360
     * @return \Psr\Log\LoggerInterface The logger instance
361
     * @throws \Exception Is thrown, if the requested logger is NOT available
362
     */
363
    public function getSystemLogger($name = LoggerKeys::SYSTEM)
364
    {
365
366
        // query whether or not, the requested logger is available
367
        if (isset($this->systemLoggers[$name])) {
368
            return $this->systemLoggers[$name];
369
        }
370
371
        // throw an exception if the requested logger is NOT available
372
        throw new \Exception(
373
            sprintf(
374
                'The requested logger \'%s\' is not available',
375
                $name
376
            )
377
        );
378
    }
379
380
    /**
381
     * Query whether or not the system logger with the passed name is available.
382
     *
383
     * @param string $name The name of the requested system logger
384
     *
385
     * @return boolean TRUE if the logger with the passed name exists, else FALSE
386
     */
387
    public function hasSystemLogger($name = LoggerKeys::SYSTEM)
388
    {
389
        return isset($this->systemLoggers[$name]);
390
    }
391
392
    /**
393
     * Return's the array with the system logger instances.
394
     *
395
     * @return array The logger instance
396
     */
397
    public function getSystemLoggers()
398
    {
399
        return $this->systemLoggers;
400
    }
401
402
    /**
403
     * Return's the unique serial for this import process.
404
     *
405
     * @return string The unique serial
406
     */
407
    public function getSerial()
408
    {
409
        return $this->serial;
410
    }
411
412
    /**
413
     * The shutdown handler to catch fatal errors.
414
     *
415
     * This method is need to make sure, that an existing PID file will be removed
416
     * if a fatal error has been triggered.
417
     *
418
     * @return void
419
     */
420
    public function shutdown()
421
    {
422
423
        // check if there was a fatal error caused shutdown
424
        if ($lastError = error_get_last()) {
425
            // initialize error type and message
426
            $type = 0;
427
            $message = '';
428
            // extract the last error values
429
            extract($lastError);
430
            // query whether we've a fatal/user error
431
            if ($type === E_ERROR || $type === E_USER_ERROR) {
432
                // clean-up the PID file
433
                $this->unlock();
434
                // log the fatal error message
435
                $this->log($message, LogLevel::ERROR);
436
            }
437
        }
438
    }
439
440
    /**
441
     * Persist the UUID of the actual import process to the PID file.
442
     *
443
     * @return void
444
     * @throws \Exception Is thrown, if the PID can not be locked or the PID can not be added
445
     * @throws \TechDivision\Import\Exceptions\ImportAlreadyRunningException Is thrown, if a import process is already running
446
     */
447
    public function lock()
448
    {
449
450
        // query whether or not, the PID has already been set
451
        if ($this->pid === $this->getSerial()) {
452
            return;
453
        }
454
455
        // if not, initialize the PID
456
        $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...
457
458
        // open the PID file
459
        $this->fh = fopen($filename = $this->getPidFilename(), 'a+');
460
461
        // try to lock the PID file exclusive
462
        if (!flock($this->fh, LOCK_EX|LOCK_NB)) {
463
            throw new ImportAlreadyRunningException(sprintf('PID file %s is already in use', $filename));
464
        }
465
466
        // append the PID to the PID file
467
        if (fwrite($this->fh, $this->pid . PHP_EOL) === false) {
468
            throw new \Exception(sprintf('Can\'t write PID %s to PID file %s', $this->pid, $filename));
469
        }
470
    }
471
472
    /**
473
     * Remove's the UUID of the actual import process from the PID file.
474
     *
475
     * @return void
476
     * @throws \Exception Is thrown, if the PID can not be removed
477
     */
478
    public function unlock()
479
    {
480
        try {
481
            // remove the PID from the PID file if set
482
            if ($this->pid === $this->getSerial() && is_resource($this->fh)) {
483
                // remove the PID from the file
484
                $this->removeLineFromFile($this->pid, $this->fh);
485
486
                // finally unlock/close the PID file
487
                flock($this->fh, LOCK_UN);
488
                fclose($this->fh);
489
490
                // if the PID file is empty, delete the file
491
                if (filesize($filename = $this->getPidFilename()) === 0) {
492
                    unlink($filename);
493
                }
494
            }
495
496
        } catch (FileNotFoundException $fnfe) {
497
            $this->getSystemLogger()->notice(sprintf('PID file %s doesn\'t exist', $this->getPidFilename()));
498
        } catch (LineNotFoundException $lnfe) {
499
            $this->getSystemLogger()->notice(sprintf('PID %s is can not be found in PID file %s', $this->pid, $this->getPidFilename()));
500
        } catch (\Exception $e) {
501
            throw new \Exception(sprintf('Can\'t remove PID %s from PID file %s', $this->pid, $this->getPidFilename()), null, $e);
502
        }
503
    }
504
505
    /**
506
     * Remove's the passed line from the file with the passed name.
507
     *
508
     * @param string   $line The line to be removed
509
     * @param resource $fh   The file handle of the file the line has to be removed
510
     *
511
     * @return void
512
     * @throws \Exception Is thrown, if the file doesn't exists, the line is not found or can not be removed
513
     */
514
    public function removeLineFromFile($line, $fh)
515
    {
516
517
        // initialize the array for the PIDs found in the PID file
518
        $lines = array();
519
520
        // initialize the flag if the line has been found
521
        $found = false;
522
523
        // rewind the file pointer
524
        rewind($fh);
525
526
        // read the lines with the PIDs from the PID file
527
        while (($buffer = fgets($fh, 4096)) !== false) {
528
            // remove the new line
529
            $buffer = trim($buffer);
530
            // if the line is the one to be removed, ignore the line
531
            if ($line === $buffer) {
532
                $found = true;
533
                continue;
534
            }
535
536
            // add the found PID to the array
537
            $lines[] = $buffer;
538
        }
539
540
        // query whether or not, we found the line
541
        if (!$found) {
542
            throw new LineNotFoundException(sprintf('Line %s can not be found', $line));
543
        }
544
545
        // empty the file and rewind the file pointer
546
        ftruncate($fh, 0);
547
        rewind($fh);
548
549
        // append the existing lines to the file
550
        foreach ($lines as $ln) {
551
            if (fwrite($fh, $ln . PHP_EOL) === false) {
552
                throw new \Exception(sprintf('Can\'t write %s to file', $ln));
553
            }
554
        }
555
    }
556
557
    /**
558
     * Process the given operation.
559
     *
560
     * @return void
561
     * @throws \Exception Is thrown if the operation can't be finished successfully
562
     */
563
    public function process()
564
    {
565
566
        try {
567
            // track the start time
568
            $startTime = microtime(true);
569
570
            // start the transaction
571
            $this->getImportProcessor()->getConnection()->beginTransaction();
572
573
            // prepare the global data for the import process
574
            $this->setUp();
575
576
            // process the plugins defined in the configuration
577
            /** @var \TechDivision\Import\Configuration\PluginConfigurationInterface $pluginConfiguration */
578
            foreach ($this->getConfiguration()->getPlugins() as $pluginConfiguration) {
579
                // query whether or not the operation has been stopped
580
                if ($this->isStopped()) {
581
                    break;
582
                }
583
                // process the plugin if not
584
                $this->pluginFactory->createPlugin($pluginConfiguration)->process();
585
            }
586
587
            // tear down the  instance
588
            $this->tearDown();
589
590
            // commit the transaction
591
            $this->getImportProcessor()->getConnection()->commit();
592
593
            // track the time needed for the import in seconds
594
            $endTime = microtime(true) - $startTime;
595
596
            // log a message that import has been finished
597
            $this->log(
598
                sprintf(
599
                    'Successfully finished import with serial %s in %f s',
600
                    $this->getSerial(),
601
                    $endTime
602
                ),
603
                LogLevel::INFO
604
            );
605
606
        } catch (ImportAlreadyRunningException $iare) {
607
            // tear down
608
            $this->tearDown();
609
610
            // rollback the transaction
611
            $this->getImportProcessor()->getConnection()->rollBack();
612
613
            // finally, if a PID has been set (because CSV files has been found),
614
            // remove it from the PID file to unlock the importer
615
            $this->unlock();
616
617
            // track the time needed for the import in seconds
618
            $endTime = microtime(true) - $startTime;
619
620
            // log a warning, because another import process is already running
621
            $this->getSystemLogger()->warning($iare->__toString());
622
623
            // log a message that import has been finished
624
            $this->getSystemLogger()->info(
625
                sprintf(
626
                    'Can\'t finish import with serial because another import process is running %s in %f s',
627
                    $this->getSerial(),
628
                    $endTime
629
                )
630
            );
631
632
            // re-throw the exception
633
            throw $iare;
634
635
        } catch (\Exception $e) {
636
            // tear down
637
            $this->tearDown();
638
639
            // rollback the transaction
640
            $this->getImportProcessor()->getConnection()->rollBack();
641
642
            // finally, if a PID has been set (because CSV files has been found),
643
            // remove it from the PID file to unlock the importer
644
            $this->unlock();
645
646
            // track the time needed for the import in seconds
647
            $endTime = microtime(true) - $startTime;
648
649
            // log a message that the file import failed
650
            foreach ($this->systemLoggers as $systemLogger) {
651
                $systemLogger->error($e->__toString());
652
            }
653
654
            // log a message that import has been finished
655
            $this->getSystemLogger()->info(
656
                sprintf(
657
                    'Can\'t finish import with serial %s in %f s',
658
                    $this->getSerial(),
659
                    $endTime
660
                )
661
            );
662
663
            // re-throw the exception
664
            throw $e;
665
        }
666
    }
667
668
    /**
669
     * Stop processing the operation.
670
     *
671
     * @param string $reason The reason why the operation has been stopped
672
     *
673
     * @return void
674
     */
675
    public function stop($reason)
676
    {
677
678
        // log a message that the operation has been stopped
679
        $this->log($reason, LogLevel::INFO);
680
681
        // stop processing the plugins by setting the flag to TRUE
682
        $this->stopped = true;
683
    }
684
685
    /**
686
     * Return's TRUE if the operation has been stopped, else FALSE.
687
     *
688
     * @return boolean TRUE if the process has been stopped, else FALSE
689
     */
690
    public function isStopped()
691
    {
692
        return $this->stopped;
693
    }
694
695
    /**
696
     * Finds an entry of the container by its identifier and returns it.
697
     *
698
     * @param string $id Identifier of the entry to look for.
699
     *
700
     * @throws NotFoundExceptionInterface  No entry was found for **this** identifier.
701
     * @throws ContainerExceptionInterface Error while retrieving the entry.
702
     *
703
     * @return mixed Entry.
704
     */
705
    public function get($id)
706
    {
707
        return $this->getContainer()->get($id);
708
    }
709
710
    /**
711
     * Returns true if the container can return an entry for the given identifier.
712
     * Returns false otherwise.
713
     *
714
     * `has($id)` returning true does not mean that `get($id)` will not throw an exception.
715
     * It does however mean that `get($id)` will not throw a `NotFoundExceptionInterface`.
716
     *
717
     * @param string $id Identifier of the entry to look for.
718
     *
719
     * @return bool
720
     */
721
    public function has($id)
722
    {
723
        return $this->getContainer()->has($id);
724
    }
725
726
    /**
727
     * Lifecycle callback that will be inovked before the
728
     * import process has been started.
729
     *
730
     * @return void
731
     */
732
    protected function setUp()
733
    {
734
735
        // generate the serial for the new job
736
        $this->serial = Uuid::uuid4()->__toString();
737
738
        // write the TechDivision ANSI art icon to the console
739
        $this->log($this->ansiArt);
740
741
        // log the debug information, if debug mode is enabled
742
        if ($this->getConfiguration()->isDebugMode()) {
743
            // load the application from the DI container
744
            /** @var TechDivision\Import\App\Application $application */
745
            $application = $this->getContainer()->get(DependencyInjectionKeys::APPLICATION);
746
            // log the system's PHP configuration
747
            $this->log(sprintf('PHP version: %s', phpversion()), LogLevel::DEBUG);
748
            $this->log(sprintf('App version: %s', $application->getVersion()), LogLevel::DEBUG);
749
            $this->log('-------------------- Loaded Extensions -----------------------', LogLevel::DEBUG);
750
            $this->log(implode(', ', $loadedExtensions = get_loaded_extensions()), LogLevel::DEBUG);
751
            $this->log('--------------------------------------------------------------', LogLevel::DEBUG);
752
753
            // write a warning for low performance, if XDebug extension is activated
754
            if (in_array('xdebug', $loadedExtensions)) {
755
                $this->log('Low performance exptected, as result of enabled XDebug extension!', LogLevel::WARNING);
756
            }
757
        }
758
759
        // log a message that import has been started
760
        $this->log(
761
            sprintf(
762
                'Now start import with serial %s (operation: %s)',
763
                $this->getSerial(),
764
                $this->getConfiguration()->getOperationName()
765
            ),
766
            LogLevel::INFO
767
        );
768
769
        // initialize the status
770
        $status = array(
771
            RegistryKeys::STATUS => 1,
772
            RegistryKeys::BUNCHES => 0,
773
            RegistryKeys::SOURCE_DIRECTORY => $this->getConfiguration()->getSourceDir(),
774
            RegistryKeys::MISSING_OPTION_VALUES => array()
775
        );
776
777
        // append it to the registry
778
        $this->getRegistryProcessor()->setAttribute($this->getSerial(), $status);
779
    }
780
781
    /**
782
     * Lifecycle callback that will be inovked after the
783
     * import process has been finished.
784
     *
785
     * @return void
786
     */
787
    protected function tearDown()
788
    {
789
        $this->getRegistryProcessor()->removeAttribute($this->getSerial());
790
    }
791
792
    /**
793
     * Simple method that writes the passed method the the console and the
794
     * system logger, if configured and a log level has been passed.
795
     *
796
     * @param string $msg      The message to log
797
     * @param string $logLevel The log level to use
798
     *
799
     * @return void
800
     */
801
    protected function log($msg, $logLevel = null)
802
    {
803
804
        // initialize the formatter helper
805
        $helper = new FormatterHelper();
806
807
        // map the log level to the console style
808
        $style = $this->mapLogLevelToStyle($logLevel);
809
810
        // format the message, according to the passed log level and write it to the console
811
        $this->getOutput()->writeln($logLevel ? $helper->formatBlock($msg, $style) : $msg);
812
813
        // log the message if a log level has been passed
814
        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...
815
            $systemLogger->log($logLevel, $msg);
816
        }
817
    }
818
819
    /**
820
     * Map's the passed log level to a valid symfony console style.
821
     *
822
     * @param string $logLevel The log level to map
823
     *
824
     * @return string The apropriate symfony console style
825
     */
826
    protected function mapLogLevelToStyle($logLevel)
827
    {
828
829
        // query whether or not the log level is mapped
830
        if (isset($this->logLevelStyleMapping[$logLevel])) {
831
            return $this->logLevelStyleMapping[$logLevel];
832
        }
833
834
        // return the default style => info
835
        return Simple::DEFAULT_STYLE;
836
    }
837
838
    /**
839
     * Return's the PID filename to use.
840
     *
841
     * @return string The PID filename
842
     */
843
    protected function getPidFilename()
844
    {
845
        return $this->getConfiguration()->getPidFilename();
846
    }
847
}
848