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

Section::addNavigationLinks()   B

Complexity

Conditions 10
Paths 14

Size

Total Lines 38
Code Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 30
CRAP Score 10.0033

Importance

Changes 0
Metric Value
cc 10
eloc 27
c 0
b 0
f 0
nc 14
nop 3
dl 0
loc 38
ccs 30
cts 31
cp 0.9677
crap 10.0033
rs 7.6666

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

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