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