Passed
Pull Request — master (#1711)
by Arnaud
08:22 queued 03:22
created

Create   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 129
Duplicated Lines 0 %

Test Coverage

Coverage 90.91%

Importance

Changes 5
Bugs 1 Features 1
Metric Value
eloc 50
c 5
b 1
f 1
dl 0
loc 129
ccs 50
cts 55
cp 0.9091
rs 10
wmc 22

6 Methods

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