Passed
Push — nested-sections-2025 ( 6db02a...4b7e82 )
by Arnaud
04:09
created

Load   A

Complexity

Total Complexity 21

Size/Duplication

Total Lines 98
Duplicated Lines 0 %

Test Coverage

Coverage 62.74%

Importance

Changes 1
Bugs 0 Features 0
Metric Value
eloc 53
c 1
b 0
f 0
dl 0
loc 98
ccs 32
cts 51
cp 0.6274
rs 10
wmc 21

3 Methods

Rating   Name   Duplication   Size   Complexity  
A init() 0 11 2
A getName() 0 3 1
D process() 0 66 18
1
<?php
2
3
/**
4
 * This file is part of Cecil.
5
 *
6
 * (c) Arnaud Ligny <[email protected]>
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\Pages;
15
16
use Cecil\Step\AbstractStep;
17
use Cecil\Util;
18
use Symfony\Component\Finder\Finder;
19
use Symfony\Component\Finder\SplFileInfo;
20
21
/**
22
 * Load pages step.
23
 *
24
 * This step is responsible for loading pages from the configured pages directory.
25
 * It initializes the pages finder, applies sorting, and filters based on the
26
 * specified page or the default configuration. It also handles exclusions and
27
 * respects the `.gitignore` file if present. The loaded pages are then set in
28
 * the builder for further processing.
29
 */
30
class Load extends AbstractStep
31
{
32
    /** @var string */
33
    protected $page;
34
35
    /**
36
     * {@inheritdoc}
37
     */
38 1
    public function getName(): string
39
    {
40 1
        return 'Loading pages';
41
    }
42
43
    /**
44
     * {@inheritdoc}
45
     */
46 1
    public function init(array $options): void
47
    {
48 1
        if (!is_dir($this->config->getPagesPath())) {
49
            $this->builder->getLogger()->debug(\sprintf('"%s" is not a valid pages directory', $this->config->getPagesPath()));
50
            $this->canProcess = false;
51
52
            return;
53
        }
54
55 1
        $this->page = $options['page'];
56 1
        $this->canProcess = true;
57
    }
58
59
    /**
60
     * {@inheritdoc}
61
     */
62 1
    public function process(): void
63
    {
64 1
        $namePattern = '/\.(' . implode('|', (array) $this->config->get('pages.ext')) . ')$/';
65 1
        $pages = Finder::create()
66 1
            ->files()
67 1
            ->in($this->config->getPagesPath())
68 1
            ->sort(function (SplFileInfo $a, SplFileInfo $b): int {
69
                // root pages first
70 1
                if (empty($a->getRelativePath()) && !empty($b->getRelativePath())) {
71 1
                    return -1;
72
                }
73 1
                if (empty($b->getRelativePath()) && !empty($a->getRelativePath())) {
74 1
                    return 1;
75
                }
76
                // section's index first
77 1
                if ($a->getRelativePath() == $b->getRelativePath() && in_array(strtolower($a->getFilenameWithoutExtension()), ['index', 'readme'])) {
78 1
                    return -1;
79
                }
80 1
                if ($b->getRelativePath() == $a->getRelativePath() && in_array(strtolower($b->getFilenameWithoutExtension()), ['index', 'readme'])) {
81
                    return 1;
82
                }
83
                // sort by name
84
                return strnatcasecmp($a->getRelativePath(), $b->getRelativePath());
85
            });
86
        // load only one page?
87
        if ($this->page) {
88
            // is the page path starts with the `pages.dir` configuration option?
89
            // (i.e.: `pages/...`, `/pages/...`, `./pages/...`)
90
            $pagePathAsArray = explode(DIRECTORY_SEPARATOR, Util::joinFile($this->page));
91
            if ($pagePathAsArray[0] == (string) $this->config->get('pages.dir')) {
92
                unset($pagePathAsArray[0]);
93
                $this->page = implode(DIRECTORY_SEPARATOR, $pagePathAsArray);
94
            }
95
            if ($pagePathAsArray[0] == '.' && $pagePathAsArray[1] == (string) $this->config->get('pages.dir')) {
96
                unset($pagePathAsArray[0]);
97
                unset($pagePathAsArray[1]);
98
                $this->page = implode(DIRECTORY_SEPARATOR, $pagePathAsArray);
99
            }
100 1
            if (!util\File::getFS()->exists(Util::joinFile($this->config->getPagesPath(), $this->page))) {
101 1
                $this->builder->getLogger()->error(\sprintf('File "%s" doesn\'t exist.', $this->page));
102 1
            }
103 1
            $pages->path('.')->path(\dirname($this->page));
104 1
            $pages->name('/index\.(' . implode('|', (array) $this->config->get('pages.ext')) . ')$/');
105
            $namePattern = basename($this->page);
106 1
        }
107
        $pages->name($namePattern);
108
        if (\is_array($exclude = $this->config->get('pages.exclude'))) {
109 1
            $pages->exclude($exclude);
110
            $pages->notPath($exclude);
111 1
            $pages->notName($exclude);
112 1
        }
113 1
        if (file_exists(Util::joinFile($this->config->getPagesPath(), '.gitignore'))) {
114
            $pages->ignoreVCSIgnored(true);
115
        }
116
        $this->builder->setPagesFiles($pages);
117
118 1
        $total = $pages->count();
119 1
        $count = 0;
120 1
        if ($total === 0) {
121
            $this->builder->getLogger()->info('Nothing to load');
122
123
            return;
124
        }
125
        foreach ($pages as $file) {
126
            $count++;
127
            $this->builder->getLogger()->info(\sprintf('File "%s" loaded', $file->getRelativePathname()), ['progress' => [$count, $total]]);
128
        }
129
    }
130
}
131