Create::process()   A
last analyzed

Complexity

Conditions 2
Paths 2

Size

Total Lines 10
Code Lines 6

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 7
CRAP Score 2

Importance

Changes 0
Metric Value
cc 2
eloc 6
nc 2
nop 0
dl 0
loc 10
ccs 7
cts 7
cp 1
crap 2
rs 10
c 0
b 0
f 0
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\Taxonomies;
15
16
use Cecil\Collection\Page\Page;
17
use Cecil\Collection\Taxonomy\Collection as VocabulariesCollection;
18
use Cecil\Collection\Taxonomy\Term;
19
use Cecil\Collection\Taxonomy\Vocabulary;
20
use Cecil\Exception\RuntimeException;
21
use Cecil\Step\AbstractStep;
22
23
/**
24
 * Create taxonomies step.
25
 *
26
 * This step is responsible for creating taxonomies based on the configuration.
27
 * It initializes a collection of vocabularies for each language defined in the
28
 * configuration and collects terms from the pages' front matter.
29
 * The created vocabularies and terms are then set in the builder for further processing.
30
 */
31
class Create extends AbstractStep
32
{
33
    /** @var array */
34
    protected $vocabCollection;
35
36
    /**
37
     * {@inheritdoc}
38
     */
39 1
    public function getName(): string
40
    {
41 1
        return 'Creating taxonomies';
42
    }
43
44
    /**
45
     * {@inheritdoc}
46
     */
47 1
    public function init(array $options): void
48
    {
49 1
        if (is_dir($this->config->getPagesPath()) && $this->hasTaxonomies()) {
50 1
            $this->canProcess = true;
51
        }
52
    }
53
54
    /**
55
     * {@inheritdoc}
56
     */
57 1
    public function process(): void
58
    {
59 1
        if ($this->hasTaxonomies()) {
60 1
            $this->createVocabulariesCollection();
61 1
            $this->builder->getLogger()->info('Vocabularies collection created', ['progress' => [1, 2]]);
62 1
            $this->collectTermsFromPages();
63 1
            $this->builder->getLogger()->info('Terms collection created', ['progress' => [2, 2]]);
64
        }
65
66 1
        $this->builder->setTaxonomies($this->vocabCollection);
67
    }
68
69
    /**
70
     * Creates a collection from the vocabularies configuration.
71
     */
72 1
    protected function createVocabulariesCollection(): void
73
    {
74
        // creates a vocabularies collection for each language
75 1
        foreach ($this->config->getLanguages() as $language) {
76 1
            $this->vocabCollection[$language['code']] = new VocabulariesCollection('taxonomies');
77
            /*
78
             * Adds each vocabulary to the collection.
79
             * e.g.:
80
             * taxonomies:
81
             *   tags: tag
82
             *   categories: category
83
             *   example: disabled
84
             * -> tags, categories
85
             */
86 1
            foreach (array_keys((array) $this->config->get('taxonomies', $language['code'], false)) as $vocabulary) {
87 1
                if ($this->config->get("taxonomies.$vocabulary", $language['code'], false) == 'disabled') {
88 1
                    continue;
89
                }
90 1
                $this->vocabCollection[$language['code']]->add(new Vocabulary($vocabulary));
91
            }
92
        }
93
    }
94
95
    /**
96
     * Collects vocabularies/terms from pages front matter.
97
     */
98 1
    protected function collectTermsFromPages(): void
99
    {
100 1
        $filteredPages = $this->builder->getPages()->filter(function (Page $page) {
101 1
            return $page->getVariable('published')
102 1
                && \in_array($page->getVariable('language', $this->config->getLanguageDefault()), array_column($this->config->getLanguages(), 'code'));
103 1
        })->sortByDate();
104 1
        foreach ($filteredPages as $page) {
105 1
            $language = (string) $page->getVariable('language', $this->config->getLanguageDefault());
106
            // e.g.:tags
107 1
            foreach ($this->vocabCollection[$language] as $vocabulary) {
108 1
                $plural = $vocabulary->getId();
109
                /*
110
                 * e.g.:
111
                 * tags: Tag 1, Tag 2
112
                 */
113 1
                if ($page->hasVariable($plural)) {
114
                    // converts a string list to an array...
115 1
                    if (!\is_array($page->getVariable($plural))) {
116 1
                        $page->setVariable($plural, [$page->getVariable($plural)]);
117
                    }
118
                    // ... and removes duplicate terms
119 1
                    $page->setVariable($plural, array_unique($page->getVariable($plural)));
120
                    // adds each term to the vocabulary collection...
121 1
                    foreach ($page->getVariable($plural) as $termName) {
122 1
                        if ($termName === null) {
123
                            throw new RuntimeException(\sprintf(
124
                                'Taxonomy "%s" of "%s" can\'t be empty.',
125
                                $plural,
126
                                $page->getId()
127
                            ));
128
                        }
129
                        // e.g.: "Tag 1" -> "tags/tag-1"
130 1
                        $termId = Page::slugify($plural . '/' . (string) $termName);
131 1
                        $term = (new Term($termId))->setName((string) $termName);
132 1
                        $this->vocabCollection[$language]
133 1
                            ->get($plural)
134 1
                            ->add($term);
135
                        // ... and adds page to the term collection
136 1
                        $this->vocabCollection[$language]
137 1
                            ->get($plural)
138 1
                            ->get($termId)
139 1
                            ->add($page);
140
                    }
141
                }
142
            }
143
        }
144
    }
145
146
    /**
147
     * Checks if there is enabled taxonomies in config.
148
     */
149 1
    private function hasTaxonomies(): bool
150
    {
151 1
        $taxonomiesCount = 0;
152 1
        foreach ($this->config->getLanguages() as $language) {
153 1
            foreach (array_keys((array) $this->config->get('taxonomies')) as $vocabulary) {
154 1
                if ($this->config->get("taxonomies.$vocabulary", $language['code'], false) == 'disabled') {
155 1
                    continue;
156
                }
157 1
                $taxonomiesCount++;
158
            }
159
        }
160
161 1
        return $taxonomiesCount > 0;
162
    }
163
}
164