Passed
Pull Request — master (#1676)
by Arnaud
05:15 queued 14s
created

Pagination   A

Complexity

Total Complexity 19

Size/Duplication

Total Lines 122
Duplicated Lines 0 %

Test Coverage

Coverage 8.98%

Importance

Changes 4
Bugs 1 Features 0
Metric Value
eloc 82
dl 0
loc 122
ccs 8
cts 89
cp 0.0898
rs 10
c 4
b 1
f 0
wmc 19

1 Method

Rating   Name   Duplication   Size   Complexity  
D generate() 0 117 19
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
20
/**
21
 * Class Generator\Pagination.
22
 */
23
class Pagination extends AbstractGenerator implements GeneratorInterface
24
{
25
    /**
26
     * {@inheritdoc}
27
     */
28 1
    public function generate(): void
29
    {
30 1
        if ($this->config->get('pagination.enabled') === false) {
31
            return;
32
        }
33
34
        // filters list pages (home, sections and terms)
35 1
        $filteredPages = $this->builder->getPages()->filter(function (Page $page) {
36 1
            return \in_array($page->getType(), [Type::HOMEPAGE, Type::SECTION, Type::TERM]);
37 1
        });
38
        /** @var Page $page */
39 1
        foreach ($filteredPages as $page) {
40 1
            if ($page->getPages() === null) {
41 1
                return;
42
            }
43
            $pages = $page->getPages()->filter(function (Page $page) {
44
                return $page->getVariable('published');
45
            });
46
            // if no sub-pages: by-pass
47
            if ($pages === null) {
48
                continue;
49
            }
50
            $path = $page->getPath();
51
            // site pagination configuration
52
            $paginationPerPage = \intval($this->config->get('pagination.max') ?? 5);
53
            $paginationPath = (string) $this->config->get('pagination.path') ?? 'page';
54
            // page pagination configuration
55
            $pagePagination = $page->getVariable('pagination');
56
            if ($pagePagination) {
57
                if (isset($pagePagination['enabled']) && $pagePagination['enabled'] === false) {
58
                    continue;
59
                }
60
                if (isset($pagePagination['max'])) {
61
                    $paginationPerPage = \intval($pagePagination['max']);
62
                }
63
                if (isset($pagePagination['path'])) {
64
                    $paginationPath = (string) $pagePagination['path'];
65
                }
66
            }
67
            $pagesTotal = \count($pages);
68
            // is pagination not necessary?
69
            if ($pagesTotal <= $paginationPerPage) {
70
                continue;
71
            }
72
            // sorts pages
73
            $pages = Section::sortSubPages($page, $pages);
74
            // builds paginator
75
            $paginatorPagesCount = \intval(ceil($pagesTotal / $paginationPerPage));
76
            for ($i = 0; $i < $paginatorPagesCount; $i++) {
77
                $itPagesInPagination = new \LimitIterator($pages->getIterator(), $i * $paginationPerPage, $paginationPerPage);
78
                $pagesInPagination = new PagesCollection(
79
                    $page->getId() . '-page-' . ($i + 1),
80
                    iterator_to_array($itPagesInPagination)
81
                );
82
                $alteredPage = clone $page;
83
                if ($i == 0) { // first page (ie: blog/page/1 -> blog)
84
                    $pageId = $page->getId();
85
                    $alteredPage
86
                        ->setVariable('alias', [
87
                            sprintf('%s/%s/%s', $path, $paginationPath, 1),
88
                        ]);
89
                } else { // others pages (ie: blog/page/X)
90
                    $pageId = Page::slugify(sprintf('%s/%s/%s', $page->getId(), $paginationPath, $i + 1));
91
                    $alteredPage
92
                        ->setId($pageId)
93
                        ->setVirtual(true)
94
                        ->setPath(Page::slugify(sprintf('%s/%s/%s', $path, $paginationPath, $i + 1)))
95
                        ->unVariable('menu')
96
                        ->unVariable('alias')
97
                        ->unVariable('aliases') // backward compatibility
98
                        ->unVariable('langref')
99
                        ->setVariable('paginated', true);
100
                }
101
                // set paginator values
102
                $paginator = [
103
                    'pages'       => $pagesInPagination,
104
                    'pages_total' => $pagesTotal,
105
                    'totalpages'  => $pagesTotal, // backward compatibility
106
                    'count'       => $paginatorPagesCount,
107
                    'current'     => $i + 1,
108
                ];
109
                // adds links
110
                $paginator['links'] = ['first' => $page->getId() ?: 'index'];
111
                if ($i == 1) {
112
                    $paginator['links'] += ['prev' => $page->getId() ?: 'index'];
113
                }
114
                if ($i > 1) {
115
                    $paginator['links'] += ['prev' => Page::slugify(sprintf(
116
                        '%s/%s/%s',
117
                        $page->getId(),
118
                        $paginationPath,
119
                        $i
120
                    ))];
121
                }
122
                $paginator['links'] += ['self' => $pageId ?: 'index'];
123
                if ($i < $paginatorPagesCount - 1) {
124
                    $paginator['links'] += ['next' => Page::slugify(sprintf(
125
                        '%s/%s/%s',
126
                        $page->getId(),
127
                        $paginationPath,
128
                        $i + 2
129
                    ))];
130
                }
131
                $paginator['links'] += ['last' => Page::slugify(sprintf(
132
                    '%s/%s/%s',
133
                    $page->getId(),
134
                    $paginationPath,
135
                    $paginatorPagesCount
136
                ))];
137
                $paginator['links'] += ['path' => Page::slugify(sprintf('%s/%s', $page->getId(), $paginationPath))];
138
                // set paginator to cloned page
139
                $alteredPage->setPaginator($paginator);
140
                $alteredPage->setVariable('pagination', $paginator); // backward compatibility
141
                // updates date with the first element of the collection
142
                $alteredPage->setVariable('date', $pagesInPagination->first()->getVariable('date'));
143
144
                $this->generatedPages->add($alteredPage);
145
            }
146
        }
147
    }
148
}
149