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

Section::generate()   F

Complexity

Conditions 16
Paths 268

Size

Total Lines 68
Code Lines 40

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 41
CRAP Score 16.0034

Importance

Changes 4
Bugs 2 Features 0
Metric Value
cc 16
eloc 40
c 4
b 2
f 0
nc 268
nop 0
dl 0
loc 68
ccs 41
cts 42
cp 0.9762
crap 16.0034
rs 3.8833

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
                    $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