Passed
Push — feat/content_to_pages ( 41bab6 )
by Arnaud
03:44
created

Load::init()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 4
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 2
c 0
b 0
f 0
nc 2
nop 1
dl 0
loc 4
rs 10
1
<?php
2
3
declare(strict_types=1);
4
5
/*
6
 * This file is part of Cecil.
7
 *
8
 * Copyright (c) Arnaud Ligny <[email protected]>
9
 *
10
 * For the full copyright and license information, please view the LICENSE
11
 * file that was distributed with this source code.
12
 */
13
14
namespace Cecil\Step\Data;
15
16
use Cecil\Step\AbstractStep;
17
use Cecil\Util;
18
use Symfony\Component\Finder\Finder;
19
use Symfony\Component\Serializer\Encoder\CsvEncoder;
20
use Symfony\Component\Serializer\Encoder\JsonEncoder;
21
use Symfony\Component\Serializer\Encoder\XmlEncoder;
22
use Symfony\Component\Serializer\Encoder\YamlEncoder;
23
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
24
use Symfony\Component\Serializer\Serializer;
25
26
/**
27
 * Loads data files.
28
 */
29
class Load extends AbstractStep
30
{
31
    /**
32
     * {@inheritdoc}
33
     */
34
    public function getName(): string
35
    {
36
        return 'Loading data';
37
    }
38
39
    /**
40
     * {@inheritdoc}
41
     */
42
    public function init(array $options): void
43
    {
44
        if (is_dir($this->builder->getConfig()->getDataPath()) && (bool) $this->config->get('data.load')) {
45
            $this->canProcess = true;
46
        }
47
    }
48
49
    /**
50
     * {@inheritdoc}
51
     */
52
    public function process(): void
53
    {
54
        $files = Finder::create()
55
            ->files()
56
            ->in($this->builder->getConfig()->getDataPath())
57
            ->name('/\.('.implode('|', (array) $this->builder->getConfig()->get('data.ext')).')$/')
58
            ->sortByName(true);
59
        $max = count($files);
60
61
        if ($max <= 0) {
62
            $message = 'No files';
63
            $this->builder->getLogger()->info($message);
64
65
            return;
66
        }
67
68
        $serializerYaml = new Serializer([new ObjectNormalizer()], [new YamlEncoder()]);
69
        $serializerJson = new Serializer([new ObjectNormalizer()], [new JsonEncoder()]);
70
        $serializerCsv = new Serializer([new ObjectNormalizer()], [new CsvEncoder()]);
71
        $serializerXml = new Serializer([new ObjectNormalizer()], [new XmlEncoder()]);
72
        $count = 0;
73
74
        /** @var \Symfony\Component\Finder\SplFileInfo $file */
75
        foreach ($files as $file) {
76
            $count++;
77
            set_error_handler(
78
                function ($severity, $message, $file, $line) {
79
                    throw new \ErrorException($message, 0, $severity, $file, $line, null);
80
                }
81
            );
82
            $data = $file->getContents();
83
            restore_error_handler();
84
85
            switch ($file->getExtension()) {
86
                case 'yml':
87
                case 'yaml':
88
                    $dataArray = $serializerYaml->decode($data, 'yaml');
89
                    break;
90
                case 'json':
91
                    $dataArray = $serializerJson->decode($data, 'json');
92
                    break;
93
                case 'csv':
94
                    $dataArray = $serializerCsv->decode($data, 'csv');
95
                    break;
96
                case 'xml':
97
                    $dataArray = $serializerXml->decode($data, 'xml');
98
                    break;
99
                default:
100
                    return;
101
            }
102
103
            $basename = $file->getBasename('.'.$file->getExtension());
104
            $subpath = \Cecil\Util\File::getFS()->makePathRelative(
105
                $file->getPath(),
106
                $this->builder->getConfig()->getDataPath()
107
            );
108
            $subpath = trim($subpath, './');
109
            $array = [];
110
            $path = !empty($subpath) ? Util::joinFile($subpath, $basename) : $basename;
111
            $this->pathToArray($array, $path, $dataArray);
112
113
            $dataArray = array_merge_recursive(
114
                $this->builder->getData(),
115
                $array
116
            );
117
            $this->builder->setData($dataArray);
118
119
            $message = \sprintf('File "%s.%s" loaded', Util::joinFile($path), $file->getExtension());
120
            $this->builder->getLogger()->info($message, ['progress' => [$count, $count]]);
121
        }
122
    }
123
124
    /**
125
     * Converts a path to an array.
126
     *
127
     * @param array  $arr       Target array
128
     * @param string $path      Source path
129
     * @param array  $value     Source values
130
     * @param string $separator Separator (ie: /)
131
     */
132
    private function pathToArray(array &$arr, string $path, array $value, string $separator = DIRECTORY_SEPARATOR): void
133
    {
134
        $keys = explode($separator, $path);
135
136
        foreach ($keys as $key) {
137
            $arr = &$arr[$key];
138
        }
139
140
        $arr = $value;
141
    }
142
}
143