Passed
Push — master ( cb72c1...6a1f09 )
by Arnaud
07:28
created

Section::generate()   F

Complexity

Conditions 18
Paths 556

Size

Total Lines 75
Code Lines 45

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 44
CRAP Score 18.0265

Importance

Changes 4
Bugs 1 Features 0
Metric Value
cc 18
eloc 45
nc 556
nop 0
dl 0
loc 75
ccs 44
cts 46
cp 0.9565
crap 18.0265
rs 1.3166
c 4
b 1
f 0

How to fix   Long Method    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
                    $subPages = new PagesCollection("section-$pageId", $pagesAsArray);
61
                    // cascade variables
62 1
                    if ($page->hasVariable('cascade')) {
63 1
                        $cascade = $page->getVariable('cascade');
64 1
                        $subPages->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 = $subPages->sortBy($this->config->get('pages.sortby'));
74 1
                    if ($page->hasVariable('sortby')) {
75
                        try {
76 1
                            $pages = $pages->sortBy($page->getVariable('sortby'));
77
                        } catch (RuntimeException $e) {
78
                            throw new RuntimeException(sprintf('In page "%s", %s', $page->getId(), $e->getMessage()));
79
                        }
80
                    }
81
                    // adds navigation links (excludes taxonomy pages)
82 1
                    $sortBy = $page->getVariable('sortby')['variable'] ?? $page->getVariable('sortby') ?? $this->config->get('pages.sortby') ?? 'date';
83 1
                    if (!\in_array($page->getId(), array_keys((array) $this->config->get('taxonomies')))) {
84 1
                        $this->addNavigationLinks($pages, $sortBy, $page->getVariable('circular') ?? false);
85
                    }
86
                    // creates page for each section
87 1
                    $page->setType(Type::SECTION->value)
88 1
                        ->setSection($path)
89 1
                        ->setPages($pages)
90 1
                        ->setVariable('language', $language)
91 1
                        ->setVariable('date', $pages->first()->getVariable('date'))
92 1
                        ->setVariable('langref', $path);
93
                    // human readable title
94 1
                    if ($page->getVariable('title') == 'index') {
95 1
                        $page->setVariable('title', $section);
96
                    }
97
                    // default menu
98 1
                    if (!$page->getVariable('menu')) {
99 1
                        $page->setVariable('menu', ['main' => ['weight' => $menuWeight]]);
100
                    }
101 1
                    $this->generatedPages->add($page);
102
                }
103 1
                $menuWeight += 10;
104
            }
105
        }
106
    }
107
108
    /**
109
     * Sorts subpages.
110
     */
111 1
    public static function sortSubPages(Page $page, PagesCollection $pages): PagesCollection
112
    {
113
        // sorts (by date by default)
114 1
        $pages = $pages->sortByDate();
115
        /*
116
         * sortby: date|updated|title|weight
117
         *
118
         * sortby:
119
         *   variable: date|updated
120
         *   desc_title: false|true
121
         *   reverse: false|true
122
         */
123 1
        if ($page->hasVariable('sortby')) {
124 1
            $sortby = (string) $page->getVariable('sortby');
125
            // options?
126 1
            $sortby = $page->getVariable('sortby')['variable'] ?? $sortby;
127 1
            $descTitle = $page->getVariable('sortby')['desc_title'] ?? false;
128 1
            $reverse = $page->getVariable('sortby')['reverse'] ?? false;
129
            // sortby: date, title or weight
130 1
            $sortMethod = sprintf('sortBy%s', ucfirst(str_replace('updated', 'date', $sortby)));
131 1
            if (!method_exists($pages, $sortMethod)) {
132
                throw new RuntimeException(sprintf('In "%s" "%s" is not a valid value for "sortby" variable.', $page->getId(), $sortby));
133
            }
134
135 1
            return $pages->$sortMethod(['variable' => $sortby, 'descTitle' => $descTitle, 'reverse' => $reverse]);
136
        }
137
138 1
        return $pages;
139
    }
140
141
    /**
142
     * Adds navigation (next and prev) to section subpages.
143
     */
144 1
    protected function addNavigationLinks(PagesCollection $pages, string|null $sortBy = null, bool $circular = false): void
145
    {
146 1
        $pagesAsArray = $pages->toArray();
147 1
        if ($sortBy === null || $sortBy == 'date' || $sortBy == 'updated') {
148 1
            $pagesAsArray = array_reverse($pagesAsArray);
149
        }
150 1
        $count = \count($pagesAsArray);
151 1
        if ($count > 1) {
152 1
            foreach ($pagesAsArray as $position => $page) {
153
                switch ($position) {
154 1
                    case 0: // first
155 1
                        if ($circular) {
156 1
                            $page->setVariables([
157 1
                                'prev' => $pagesAsArray[$count - 1],
158 1
                            ]);
159
                        }
160 1
                        $page->setVariables([
161 1
                            'next' => $pagesAsArray[$position + 1],
162 1
                        ]);
163 1
                        break;
164 1
                    case $count - 1: // last
165 1
                        $page->setVariables([
166 1
                            'prev' => $pagesAsArray[$position - 1],
167 1
                        ]);
168 1
                        if ($circular) {
169 1
                            $page->setVariables([
170 1
                                'next' => $pagesAsArray[0],
171 1
                            ]);
172
                        }
173 1
                        break;
174
                    default:
175 1
                        $page->setVariables([
176 1
                            'prev' => $pagesAsArray[$position - 1],
177 1
                            'next' => $pagesAsArray[$position + 1],
178 1
                        ]);
179 1
                        break;
180
                }
181 1
                $this->generatedPages->add($page);
182
            }
183
        }
184
    }
185
}
186