Completed
Push — master ( e493c9...453c86 )
by Tim
9s
created

Configuration::factory()   F

Complexity

Conditions 13
Paths 2049

Size

Total Lines 86
Code Lines 29

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 182

Importance

Changes 0
Metric Value
c 0
b 0
f 0
dl 0
loc 86
ccs 0
cts 43
cp 0
rs 2
cc 13
eloc 29
nc 2049
nop 1
crap 182

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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 JMS\Serializer\Annotation\Type;
24
use JMS\Serializer\SerializerBuilder;
25
use JMS\Serializer\Annotation\SerializedName;
26
use TechDivision\Import\ConfigurationInterface;
27
use Symfony\Component\Console\Input\InputInterface;
28
use TechDivision\Import\Cli\Command\InputOptionKeys;
29
use TechDivision\Import\Cli\Command\InputArgumentKeys;
30
use TechDivision\Import\Cli\Configuration\Operation;
31
32
/**
33
 * A simple configuration implementation.
34
 *
35
 * @author    Tim Wagner <[email protected]>
36
 * @copyright 2016 TechDivision GmbH <[email protected]>
37
 * @license   http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
38
 * @link      https://github.com/techdivision/import-cli-simple
39
 * @link      http://www.techdivision.com
40
 */
41
class Configuration implements ConfigurationInterface
42
{
43
44
    /**
45
     * The operation name to use.
46
     *
47
     * @var string
48
     * @Type("string")
49
     * @SerializedName("operation-name")
50
     */
51
    protected $operationName;
52
53
    /**
54
     * The Magento edition, EE or CE.
55
     *
56
     * @var string
57
     * @Type("string")
58
     * @SerializedName("magento-edition")
59
     */
60
    protected $magentoEdition = 'CE';
61
62
    /**
63
     * The Magento version, e. g. 2.1.0.
64
     *
65
     * @var string
66
     * @Type("string")
67
     * @SerializedName("magento-version")
68
     */
69
    protected $magentoVersion = '2.1.2';
70
71
    /**
72
     * The Magento installation directory.
73
     *
74
     * @var string
75
     * @Type("string")
76
     * @SerializedName("installation-dir")
77
     */
78
    protected $installationDir;
79
80
    /**
81
     * The source directory that has to be watched for new files.
82
     *
83
     * @var string
84
     * @Type("string")
85
     * @SerializedName("source-dir")
86
     */
87
    protected $sourceDir;
88
89
    /**
90
     * The target directory with the files that has been imported.
91
     *
92
     * @var string
93
     * @Type("string")
94
     * @SerializedName("target-dir")
95
     */
96
    protected $targetDir;
97
98
    /**
99
     * The database configuration.
100
     *
101
     * @var TechDivision\Import\Configuration\Database
102
     * @Type("TechDivision\Import\Cli\Configuration\Database")
103
     */
104
    protected $database;
105
106
    /**
107
     * ArrayCollection with the information of the configured operations.
108
     *
109
     * @var \Doctrine\Common\Collections\ArrayCollection
110
     * @Type("ArrayCollection<TechDivision\Import\Cli\Configuration\Operation>")
111
     */
112
    protected $operations;
113
114
    /**
115
     * The subject's utility class with the SQL statements to use.
116
     *
117
     * @var string
118
     * @Type("string")
119
     * @SerializedName("utility-class-name")
120
     */
121
    protected $utilityClassName;
122
123
    /**
124
     * The source date format to use in the subject.
125
     *
126
     * @var string
127
     * @Type("string")
128
     * @SerializedName("source-date-format")
129
     */
130
    protected $sourceDateFormat = 'n/d/y, g:i A';
131
132
    /**
133
     * The subject's multiple field delimiter character for fields with multiple values, defaults to (,).
134
     *
135
     * @var string
136
     * @Type("string")
137
     * @SerializedName("multiple-field-delimiter")
138
     */
139
    protected $multipleFieldDelimiter = ',';
140
141
    /**
142
     * The subject's delimiter character for CSV files.
143
     *
144
     * @var string
145
     * @Type("string")
146
     */
147
    protected $delimiter;
148
149
    /**
150
     * The subject's enclosure character for CSV files.
151
     *
152
     * @var string
153
     * @Type("string")
154
     */
155
    protected $enclosure;
156
157
    /**
158
     * The subject's escape character for CSV files.
159
     *
160
     * @var string
161
     * @Type("string")
162
     */
163
    protected $escape;
164
165
    /**
166
     * The subject's source charset for the CSV file.
167
     *
168
     * @var string
169
     * @Type("string")
170
     * @SerializedName("from-charset")
171
     */
172
    protected $fromCharset;
173
174
    /**
175
     * The subject's target charset for a CSV file.
176
     *
177
     * @var string
178
     * @Type("string")
179
     * @SerializedName("to-charset")
180
     */
181
    protected $toCharset;
182
183
    /**
184
     * The subject's file mode for a CSV target file.
185
     *
186
     * @var string
187
     * @Type("string")
188
     * @SerializedName("file-mode")
189
     */
190
    protected $fileMode;
191
192
    /**
193
     * The flag to signal that the subject has to use the strict mode or not.
194
     *
195
     * @var boolean
196
     * @Type("boolean")
197
     * @SerializedName("strict-mode")
198
     */
199
    protected $strictMode;
200
201
    /**
202
     * Factory implementation to create a new initialized configuration instance.
203
     *
204
     * If command line options are specified, they will always override the
205
     * values found in the configuration file.
206
     *
207
     * @param \Symfony\Component\Console\Input\InputInterface $input The Symfony console input instance
208
     *
209
     * @return \TechDivision\Import\Cli\Configuration The configuration instance
210
     * @throws \Exception Is thrown, if the specified configuration file doesn't exist
211
     */
212
    public static function factory(InputInterface $input)
213
    {
214
215
        // load the configuration filename we want to use
216
        $filename = $input->getOption(InputOptionKeys::CONFIGURATION);
217
218
        // load the JSON data
219
        if (!$jsonData = file_get_contents($filename)) {
220
            throw new \Exception('Can\'t load configuration file $filename');
221
        }
222
223
        // initialize the JMS serializer and load the configuration
224
        $serializer = SerializerBuilder::create()->build();
225
        /** @var \TechDivision\Import\Cli\Configuration $instance */
226
        $instance = $serializer->deserialize($jsonData, 'TechDivision\Import\Cli\Configuration', 'json');
227
228
        // query whether or not an operation name has been specified as command line
229
        // option, if yes override the value from the configuration file
230
        if ($operationName = $input->getArgument(InputArgumentKeys::OPERATION_NAME)) {
231
            $instance->setOperationName($operationName);
232
        }
233
234
        // query whether or not a Magento installation directory has been specified as command line
235
        // option, if yes override the value from the configuration file
236
        if ($installationDir = $input->getOption(InputOptionKeys::INSTALLATION_DIR)) {
237
            $instance->setInstallationDir($installationDir);
238
        }
239
240
        // query whether or not a directory for the source files has been specified as command line
241
        // option, if yes override the value from the configuration file
242
        if ($sourceDir = $input->getOption(InputOptionKeys::SOURCE_DIR)) {
243
            $instance->setSourceDir($sourceDir);
244
        }
245
246
        // query whether or not a directory containing the imported files has been specified as command line
247
        // option, if yes override the value from the configuration file
248
        if ($targetDir = $input->getOption(InputOptionKeys::TARGET_DIR)) {
249
            $instance->setTargetDir($targetDir);
250
        }
251
252
        // query whether or not a source date format has been specified as command
253
        // line  option, if yes override the value from the configuration file
254
        if ($sourceDateFormat = $input->getOption(InputOptionKeys::SOURCE_DATE_FORMAT)) {
255
            $instance->setSourceDateFormat($sourceDateFormat);
256
        }
257
258
        // query whether or not a Magento edition has been specified as command line
259
        // option, if yes override the value from the configuration file
260
        if ($magentoEdition = $input->getOption(InputOptionKeys::MAGENTO_EDITION)) {
261
            $instance->setMagentoEdition($magentoEdition);
262
        }
263
264
        // query whether or not a Magento version has been specified as command line
265
        // option, if yes override the value from the configuration file
266
        if ($magentoVersion = $input->getOption(InputOptionKeys::MAGENTO_VERSION)) {
267
            $instance->setMagentoVersion($magentoVersion);
268
        }
269
270
        // query whether or not a PDO DSN has been specified as command line
271
        // option, if yes override the value from the configuration file
272
        if ($dsn = $input->getOption(InputOptionKeys::DB_PDO_DSN)) {
273
            $instance->getDatabase()->setDsn($dsn);
274
        }
275
276
        // query whether or not a DB username has been specified as command line
277
        // option, if yes override the value from the configuration file
278
        if ($username = $input->getOption(InputOptionKeys::DB_USERNAME)) {
279
            $instance->getDatabase()->setUsername($username);
280
        }
281
282
        // query whether or not a DB password has been specified as command line
283
        // option, if yes override the value from the configuration file
284
        if ($password = $input->getOption(InputOptionKeys::DB_PASSWORD)) {
285
            $instance->getDatabase()->setPassword($password);
286
        }
287
288
        // extend the subjects with the parent configuration instance
289
        /** @var \TechDivision\Import\Cli\Configuration\Subject $subject */
290
        foreach ($instance->getSubjects() as $subject) {
291
            // set the configuration instance on the subject
292
            $subject->setConfiguration($instance);
293
        }
294
295
        // return the initialized configuration instance
296
        return $instance;
297
    }
298
299
    /**
300
     * Return's the array with the subjects of the operation to use.
301
     *
302
     * @return \Doctrine\Common\Collections\ArrayCollection The ArrayCollection with the subjects
303
     * @throws \Exception Is thrown, if no subjects are available for the actual operation
304
     */
305
    public function getSubjects()
306
    {
307
308
        // iterate over the operations and return the subjects of the actual one
309
        /** @var TechDivision\Import\Configuration\OperationInterface $operation */
310
        foreach ($this->getOperations() as $operation) {
311
            if ($this->getOperation()->equals($operation)) {
312
                return $operation->getSubjects();
313
            }
314
        }
315
316
        // throw an exception if no subjects are available
317
        throw new \Exception(sprintf('Can\'t find any subjects for operation %s', $this->getOperation()));
318
    }
319
320
    /**
321
     * Return's the operation, initialize from the actual operation name.
322
     *
323
     * @return \TechDivision\Import\Configuration\OperationInterface The operation instance
324
     */
325
    protected function getOperation()
326
    {
327
        return new Operation($this->getOperationName());
328
    }
329
330
    /**
331
     * Return's the operation name that has to be used.
332
     *
333
     * @param string $operationName The operation name that has to be used
334
     *
335
     * @return void
336
     */
337
    public function setOperationName($operationName)
338
    {
339
        return $this->operationName = $operationName;
340
    }
341
342
    /**
343
     * Return's the operation name that has to be used.
344
     *
345
     * @return string The operation name that has to be used
346
     */
347
    public function getOperationName()
348
    {
349
        return $this->operationName;
350
    }
351
352
    /**
353
     * Set's the Magento installation directory.
354
     *
355
     * @param string $installationDir The Magento installation directory
356
     *
357
     * @return void
358
     */
359
    public function setInstallationDir($installationDir)
360
    {
361
        $this->installationDir = $installationDir;
362
    }
363
364
    /**
365
     * Return's the Magento installation directory.
366
     *
367
     * @return string The Magento installation directory
368
     */
369
    public function getInstallationDir()
370
    {
371
        return $this->installationDir;
372
    }
373
374
    /**
375
     * Set's the source directory that has to be watched for new files.
376
     *
377
     * @param string $sourceDir The source directory
378
     *
379
     * @return void
380
     */
381
    public function setSourceDir($sourceDir)
382
    {
383
        $this->sourceDir = $sourceDir;
384
    }
385
386
    /**
387
     * Return's the source directory that has to be watched for new files.
388
     *
389
     * @return string The source directory
390
     */
391
    public function getSourceDir()
392
    {
393
        return $this->sourceDir;
394
    }
395
396
    /**
397
     * Return's the target directory with the files that has been imported.
398
     *
399
     * @return string The target directory
400
     */
401
    public function getTargetDir()
402
    {
403
        return $this->targetDir;
404
    }
405
406
    /**
407
     * Set's the target directory with the files that has been imported.
408
     *
409
     * @param string $targetDir The target directory
410
     *
411
     * @return void
412
     */
413
    public function setTargetDir($targetDir)
414
    {
415
        $this->targetDir = $targetDir;
416
    }
417
418
    /**
419
     * Return's the utility class with the SQL statements to use.
420
     *
421
     * @param string $utilityClassName The utility class name
422
     *
423
     * @return void
424
     */
425
    public function setUtilityClassName($utilityClassName)
426
    {
427
        return $this->utilityClassName = $utilityClassName;
428
    }
429
430
    /**
431
     * Return's the utility class with the SQL statements to use.
432
     *
433
     * @return string The utility class name
434
     */
435
    public function getUtilityClassName()
436
    {
437
        return $this->utilityClassName;
438
    }
439
440
    /**
441
     * Set's the Magento edition, EE or CE.
442
     *
443
     * @param string $magentoEdition The Magento edition
444
     *
445
     * @return void
446
     */
447
    public function setMagentoEdition($magentoEdition)
448
    {
449
        $this->magentoEdition = $magentoEdition;
450
    }
451
452
    /**
453
     * Return's the Magento edition, EE or CE.
454
     *
455
     * @return string The Magento edition
456
     */
457
    public function getMagentoEdition()
458
    {
459
        return $this->magentoEdition;
460
    }
461
462
    /**
463
     * Return's the Magento version, e. g. 2.1.0.
464
     *
465
     * @param string $magentoVersion The Magento version
466
     *
467
     * @return void
468
     */
469
    public function setMagentoVersion($magentoVersion)
470
    {
471
        $this->magentoVersion = $magentoVersion;
472
    }
473
474
    /**
475
     * Return's the Magento version, e. g. 2.1.0.
476
     *
477
     * @return string The Magento version
478
     */
479
    public function getMagentoVersion()
480
    {
481
        return $this->magentoVersion;
482
    }
483
484
    /**
485
     * Return's the subject's source date format to use.
486
     *
487
     * @return string The source date format
488
     */
489
    public function getSourceDateFormat()
490
    {
491
        return $this->sourceDateFormat;
492
    }
493
494
    /**
495
     * Set's the subject's source date format to use.
496
     *
497
     * @param string $sourceDateFormat The source date format
498
     *
499
     * @return void
500
     */
501
    public function setSourceDateFormat($sourceDateFormat)
502
    {
503
        $this->sourceDateFormat = $sourceDateFormat;
504
    }
505
506
    /**
507
     * Return's the multiple field delimiter character to use, default value is comma (,).
508
     *
509
     * @return string The multiple field delimiter character
510
     */
511
    public function getMultipleFieldDelimiter()
512
    {
513
        return $this->multipleFieldDelimiter;
514
    }
515
516
    /**
517
     * Return's the delimiter character to use, default value is comma (,).
518
     *
519
     * @return string The delimiter character
520
     */
521
    public function getDelimiter()
522
    {
523
        return $this->delimiter;
524
    }
525
526
    /**
527
     * The enclosure character to use, default value is double quotation (").
528
     *
529
     * @return string The enclosure character
530
     */
531
    public function getEnclosure()
532
    {
533
        return $this->enclosure;
534
    }
535
536
    /**
537
     * The escape character to use, default value is backslash (\).
538
     *
539
     * @return string The escape character
540
     */
541
    public function getEscape()
542
    {
543
        return $this->escape;
544
    }
545
546
    /**
547
     * The file encoding of the CSV source file, default value is UTF-8.
548
     *
549
     * @return string The charset used by the CSV source file
550
     */
551
    public function getFromCharset()
552
    {
553
        return $this->fromCharset;
554
    }
555
556
    /**
557
     * The file encoding of the CSV targetfile, default value is UTF-8.
558
     *
559
     * @return string The charset used by the CSV target file
560
     */
561
    public function getToCharset()
562
    {
563
        return $this->toCharset;
564
    }
565
566
    /**
567
     * The file mode of the CSV target file, either one of write or append, default is write.
568
     *
569
     * @return string The file mode of the CSV target file
570
     */
571
    public function getFileMode()
572
    {
573
        return $this->fileMode;
574
    }
575
576
    /**
577
     * Queries whether or not strict mode is enabled or not, default is TRUE.
578
     *
579
     * @return boolean TRUE if strict mode is enabled, else FALSE
580
     */
581
    public function isStrictMode()
582
    {
583
        return $this->strictMode;
584
    }
585
586
    /**
587
     * Return's the database configuration.
588
     *
589
     * @return \TechDivision\Import\Cli\Configuration\Database The database configuration
590
     */
591
    public function getDatabase()
592
    {
593
        return $this->database;
0 ignored issues
show
Bug Best Practice introduced by
The return type of return $this->database; (TechDivision\Import\Cli\...\Configuration\Database) is incompatible with the return type declared by the interface TechDivision\Import\Conf...nInterface::getDatabase of type TechDivision\Import\Tech...\Configuration\Database.

If you return a value from a function or method, it should be a sub-type of the type that is given by the parent type f.e. an interface, or abstract method. This is more formally defined by the Lizkov substitution principle, and guarantees that classes that depend on the parent type can use any instance of a child type interchangably. This principle also belongs to the SOLID principles for object oriented design.

Let’s take a look at an example:

class Author {
    private $name;

    public function __construct($name) {
        $this->name = $name;
    }

    public function getName() {
        return $this->name;
    }
}

abstract class Post {
    public function getAuthor() {
        return 'Johannes';
    }
}

class BlogPost extends Post {
    public function getAuthor() {
        return new Author('Johannes');
    }
}

class ForumPost extends Post { /* ... */ }

function my_function(Post $post) {
    echo strtoupper($post->getAuthor());
}

Our function my_function expects a Post object, and outputs the author of the post. The base class Post returns a simple string and outputting a simple string will work just fine. However, the child class BlogPost which is a sub-type of Post instead decided to return an object, and is therefore violating the SOLID principles. If a BlogPost were passed to my_function, PHP would not complain, but ultimately fail when executing the strtoupper call in its body.

Loading history...
594
    }
595
596
    /**
597
     * Return's the ArrayCollection with the configured operations.
598
     *
599
     * @return \Doctrine\Common\Collections\ArrayCollection The ArrayCollection with the operations
600
     */
601
    public function getOperations()
602
    {
603
        return $this->operations;
604
    }
605
}
606