Passed
Pull Request — master (#1704)
by Arnaud
12:40 queued 05:14
created

Section::generate()   F

Complexity

Conditions 18
Paths 655

Size

Total Lines 78
Code Lines 45

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 45
CRAP Score 18.0033

Importance

Changes 2
Bugs 1 Features 0
Metric Value
cc 18
eloc 45
c 2
b 1
f 0
nc 655
nop 0
dl 0
loc 78
ccs 45
cts 46
cp 0.9783
crap 18.0033
rs 1.1791

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