Completed
Push — feature-data-loader ( e79fec )
by Arnaud
02:53
created

DataLoad::process()   B

Complexity

Conditions 8
Paths 12

Size

Total Lines 71

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
dl 0
loc 71
rs 7.3882
c 0
b 0
f 0
cc 8
nc 12
nop 0

How to fix   Long Method   

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
 * Copyright (c) Arnaud Ligny <[email protected]>
4
 *
5
 * For the full copyright and license information, please view the LICENSE
6
 * file that was distributed with this source code.
7
 */
8
9
namespace Cecil\Step;
10
11
use Symfony\Component\Finder\Finder;
12
use Symfony\Component\Serializer\Encoder\JsonEncoder;
13
use Symfony\Component\Serializer\Encoder\XmlEncoder;
14
use Symfony\Component\Serializer\Encoder\YamlEncoder;
15
use Symfony\Component\Serializer\Encoder\CsvEncoder;
16
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
17
use Symfony\Component\Serializer\Serializer;
18
use Symfony\Component\Yaml\Yaml;
19
20
/**
21
 * Load data files.
22
 */
23
class DataLoad extends AbstractStep
24
{
25
    /**
26
     * {@inheritdoc}
27
     */
28
    public function init($options)
29
    {
30
        if (is_dir($this->builder->getConfig()->getDataPath())) {
31
            $this->process = true;
32
        }
33
    }
34
35
    /**
36
     * {@inheritdoc}
37
     */
38
    public function process()
39
    {
40
        call_user_func_array($this->builder->getMessageCb(), ['DATA', 'Loading data']);
41
42
        $data = Finder::create()
43
            ->files()
44
            ->in($this->builder->getConfig()->getDataPath())
45
            ->name('/\.('.implode('|', $this->builder->getConfig()->get('data.ext')).')$/')
46
            ->sortByName(true);
47
        $max = count($data);
48
        $count = 0;
49
50
        // JSON
51
        $serializerJson = new Serializer([new ObjectNormalizer()], [new JsonEncoder()]);
52
        // XML
53
        $serializerXml = new Serializer([new ObjectNormalizer()], [new XmlEncoder()]);
54
        // YAML
55
        $serializerYaml = new Serializer([new ObjectNormalizer()], [new YamlEncoder()]);
56
        // CSV
57
        $serializerCsv = new Serializer([new ObjectNormalizer()], [new CsvEncoder()]);
58
59
        /* @var $file \Symfony\Component\Finder\SplFileInfo */
60
        foreach ($data as $file) {
61
            $count++;
62
            set_error_handler(
63
                function ($severity, $message, $file, $line) {
64
                    throw new \ErrorException($message, 0, $severity, $file, $line, null);
65
                }
66
            );
67
            $dataFile = $file->getContents();
68
            restore_error_handler();
69
70
            switch ($file->getExtension()) {
71
                case 'json':
72
                    $dataArray = $serializerJson->decode($dataFile, 'json');
73
                    break;
74
                case 'xml':
75
                    $dataArray = $serializerXml->decode($dataFile, 'xml');
76
                    break;
77
                case 'yml':
78
                case 'yaml':
79
                    $dataArray = $serializerYaml->decode($dataFile, 'yaml');
80
                    break;
81
                case 'csv':
82
                    $dataArray = $serializerCsv->decode($dataFile, 'csv');
83
                    break;
84
                default:
85
                    return;
86
                    break;
0 ignored issues
show
Unused Code introduced by
break is not strictly necessary here and could be removed.

The break statement is not necessary if it is preceded for example by a return statement:

switch ($x) {
    case 1:
        return 'foo';
        break; // This break is not necessary and can be left off.
}

If you would like to keep this construct to be consistent with other case statements, you can safely mark this issue as a false-positive.

Loading history...
87
            }
88
89
            $basename = $file->getBasename('.'.$file->getExtension());
90
            $subpath = \Cecil\Util::getFS()->makePathRelative(
91
                $file->getPath(),
92
                $this->builder->getConfig()->getDataPath()
93
            );
94
            $subpath = trim($subpath, './');
95
            $array = [];
96
            $path = $subpath ? $subpath.'/'.$basename : $basename;
97
            $this->pathToArray($array, $path, $dataArray);
98
99
            $dataArray = array_merge_recursive(
100
                $this->builder->getData(),
101
                $array
102
            );
103
            $this->builder->setData($dataArray);
104
105
            $message = sprintf('"%s" loaded', $path);
106
            call_user_func_array($this->builder->getMessageCb(), ['DATA_PROGRESS', $message, $count, $max]);
107
        }
108
    }
109
110
    private function pathToArray(&$arr, $path, $value, $separator = '/')
111
    {
112
        $keys = explode($separator, $path);
113
114
        foreach ($keys as $key) {
115
            $arr = &$arr[$key];
116
        }
117
118
        $arr = $value;
119
    }
120
}
121