Passed
Pull Request — master (#1704)
by Arnaud
08:53 queued 03:28
created

Section   A

Complexity

Total Complexity 30

Size/Duplication

Total Lines 161
Duplicated Lines 0 %

Test Coverage

Coverage 96.67%

Importance

Changes 4
Bugs 2 Features 0
Metric Value
eloc 83
dl 0
loc 161
ccs 87
cts 90
cp 0.9667
rs 10
c 4
b 2
f 0
wmc 30

3 Methods

Rating   Name   Duplication   Size   Complexity  
F generate() 0 78 17
A sortSubPages() 0 28 3
B addNavigationLinks() 0 38 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\Generator;
15
16
use Cecil\Collection\Page\Collection as PagesCollection;
17
use Cecil\Collection\Page\Page;
18
use Cecil\Collection\Page\Type;
19
use Cecil\Exception\RuntimeException;
20
21
/**
22
 * Class Generator\Section.
23
 */
24
class Section extends AbstractGenerator implements GeneratorInterface
25
{
26
    /**
27
     * {@inheritdoc}
28
     */
29 1
    public function generate(): void
30
    {
31 1
        $sections = [];
32
33
        // identifying sections from all pages
34
        /** @var Page $page */
35 1
        foreach ($this->builder->getPages() as $page) {
36
            // top level (root) sections
37 1
            if ($page->getSection()) {
38
                // do not add "not published" and "not excluded" pages to its section
39 1
                if ($page->getVariable('published') !== true || $page->getVariable('exclude')) {
40 1
                    continue;
41
                }
42 1
                $sections[$page->getSection()][$page->getVariable('language', $this->config->getLanguageDefault())][] = $page;
43
44
                // DEBUG
45 1
                if ($page->getParent() !== null) {
46 1
                    dump([
47 1
                        'pid'  => $page->getId(),
48 1
                        'ppid' => $page->getParent()->getId()
49 1
                    ]);
50
                    //$sections[$page->getParent()->getId()][$page->getVariable('language', $this->config->getLanguageDefault())][] = $page;
51
                }
52
            }
53
        }
54
55
        // adds each section to pages collection
56 1
        if (\count($sections) > 0) {
57 1
            $menuWeight = 100;
58
59 1
            foreach ($sections as $section => $languages) {
60 1
                foreach ($languages as $language => $pagesAsArray) {
61 1
                    $pageId = $path = Page::slugify($section);
62 1
                    if ($language != $this->config->getLanguageDefault()) {
63 1
                        $pageId = "$language/$pageId";
64
                    }
65 1
                    $page = (new Page($pageId))->setVariable('title', ucfirst($section))
66 1
                        ->setPath($path);
67 1
                    if ($this->builder->getPages()->has($pageId)) {
68 1
                        $page = clone $this->builder->getPages()->get($pageId);
69
                    }
70 1
                    $pages = new PagesCollection("section-$pageId", $pagesAsArray);
71
                    // cascade variables
72 1
                    if ($page->hasVariable('cascade')) {
73 1
                        $cascade = $page->getVariable('cascade');
74 1
                        $pages->map(function (Page $page) use ($cascade) {
75 1
                            foreach ($cascade as $key => $value) {
76 1
                                if (!$page->hasVariable($key)) {
77 1
                                    $page->setVariable($key, $value);
78
                                }
79
                            }
80 1
                        });
81
                    }
82
                    // sorts pages
83 1
                    $pages = self::sortSubPages($page, $pages);
84
                    // adds navigation links (excludes taxonomy pages)
85 1
                    $sortby = $page->getVariable('sortby')['variable'] ?? (string) $page->getVariable('sortby') ?? 'date';
86 1
                    if (!\in_array($page->getId(), array_keys((array) $this->config->get('taxonomies')))) {
87 1
                        $this->addNavigationLinks($pages, $sortby, $page->getVariable('circular'));
88
                    }
89
                    // creates page for each section
90 1
                    $page->setType(Type::SECTION)
91 1
                        ->setSection($path)
92 1
                        ->setPages($pages)
93 1
                        ->setVariable('language', $language)
94 1
                        ->setVariable('date', $pages->first()->getVariable('date'))
95 1
                        ->setVariable('langref', $path);
96
                    // human readable title
97 1
                    if ($page->getVariable('title') == 'index') {
98
                        $page->setVariable('title', $section);
99
                    }
100
                    // default menu
101 1
                    if (!$page->getVariable('menu')) {
102 1
                        $page->setVariable('menu', ['main' => ['weight' => $menuWeight]]);
103
                    }
104 1
                    $this->generatedPages->add($page);
105
                }
106 1
                $menuWeight += 10;
107
            }
108
        }
109
    }
110
111
    /**
112
     * Sorts subpages.
113
     */
114 1
    public static function sortSubPages(Page $page, PagesCollection $pages): PagesCollection
115
    {
116
        // sorts (by date by default)
117 1
        $pages = $pages->sortByDate();
118
        /*
119
         * sortby: date|updated|title|weight
120
         *
121
         * sortby:
122
         *   variable: date|updated
123
         *   desc_title: false|true
124
         *   reverse: false|true
125
         */
126 1
        if ($page->hasVariable('sortby')) {
127 1
            $sortby = (string) $page->getVariable('sortby');
128
            // options?
129 1
            $sortby = $page->getVariable('sortby')['variable'] ?? $sortby;
130 1
            $descTitle = $page->getVariable('sortby')['desc_title'] ?? false;
131 1
            $reverse = $page->getVariable('sortby')['reverse'] ?? false;
132
            // sortby: date, title or weight
133 1
            $sortMethod = sprintf('sortBy%s', ucfirst(str_replace('updated', 'date', $sortby)));
134 1
            if (!method_exists($pages, $sortMethod)) {
135
                throw new RuntimeException(sprintf('In "%s" "%s" is not a valid value for "sortby" variable.', $page->getId(), $sortby));
136
            }
137
138 1
            return $pages->$sortMethod(['variable' => $sortby, 'descTitle' => $descTitle, 'reverse' => $reverse]);
139
        }
140
141 1
        return $pages;
142
    }
143
144
    /**
145
     * Adds navigation (next and prev) to section subpages.
146
     */
147 1
    protected function addNavigationLinks(PagesCollection $pages, string $sort = null, $circular = false): void
148
    {
149 1
        $pagesAsArray = $pages->toArray();
150 1
        if ($sort === null || $sort == 'date' || $sort == 'updated') {
151
            $pagesAsArray = array_reverse($pagesAsArray);
152
        }
153 1
        $count = \count($pagesAsArray);
154 1
        if ($count > 1) {
155 1
            foreach ($pagesAsArray as $position => $page) {
156
                switch ($position) {
157 1
                    case 0: // first
158 1
                        if ($circular) {
159 1
                            $page->setVariables([
160 1
                                'prev' => $pagesAsArray[$count - 1],
161 1
                            ]);
162
                        }
163 1
                        $page->setVariables([
164 1
                            'next' => $pagesAsArray[$position + 1],
165 1
                        ]);
166 1
                        break;
167 1
                    case $count - 1: // last
168 1
                        $page->setVariables([
169 1
                            'prev' => $pagesAsArray[$position - 1],
170 1
                        ]);
171 1
                        if ($circular) {
172 1
                            $page->setVariables([
173 1
                                'next' => $pagesAsArray[0],
174 1
                            ]);
175
                        }
176 1
                        break;
177
                    default:
178 1
                        $page->setVariables([
179 1
                            'prev' => $pagesAsArray[$position - 1],
180 1
                            'next' => $pagesAsArray[$position + 1],
181 1
                        ]);
182 1
                        break;
183
                }
184 1
                $this->generatedPages->add($page);
185
            }
186
        }
187
    }
188
}
189