• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Cecilapp / Cecil / 17554979347

08 Sep 2025 02:56PM UTC coverage: 81.757% (-0.03%) from 81.783%
17554979347

push

github

ArnaudLigny
feat: load data of themes

8 of 10 new or added lines in 1 file covered. (80.0%)

3164 of 3870 relevant lines covered (81.76%)

0.82 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

89.39
/src/Step/Data/Load.php
1
<?php
2

3
/**
4
 * This file is part of Cecil.
5
 *
6
 * (c) Arnaud Ligny <arnaud@ligny.fr>
7
 *
8
 * For the full copyright and license information, please view the LICENSE
9
 * file that was distributed with this source code.
10
 */
11

12
declare(strict_types=1);
13

14
namespace Cecil\Step\Data;
15

16
use Cecil\Collection\Page\PrefixSuffix;
17
use Cecil\Step\AbstractStep;
18
use Cecil\Util;
19
use Symfony\Component\Finder\Finder;
20
use Symfony\Component\Serializer\Encoder\CsvEncoder;
21
use Symfony\Component\Serializer\Encoder\JsonEncoder;
22
use Symfony\Component\Serializer\Encoder\XmlEncoder;
23
use Symfony\Component\Serializer\Encoder\YamlEncoder;
24
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
25
use Symfony\Component\Serializer\Serializer;
26

27
/**
28
 * Load step class.
29
 *
30
 * This class is responsible for loading data files from a specified directory,
31
 * decoding their contents based on the file extension, and merging the data
32
 * into the builder's data collection. It supports various file formats such as
33
 * YAML, JSON, CSV, and XML. The loaded data is organized into a nested array
34
 * structure based on the file paths and language suffixes.
35
 */
36
class Load extends AbstractStep
37
{
38
    /**
39
     * {@inheritdoc}
40
     */
41
    public function getName(): string
42
    {
43
        return 'Loading data';
1✔
44
    }
45

46
    /**
47
     * {@inheritdoc}
48
     */
49
    public function init(array $options): void
50
    {
51
        if (is_dir($this->config->getDataPath()) && $this->config->isEnabled('data.load')) {
1✔
52
            $this->canProcess = true;
1✔
53
        }
54
    }
55

56
    /**
57
     * {@inheritdoc}
58
     */
59
    public function process(): void
60
    {
61
        $files = Finder::create()
1✔
62
            ->files()
1✔
63
            ->in($this->config->getDataPath())
1✔
64
            ->name('/\.(' . implode('|', (array) $this->config->get('data.ext')) . ')$/')
1✔
65
            ->sortByName(true);
1✔
66

67
        if ($this->config->hasTheme()) {
1✔
68
            $themes = $this->config->getTheme();
1✔
69
            foreach ($themes ?? [] as $theme) {
1✔
70
                if (Util\File::getFS()->exists($this->config->getThemeDirPath($theme, 'data'))) {
1✔
NEW
71
                    $files->in($this->config->getThemeDirPath($theme, 'data'));
×
72
                }
73
            }
74
        }
75

76
        $total = \count($files);
1✔
77

78
        if ($total < 1) {
1✔
79
            $message = 'No files';
×
80
            $this->builder->getLogger()->info($message);
×
81

82
            return;
×
83
        }
84

85
        $serializerYaml = new Serializer([new ObjectNormalizer()], [new YamlEncoder()]);
1✔
86
        $serializerJson = new Serializer([new ObjectNormalizer()], [new JsonEncoder()]);
1✔
87
        $serializerCsv = new Serializer([new ObjectNormalizer()], [new CsvEncoder()]);
1✔
88
        $serializerXml = new Serializer([new ObjectNormalizer()], [new XmlEncoder()]);
1✔
89
        $count = 0;
1✔
90

91
        /** @var \Symfony\Component\Finder\SplFileInfo $file */
92
        foreach ($files as $file) {
1✔
93
            $count++;
1✔
94
            set_error_handler(
1✔
95
                function ($severity, $message, $file, $line) {
1✔
96
                    throw new \ErrorException($message, 0, $severity, $file, $line, null);
×
97
                }
1✔
98
            );
1✔
99
            $data = $file->getContents();
1✔
100
            restore_error_handler();
1✔
101

102
            switch ($file->getExtension()) {
1✔
103
                case 'yml':
1✔
104
                case 'yaml':
1✔
105
                    $dataAsArray = $serializerYaml->decode($data, 'yaml');
1✔
106
                    break;
1✔
107
                case 'json':
1✔
108
                    $dataAsArray = $serializerJson->decode($data, 'json');
1✔
109
                    break;
1✔
110
                case 'csv':
1✔
111
                    $dataAsArray = $serializerCsv->decode($data, 'csv');
1✔
112
                    break;
1✔
113
                case 'xml':
1✔
114
                    $dataAsArray = $serializerXml->decode($data, 'xml');
1✔
115
                    break;
1✔
116
                default:
117
                    return;
×
118
            }
119

120
            $lang = $this->config->getLanguageDefault();
1✔
121
            if (PrefixSuffix::hasSuffix($file->getFilenameWithoutExtension())) {
1✔
NEW
122
                $lang = PrefixSuffix::getSuffix($file->getFilenameWithoutExtension());
×
123
            }
124
            $array = [];
1✔
125
            $path = Util::joinFile(pathinfo($file->getRelativePathname(), PATHINFO_DIRNAME), pathinfo($file->getRelativePathname(), PATHINFO_FILENAME));
1✔
126
            $path = trim($path, './');
1✔
127
            $localizedPath = Util::joinFile((string) $lang, PrefixSuffix::sub($path));
1✔
128
            $this->pathToArray($array, $localizedPath, $dataAsArray);
1✔
129

130
            $dataAsArray = array_merge_recursive(
1✔
131
                $this->builder->getData(),
1✔
132
                $array
1✔
133
            );
1✔
134
            $this->builder->setData($dataAsArray);
1✔
135

136
            $message = \sprintf('File "%s" loaded', $file->getRelativePathname());
1✔
137
            $this->builder->getLogger()->info($message, ['progress' => [$count, $total]]);
1✔
138
        }
139
    }
140

141
    /**
142
     * Puts a path/value couple into an array.
143
     *
144
     * @param array  $arr       Target array
145
     * @param string $path      Source path
146
     * @param array  $value     Source values
147
     * @param string $separator Path separator (ie: '/')
148
     */
149
    private function pathToArray(array &$arr, string $path, array $value, string $separator = DIRECTORY_SEPARATOR): void
150
    {
151
        $keys = explode($separator, $path);
1✔
152
        foreach ($keys as $key) {
1✔
153
            $arr = &$arr[$key];
1✔
154
        }
155
        $arr = $value;
1✔
156
    }
157
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc