Completed
Pull Request — master (#41)
by Tim
03:41
created

Configuration::isDebugMode()   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 0
Metric Value
c 0
b 0
f 0
dl 0
loc 4
ccs 0
cts 4
cp 0
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 2
1
<?php
2
3
/**
4
 * TechDivision\Import\Cli\Configuration
5
 *
6
 * NOTICE OF LICENSE
7
 *
8
 * This source file is subject to the Open Software License (OSL 3.0)
9
 * that is available through the world-wide-web at this URL:
10
 * http://opensource.org/licenses/osl-3.0.php
11
 *
12
 * PHP version 5
13
 *
14
 * @author    Tim Wagner <[email protected]>
15
 * @copyright 2016 TechDivision GmbH <[email protected]>
16
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
17
 * @link      https://github.com/techdivision/import-cli-simple
18
 * @link      http://www.techdivision.com
19
 */
20
21
namespace TechDivision\Import\Cli;
22
23
use Psr\Log\LogLevel;
24
use JMS\Serializer\Annotation\Type;
25
use JMS\Serializer\SerializerBuilder;
26
use JMS\Serializer\Annotation\SerializedName;
27
use TechDivision\Import\ConfigurationInterface;
28
use Symfony\Component\Console\Input\InputInterface;
29
use TechDivision\Import\Cli\Command\InputOptionKeys;
30
use TechDivision\Import\Cli\Command\InputArgumentKeys;
31
use TechDivision\Import\Cli\Configuration\Operation;
32
33
/**
34
 * A simple configuration implementation.
35
 *
36
 * @author    Tim Wagner <[email protected]>
37
 * @copyright 2016 TechDivision GmbH <[email protected]>
38
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
39
 * @link      https://github.com/techdivision/import-cli-simple
40
 * @link      http://www.techdivision.com
41
 */
42
class Configuration implements ConfigurationInterface
43
{
44
45
    /**
46
     * Mapping for boolean values passed on the console.
47
     *
48
     * @var array
49
     */
50
    protected $booleanMapping = array(
51
        'true'  => true,
52
        'false' => false,
53
        '1'     => true,
54
        '0'     => false,
55
        'on'    => true,
56
        'off'   => false
57
    );
58
59
    /**
60
     * The operation name to use.
61
     *
62
     * @var string
63
     * @Type("string")
64
     * @SerializedName("operation-name")
65
     */
66
    protected $operationName;
67
68
    /**
69
     * The Magento edition, EE or CE.
70
     *
71
     * @var string
72
     * @Type("string")
73
     * @SerializedName("magento-edition")
74
     */
75
    protected $magentoEdition = 'CE';
76
77
    /**
78
     * The Magento version, e. g. 2.1.0.
79
     *
80
     * @var string
81
     * @Type("string")
82
     * @SerializedName("magento-version")
83
     */
84
    protected $magentoVersion = '2.1.2';
85
86
    /**
87
     * The Magento installation directory.
88
     *
89
     * @var string
90
     * @Type("string")
91
     * @SerializedName("installation-dir")
92
     */
93
    protected $installationDir;
94
95
    /**
96
     * The source directory that has to be watched for new files.
97
     *
98
     * @var string
99
     * @Type("string")
100
     * @SerializedName("source-dir")
101
     */
102
    protected $sourceDir;
103
104
    /**
105
     * The target directory with the files that has been imported.
106
     *
107
     * @var string
108
     * @Type("string")
109
     * @SerializedName("target-dir")
110
     */
111
    protected $targetDir;
112
113
    /**
114
     * ArrayCollection with the information of the configured databases.
115
     *
116
     * @var \Doctrine\Common\Collections\ArrayCollection
117
     * @Type("ArrayCollection<TechDivision\Import\Cli\Configuration\Database>")
118
     */
119
    protected $databases;
120
121
    /**
122
     * ArrayCollection with the information of the configured operations.
123
     *
124
     * @var \Doctrine\Common\Collections\ArrayCollection
125
     * @Type("ArrayCollection<TechDivision\Import\Cli\Configuration\Operation>")
126
     */
127
    protected $operations;
128
129
    /**
130
     * The subject's utility class with the SQL statements to use.
131
     *
132
     * @var string
133
     * @Type("string")
134
     * @SerializedName("utility-class-name")
135
     */
136
    protected $utilityClassName;
137
138
    /**
139
     * The source date format to use in the subject.
140
     *
141
     * @var string
142
     * @Type("string")
143
     * @SerializedName("source-date-format")
144
     */
145
    protected $sourceDateFormat = 'n/d/y, g:i A';
146
147
    /**
148
     * The subject's multiple field delimiter character for fields with multiple values, defaults to (,).
149
     *
150
     * @var string
151
     * @Type("string")
152
     * @SerializedName("multiple-field-delimiter")
153
     */
154
    protected $multipleFieldDelimiter = ',';
155
156
    /**
157
     * The subject's delimiter character for CSV files.
158
     *
159
     * @var string
160
     * @Type("string")
161
     */
162
    protected $delimiter;
163
164
    /**
165
     * The subject's enclosure character for CSV files.
166
     *
167
     * @var string
168
     * @Type("string")
169
     */
170
    protected $enclosure;
171
172
    /**
173
     * The subject's escape character for CSV files.
174
     *
175
     * @var string
176
     * @Type("string")
177
     */
178
    protected $escape;
179
180
    /**
181
     * The subject's source charset for the CSV file.
182
     *
183
     * @var string
184
     * @Type("string")
185
     * @SerializedName("from-charset")
186
     */
187
    protected $fromCharset;
188
189
    /**
190
     * The subject's target charset for a CSV file.
191
     *
192
     * @var string
193
     * @Type("string")
194
     * @SerializedName("to-charset")
195
     */
196
    protected $toCharset;
197
198
    /**
199
     * The subject's file mode for a CSV target file.
200
     *
201
     * @var string
202
     * @Type("string")
203
     * @SerializedName("file-mode")
204
     */
205
    protected $fileMode;
206
207
    /**
208
     * The flag to signal that the subject has to use the strict mode or not.
209
     *
210
     * @var boolean
211
     * @Type("boolean")
212
     * @SerializedName("strict-mode")
213
     */
214
    protected $strictMode;
215
216
    /**
217
     * The flag whether or not the import artefacts have to be archived.
218
     *
219
     * @var boolean
220
     * @Type("boolean")
221
     * @SerializedName("archive-artefacts")
222
     */
223
    protected $archiveArtefacts;
224
225
    /**
226
     * The directory where the archives will be stored.
227
     *
228
     * @var string
229
     * @Type("string")
230
     * @SerializedName("archive-dir")
231
     */
232
    protected $archiveDir;
233
234
    /**
235
     * The flag to signal that the subject has to use the debug mode or not.
236
     *
237
     * @var boolean
238
     * @Type("boolean")
239
     * @SerializedName("debug-mode")
240
     */
241
    protected $debugMode = false;
242
243
    /**
244
     * The flag to signal that the an existing PID should be ignored, whether or import process is running or not.
245
     *
246
     * @var boolean
247
     * @Type("boolean")
248
     * @SerializedName("ignore-pid")
249
     */
250
    protected $ignorePid = false;
251
252
    /**
253
     * The log level to use (see Monolog documentation).
254
     *
255
     * @var string
256
     * @Type("string")
257
     * @SerializedName("log-level")
258
     */
259
    protected $logLevel = LogLevel::INFO;
260
261
    /**
262
     * Factory implementation to create a new initialized configuration instance.
263
     *
264
     * If command line options are specified, they will always override the
265
     * values found in the configuration file.
266
     *
267
     * @param \Symfony\Component\Console\Input\InputInterface $input The Symfony console input instance
268
     *
269
     * @return \TechDivision\Import\Cli\Configuration The configuration instance
270
     * @throws \Exception Is thrown, if the specified configuration file doesn't exist
271
     */
272
    public static function factory(InputInterface $input)
273
    {
274
275
        // load the configuration filename we want to use
276
        $filename = $input->getOption(InputOptionKeys::CONFIGURATION);
277
278
        // load the JSON data
279
        if (!$jsonData = file_get_contents($filename)) {
280
            throw new \Exception(sprintf('Can\'t load configuration file %s', $filename));
281
        }
282
283
        // initialize the JMS serializer and load the configuration
284
        $serializer = SerializerBuilder::create()->build();
285
        /** @var \TechDivision\Import\Cli\Configuration $instance */
286
        $instance = $serializer->deserialize($jsonData, 'TechDivision\Import\Cli\Configuration', 'json');
287
288
        // query whether or not an operation name has been specified as command line
289
        // option, if yes override the value from the configuration file
290
        if ($operationName = $input->getArgument(InputArgumentKeys::OPERATION_NAME)) {
291
            $instance->setOperationName($operationName);
292
        }
293
294
        // query whether or not a Magento installation directory has been specified as command line
295
        // option, if yes override the value from the configuration file
296
        if ($installationDir = $input->getOption(InputOptionKeys::INSTALLATION_DIR)) {
297
            $instance->setInstallationDir($installationDir);
298
        }
299
300
        // query whether or not a directory for the source files has been specified as command line
301
        // option, if yes override the value from the configuration file
302
        if ($sourceDir = $input->getOption(InputOptionKeys::SOURCE_DIR)) {
303
            $instance->setSourceDir($sourceDir);
304
        }
305
306
        // query whether or not a directory containing the imported files has been specified as command line
307
        // option, if yes override the value from the configuration file
308
        if ($targetDir = $input->getOption(InputOptionKeys::TARGET_DIR)) {
309
            $instance->setTargetDir($targetDir);
310
        }
311
312
        // query whether or not a source date format has been specified as command
313
        // line  option, if yes override the value from the configuration file
314
        if ($sourceDateFormat = $input->getOption(InputOptionKeys::SOURCE_DATE_FORMAT)) {
315
            $instance->setSourceDateFormat($sourceDateFormat);
316
        }
317
318
        // query whether or not a Magento edition has been specified as command line
319
        // option, if yes override the value from the configuration file
320
        if ($magentoEdition = $input->getOption(InputOptionKeys::MAGENTO_EDITION)) {
321
            $instance->setMagentoEdition($magentoEdition);
322
        }
323
324
        // query whether or not a Magento version has been specified as command line
325
        // option, if yes override the value from the configuration file
326
        if ($magentoVersion = $input->getOption(InputOptionKeys::MAGENTO_VERSION)) {
327
            $instance->setMagentoVersion($magentoVersion);
328
        }
329
330
        // query whether or not a PDO DSN has been specified as command line
331
        // option, if yes override the value from the configuration file
332
        if ($dsn = $input->getOption(InputOptionKeys::DB_PDO_DSN)) {
333
            $instance->getDatabase()->setDsn($dsn);
334
        }
335
336
        // query whether or not a DB username has been specified as command line
337
        // option, if yes override the value from the configuration file
338
        if ($username = $input->getOption(InputOptionKeys::DB_USERNAME)) {
339
            $instance->getDatabase()->setUsername($username);
340
        }
341
342
        // query whether or not a DB password has been specified as command line
343
        // option, if yes override the value from the configuration file
344
        if ($password = $input->getOption(InputOptionKeys::DB_PASSWORD)) {
345
            $instance->getDatabase()->setPassword($password);
346
        }
347
348
        // query whether or not the debug mode has been specified as command line
349
        // option, if yes override the value from the configuration file
350
        if ($debugMode = $input->getOption(InputOptionKeys::DEBUG_MODE)) {
351
            $instance->setDebugMode($instance->mapBoolean($debugMode));
352
        }
353
354
        // query whether or not the ignore PID flag has been specified as command line
355
        // option, if yes override the value from the configuration file
356
        if ($ignorePid = $input->getOption(InputOptionKeys::IGNORE_PID)) {
357
            $instance->setIgnorePid($instance->mapBoolean($ignorePid));
358
        }
359
360
        // query whether or not the log level has been specified as command line
361
        // option, if yes override the value from the configuration file
362
        if ($logLevel = $input->getOption(InputOptionKeys::LOG_LEVEL)) {
363
            $instance->setLogLevel($logLevel);
364
        }
365
366
        // extend the subjects with the parent configuration instance
367
        /** @var \TechDivision\Import\Cli\Configuration\Subject $subject */
368
        foreach ($instance->getSubjects() as $subject) {
369
            // set the configuration instance on the subject
370
            $subject->setConfiguration($instance);
371
        }
372
373
        // query whether or not the debug mode is enabled and log level
374
        // has NOT been overwritten with a commandline option
375
        if ($instance->isDebugMode() && !$input->getOption(InputOptionKeys::LOG_LEVEL)) {
376
            // set debug log level, if log level has NOT been overwritten on command line
377
            $instance->setLogLevel(LogLevel::DEBUG);
378
        }
379
380
        // return the initialized configuration instance
381
        return $instance;
382
    }
383
384
    /**
385
     * Return's the array with the subjects of the operation to use.
386
     *
387
     * @return \Doctrine\Common\Collections\ArrayCollection The ArrayCollection with the subjects
388
     * @throws \Exception Is thrown, if no subjects are available for the actual operation
389
     */
390
    public function getSubjects()
391
    {
392
393
        // iterate over the operations and return the subjects of the actual one
394
        /** @var TechDivision\Import\Configuration\OperationInterface $operation */
395
        foreach ($this->getOperations() as $operation) {
396
            if ($this->getOperation()->equals($operation)) {
397
                return $operation->getSubjects();
398
            }
399
        }
400
401
        // throw an exception if no subjects are available
402
        throw new \Exception(sprintf('Can\'t find any subjects for operation %s', $this->getOperation()));
403
    }
404
405
    /**
406
     * Map's the passed value to a boolean.
407
     *
408
     * @param string $value The value to map
409
     *
410
     * @return boolean The mapped value
411
     * @throws \Exception Is thrown, if the value can't be mapped
412
     */
413
    public function mapBoolean($value)
414
    {
415
416
        // try to map the passed value to a boolean
417
        if (isset($this->booleanMapping[$value])) {
418
            return $this->booleanMapping[$value];
419
        }
420
421
        // throw an exception if we can't convert the passed value
422
        throw new \Exception(sprintf('Can\'t convert %s to boolean', $value));
423
    }
424
425
    /**
426
     * Return's the operation, initialize from the actual operation name.
427
     *
428
     * @return \TechDivision\Import\Configuration\OperationInterface The operation instance
429
     */
430
    protected function getOperation()
431
    {
432
        return new Operation($this->getOperationName());
433
    }
434
435
    /**
436
     * Return's the operation name that has to be used.
437
     *
438
     * @param string $operationName The operation name that has to be used
439
     *
440
     * @return void
441
     */
442
    public function setOperationName($operationName)
443
    {
444
        return $this->operationName = $operationName;
445
    }
446
447
    /**
448
     * Return's the operation name that has to be used.
449
     *
450
     * @return string The operation name that has to be used
451
     */
452
    public function getOperationName()
453
    {
454
        return $this->operationName;
455
    }
456
457
    /**
458
     * Set's the Magento installation directory.
459
     *
460
     * @param string $installationDir The Magento installation directory
461
     *
462
     * @return void
463
     */
464
    public function setInstallationDir($installationDir)
465
    {
466
        $this->installationDir = $installationDir;
467
    }
468
469
    /**
470
     * Return's the Magento installation directory.
471
     *
472
     * @return string The Magento installation directory
473
     */
474
    public function getInstallationDir()
475
    {
476
        return $this->installationDir;
477
    }
478
479
    /**
480
     * Set's the source directory that has to be watched for new files.
481
     *
482
     * @param string $sourceDir The source directory
483
     *
484
     * @return void
485
     */
486
    public function setSourceDir($sourceDir)
487
    {
488
        $this->sourceDir = $sourceDir;
489
    }
490
491
    /**
492
     * Return's the source directory that has to be watched for new files.
493
     *
494
     * @return string The source directory
495
     */
496
    public function getSourceDir()
497
    {
498
        return $this->sourceDir;
499
    }
500
501
    /**
502
     * Return's the target directory with the files that has been imported.
503
     *
504
     * @return string The target directory
505
     */
506
    public function getTargetDir()
507
    {
508
        return $this->targetDir;
509
    }
510
511
    /**
512
     * Set's the target directory with the files that has been imported.
513
     *
514
     * @param string $targetDir The target directory
515
     *
516
     * @return void
517
     */
518
    public function setTargetDir($targetDir)
519
    {
520
        $this->targetDir = $targetDir;
521
    }
522
523
    /**
524
     * Return's the utility class with the SQL statements to use.
525
     *
526
     * @param string $utilityClassName The utility class name
527
     *
528
     * @return void
529
     */
530
    public function setUtilityClassName($utilityClassName)
531
    {
532
        return $this->utilityClassName = $utilityClassName;
533
    }
534
535
    /**
536
     * Return's the utility class with the SQL statements to use.
537
     *
538
     * @return string The utility class name
539
     */
540
    public function getUtilityClassName()
541
    {
542
        return $this->utilityClassName;
543
    }
544
545
    /**
546
     * Set's the Magento edition, EE or CE.
547
     *
548
     * @param string $magentoEdition The Magento edition
549
     *
550
     * @return void
551
     */
552
    public function setMagentoEdition($magentoEdition)
553
    {
554
        $this->magentoEdition = $magentoEdition;
555
    }
556
557
    /**
558
     * Return's the Magento edition, EE or CE.
559
     *
560
     * @return string The Magento edition
561
     */
562
    public function getMagentoEdition()
563
    {
564
        return $this->magentoEdition;
565
    }
566
567
    /**
568
     * Return's the Magento version, e. g. 2.1.0.
569
     *
570
     * @param string $magentoVersion The Magento version
571
     *
572
     * @return void
573
     */
574
    public function setMagentoVersion($magentoVersion)
575
    {
576
        $this->magentoVersion = $magentoVersion;
577
    }
578
579
    /**
580
     * Return's the Magento version, e. g. 2.1.0.
581
     *
582
     * @return string The Magento version
583
     */
584
    public function getMagentoVersion()
585
    {
586
        return $this->magentoVersion;
587
    }
588
589
    /**
590
     * Return's the subject's source date format to use.
591
     *
592
     * @return string The source date format
593
     */
594
    public function getSourceDateFormat()
595
    {
596
        return $this->sourceDateFormat;
597
    }
598
599
    /**
600
     * Set's the subject's source date format to use.
601
     *
602
     * @param string $sourceDateFormat The source date format
603
     *
604
     * @return void
605
     */
606
    public function setSourceDateFormat($sourceDateFormat)
607
    {
608
        $this->sourceDateFormat = $sourceDateFormat;
609
    }
610
611
    /**
612
     * Return's the multiple field delimiter character to use, default value is comma (,).
613
     *
614
     * @return string The multiple field delimiter character
615
     */
616
    public function getMultipleFieldDelimiter()
617
    {
618
        return $this->multipleFieldDelimiter;
619
    }
620
621
    /**
622
     * Return's the delimiter character to use, default value is comma (,).
623
     *
624
     * @return string The delimiter character
625
     */
626
    public function getDelimiter()
627
    {
628
        return $this->delimiter;
629
    }
630
631
    /**
632
     * The enclosure character to use, default value is double quotation (").
633
     *
634
     * @return string The enclosure character
635
     */
636
    public function getEnclosure()
637
    {
638
        return $this->enclosure;
639
    }
640
641
    /**
642
     * The escape character to use, default value is backslash (\).
643
     *
644
     * @return string The escape character
645
     */
646
    public function getEscape()
647
    {
648
        return $this->escape;
649
    }
650
651
    /**
652
     * The file encoding of the CSV source file, default value is UTF-8.
653
     *
654
     * @return string The charset used by the CSV source file
655
     */
656
    public function getFromCharset()
657
    {
658
        return $this->fromCharset;
659
    }
660
661
    /**
662
     * The file encoding of the CSV targetfile, default value is UTF-8.
663
     *
664
     * @return string The charset used by the CSV target file
665
     */
666
    public function getToCharset()
667
    {
668
        return $this->toCharset;
669
    }
670
671
    /**
672
     * The file mode of the CSV target file, either one of write or append, default is write.
673
     *
674
     * @return string The file mode of the CSV target file
675
     */
676
    public function getFileMode()
677
    {
678
        return $this->fileMode;
679
    }
680
681
    /**
682
     * Queries whether or not strict mode is enabled or not, default is TRUE.
683
     *
684
     * @return boolean TRUE if strict mode is enabled, else FALSE
685
     */
686
    public function isStrictMode()
687
    {
688
        return $this->strictMode;
689
    }
690
691
    /**
692
     * Return's the database configuration.
693
     *
694
     * @param string $id The ID of the database connection to return
695
     *
696
     * @return \TechDivision\Import\Cli\Configuration\Database The database configuration
697
     * @throws \Exception Is thrown, if the database with the passed ID is not configured
698
     */
699
    public function getDatabase($id = null)
700
    {
701
702
        // if no ID has been passed, try to load the default database
703
        if ($id === null) {
704
            // iterate over the configured databases and return the default database
705
            /** @var TechDivision\Import\Configuration\DatabaseInterface  $database */
706
            foreach ($this->databases as $database) {
707
                if ($database->isDefault()) {
708
                    return $database;
709
                }
710
            }
711
        }
712
713
        // iterate over the configured databases and return the one with the passed ID
714
        /** @var TechDivision\Import\Configuration\DatabaseInterface  $database */
715
        foreach ($this->databases as $database) {
716
            if ($database->getId() === $id) {
717
                return $database;
718
            }
719
        }
720
721
        // throw an exception, if the database with the passed ID is NOT configured
722
        throw new \Exception(sprintf('Database with ID %s can not be found', $id));
723
    }
724
725
    /**
726
     * Return's the ArrayCollection with the configured operations.
727
     *
728
     * @return \Doctrine\Common\Collections\ArrayCollection The ArrayCollection with the operations
729
     */
730
    public function getOperations()
731
    {
732
        return $this->operations;
733
    }
734
735
    /**
736
     * Return's the TRUE if the import artefacts have to be archived.
737
     *
738
     * @return boolean TRUE if the import artefacts have to be archived
739
     */
740
    public function haveArchiveArtefacts()
741
    {
742
        return $this->archiveArtefacts;
743
    }
744
745
    /**
746
     * The directory where the archives will be stored.
747
     *
748
     * @return string The archive directory
749
     */
750
    public function getArchiveDir()
751
    {
752
        return $this->archiveDir;
753
    }
754
755
    /**
756
     * Set's the debug mode.
757
     *
758
     * @param boolean $debugMode TRUE if debug mode is enabled, else FALSE
759
     *
760
     * @return void
761
     */
762
    public function setDebugMode($debugMode)
763
    {
764
        $this->debugMode = $debugMode;
765
    }
766
767
    /**
768
     * Queries whether or not debug mode is enabled or not, default is TRUE.
769
     *
770
     * @return boolean TRUE if debug mode is enabled, else FALSE
771
     */
772
    public function isDebugMode()
773
    {
774
        return $this->debugMode;
775
    }
776
777
    /**
778
     * Set's the flag to signal that the an existing PID hast to be ignored, whether a
779
     * import process is running or not.
780
     *
781
     * @param boolean $ignorePid TRUE if the PID has to be ignored, else FALSE
782
     *
783
     * @return void
784
     */
785
    public function setIgnorePid($ignorePid)
786
    {
787
        $this->ignorePid = $ignorePid;
788
    }
789
790
    /**
791
     * Queries whether or not that the an existing PID has to be ignored.
792
     *
793
     * @return boolean TRUE if an existing PID has to be ignored, else FALSE
794
     */
795
    public function isIgnorePid()
796
    {
797
        return $this->ignorePid;
798
    }
799
800
    /**
801
     * Set's the log level to use.
802
     *
803
     * @param string $logLevel The log level to use
804
     *
805
     * @return void
806
     */
807
    public function setLogLevel($logLevel)
808
    {
809
        $this->logLevel = $logLevel;
810
    }
811
812
    /**
813
     * Return's the log level to use.
814
     *
815
     * @return string The log level to use
816
     */
817
    public function getLogLevel()
818
    {
819
        return $this->logLevel;
820
    }
821
}
822