Passed
Pull Request — menu (#1177)
by Arnaud
08:02 queued 04:44
created

Section::generate()   F

Complexity

Conditions 17
Paths 300

Size

Total Lines 76
Code Lines 47

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 40
CRAP Score 17.217

Importance

Changes 3
Bugs 0 Features 0
Metric Value
cc 17
eloc 47
c 3
b 0
f 0
nc 300
nop 0
dl 0
loc 76
ccs 40
cts 44
cp 0.9091
crap 17.217
rs 3.1333

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
 * This file is part of the Cecil/Cecil package.
4
 *
5
 * Copyright (c) Arnaud Ligny <[email protected]>
6
 *
7
 * For the full copyright and license information, please view the LICENSE
8
 * file that was distributed with this source code.
9
 */
10
11
namespace Cecil\Generator;
12
13
use Cecil\Collection\Page\Collection as PagesCollection;
14
use Cecil\Collection\Page\Page;
15
use Cecil\Collection\Page\Type;
16
use Cecil\Exception\Exception;
17
18
/**
19
 * Class Generator\Section.
20
 */
21
class Section extends AbstractGenerator implements GeneratorInterface
22
{
23
    /**
24
     * {@inheritdoc}
25
     */
26 1
    public function generate(): void
27
    {
28 1
        $sections = [];
29
30
        // identifying sections
31
        /** @var Page $page */
32 1
        foreach ($this->builder->getPages() as $page) {
33 1
            if ($page->getSection()) {
34
                // excludes page from its section?
35 1
                if ($page->getVariable('published') !== true || $page->getVariable('exclude')) {
36 1
                    $alteredPage = clone $page;
37 1
                    $alteredPage->setSection('');
38 1
                    $this->builder->getPages()->replace($page->getId(), $alteredPage);
39 1
                    continue;
40
                }
41 1
                $sections[$page->getSection()][$page->getVariable('language') ?? $this->config->getLanguageDefault()][] = $page;
42
            }
43
        }
44
45
        // adds section to pages collection
46 1
        if (count($sections) > 0) {
47 1
            $menuWeight = 100;
48 1
49 1
            foreach ($sections as $section => $languages) {
50 1
                foreach ($languages as $lang => $pagesAsArray) {
51 1
                    $pageId = $path = Page::slugify($section);
52 1
                    if ($lang != $this->config->getLanguageDefault()) {
53
                        $pageId = sprintf('%s.%s', Page::slugify($section), $lang);
54 1
                    }
55
                    $page = (new Page($pageId))->setVariable('title', ucfirst($section));
56 1
                    if ($this->builder->getPages()->has($pageId)) {
57 1
                        $page = clone $this->builder->getPages()->get($pageId);
58
                    }
59 1
                    $pages = new PagesCollection($section, $pagesAsArray);
60 1
                    // cascade
61 1
                    if ($page->hasVariable('cascade')) {
0 ignored issues
show
Bug introduced by
The method hasVariable() does not exist on Cecil\Collection\ItemInterface. It seems like you code against a sub-type of Cecil\Collection\ItemInterface such as Cecil\Collection\Page\Page. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

61
                    if ($page->/** @scrutinizer ignore-call */ hasVariable('cascade')) {
Loading history...
62
                        $cascade = $page->getVariable('cascade');
63
                        $pages->map(function (Page $page) use ($cascade) {
64 1
                            foreach ($cascade as $key => $value) {
65
                                if (!$page->hasVariable($key)) {
66
                                    $page->setVariable($key, $value);
67 1
                                }
68 1
                            }
69 1
                        });
70 1
                    }
71
                    // sorts
72
                    $pages = $pages->sortByDate();
73
                    if ($page->getVariable('sortby')) {
74
                        $sortMethod = sprintf('sortBy%s', ucfirst($page->getVariable('sortby')));
0 ignored issues
show
Bug introduced by
It seems like $page->getVariable('sortby') can also be of type null; however, parameter $string of ucfirst() does only seem to accept string, maybe add an additional type check? ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-type  annotation

74
                        $sortMethod = sprintf('sortBy%s', ucfirst(/** @scrutinizer ignore-type */ $page->getVariable('sortby')));
Loading history...
75
                        if (!method_exists($pages, $sortMethod)) {
76
                            throw new Exception(sprintf(
77 1
                                'In "%s" section "%s" is not a valid value for "sortby" variable.',
78
                                $page->getId(),
79
                                $page->getVariable('sortby')
80 1
                            ));
81
                        }
82 1
                        $pages = $pages->$sortMethod();
83 1
                    }
84 1
                    // adds navigation links
85 1
                    $this->addNavigationLinks($pages, $page->getVariable('sortby'), $page->getVariable('circular'));
86
                    // creates page for each section
87 1
                    $page->setPath($path)
0 ignored issues
show
Bug introduced by
The method setPath() does not exist on Cecil\Collection\ItemInterface. It seems like you code against a sub-type of Cecil\Collection\ItemInterface such as Cecil\Collection\Page\Page. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

87
                    $page->/** @scrutinizer ignore-call */ 
88
                           setPath($path)
Loading history...
88 1
                        ->setType(Type::SECTION)
0 ignored issues
show
Bug introduced by
The method setType() does not exist on Cecil\Collection\ItemInterface. It seems like you code against a sub-type of Cecil\Collection\ItemInterface such as Cecil\Collection\Page\Page. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

88
                        ->/** @scrutinizer ignore-call */ setType(Type::SECTION)
Loading history...
89 1
                        ->setVariable('pages', $pages)
0 ignored issues
show
Bug introduced by
The method setVariable() does not exist on Cecil\Collection\ItemInterface. It seems like you code against a sub-type of Cecil\Collection\ItemInterface such as Cecil\Collection\Page\Page. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

89
                        ->/** @scrutinizer ignore-call */ setVariable('pages', $pages)
Loading history...
90
                        ->setVariable('date', $pages->first()->getVariable('date'));
91
                    if ($lang != $this->config->getLanguageDefault()) {
92 1
                        $page->setVariable('language', $lang);
93 1
                    }
94
                    // default menu
95
                    if (!$page->getVariable('menu')) {
96 1
                        $page->setVariable('menu', [
97
                            'main' => ['weight' => $menuWeight],
98
                        ]);
99
                    }
100
                    $this->generatedPages->add($page);
101
                    $menuWeight += 10;
102
                }
103
            }
104
        }
105
    }
106
107 1
    /**
108
     * Adds navigation (next and prev) to section sub pages.
109 1
     *
110 1
     * @param PagesCollection $pages
111 1
     * @param string          $sort
112
     * @param bool            $circular
113 1
     *
114 1
     * @return void
115 1
     */
116
    protected function addNavigationLinks(PagesCollection $pages, string $sort = null, $circular = false): void
117
    {
118 1
        $pagesAsArray = $pages->toArray();
119 1
        if ($sort === null || $sort == 'date') {
120 1
            $pagesAsArray = array_reverse($pagesAsArray);
121
        }
122 1
        $count = count($pagesAsArray);
123 1
        if ($count > 1) {
124 1
            foreach ($pagesAsArray as $position => $page) {
125
                switch ($position) {
126
                    // first
127
                    case 0:
128 1
                        if ($circular) {
129
                            $page->setVariables([
130 1
                                'prev' => [
131 1
                                    'id'    => $pagesAsArray[$count - 1]->getId(),
132 1
                                    'path'  => $pagesAsArray[$count - 1]->getPath(),
133
                                    'title' => $pagesAsArray[$count - 1]->getVariable('title'),
134
                                ],
135 1
                            ]);
136
                        }
137 1
                        $page->setVariables([
138 1
                            'next' => [
139
                                'id'    => $pagesAsArray[$position + 1]->getId(),
140 1
                                'path'  => $pagesAsArray[$position + 1]->getPath(),
141 1
                                'title' => $pagesAsArray[$position + 1]->getVariable('title'),
142 1
                            ],
143
                        ]);
144
                        break;
145 1
                    // last
146 1
                    case $count - 1:
147
                        $page->setVariables([
148 1
                            'prev' => [
149 1
                                'id'    => $pagesAsArray[$position - 1]->getId(),
150 1
                                'path'  => $pagesAsArray[$position - 1]->getPath(),
151
                                'title' => $pagesAsArray[$position - 1]->getVariable('title'),
152
                            ],
153
                        ]);
154 1
                        if ($circular) {
155
                            $page->setVariables([
156 1
                                'next' => [
157
                                    'id'    => $pagesAsArray[0]->getId(),
158 1
                                    'path'  => $pagesAsArray[0]->getPath(),
159 1
                                    'title' => $pagesAsArray[0]->getVariable('title'),
160 1
                                ],
161
                            ]);
162
                        }
163 1
                        break;
164 1
                    default:
165 1
                        $page->setVariables([
166
                            'prev' => [
167
                                'id'    => $pagesAsArray[$position - 1]->getId(),
168 1
                                'path'  => $pagesAsArray[$position - 1]->getPath(),
169
                                'title' => $pagesAsArray[$position - 1]->getVariable('title'),
170 1
                            ],
171
                            'next' => [
172
                                'id'    => $pagesAsArray[$position + 1]->getId(),
173 1
                                'path'  => $pagesAsArray[$position + 1]->getPath(),
174
                                'title' => $pagesAsArray[$position + 1]->getVariable('title'),
175
                            ],
176
                        ]);
177
                        break;
178
                }
179
                $this->generatedPages->add($page);
180
            }
181
        }
182
    }
183
}
184