• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

Cecilapp / Cecil / 5051201718

pending completion
5051201718

push

github

Arnaud Ligny
fix: pagination sorting

10 of 10 new or added lines in 1 file covered. (100.0%)

2789 of 4129 relevant lines covered (67.55%)

0.68 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

95.83
/src/Generator/Pagination.php
1
<?php
2

3
declare(strict_types=1);
4

5
/*
6
 * This file is part of Cecil.
7
 *
8
 * Copyright (c) Arnaud Ligny <arnaud@ligny.fr>
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\Pagination.
23
 */
24
class Pagination extends AbstractGenerator implements GeneratorInterface
25
{
26
    /**
27
     * {@inheritdoc}
28
     */
29
    public function generate(): void
30
    {
31
        if ($this->config->get('pagination.enabled') === false) {
1✔
32
            return;
×
33
        }
34

35
        // filters list pages (home, sections and terms)
36
        $filteredPages = $this->builder->getPages()->filter(function (Page $page) {
1✔
37
            return \in_array($page->getType(), [Type::HOMEPAGE, Type::SECTION, Type::TERM]);
1✔
38
        });
1✔
39
        /** @var Page $page */
40
        foreach ($filteredPages as $page) {
1✔
41
            $pages = $page->getPages()->filter(function (Page $page) {
1✔
42
                return $page->getVariable('published');
1✔
43
            });
1✔
44
            // if no sub-pages: by-pass
45
            if ($pages === null) {
1✔
46
                continue;
×
47
            }
48
            $path = $page->getPath();
1✔
49
            $sortby = $page->getVariable('sortby');
1✔
50
            // site pagination configuration
51
            $paginationPerPage = \intval($this->config->get('pagination.max') ?? 5);
1✔
52
            $paginationPath = (string) $this->config->get('pagination.path') ?? 'page';
1✔
53
            // page pagination configuration
54
            $pagePagination = $page->getVariable('pagination');
1✔
55
            if ($pagePagination) {
1✔
56
                if (isset($pagePagination['enabled']) && $pagePagination['enabled'] === false) {
1✔
57
                    continue;
×
58
                }
59
                if (isset($pagePagination['max'])) {
1✔
60
                    $paginationPerPage = \intval($pagePagination['max']);
1✔
61
                }
62
                if (isset($pagePagination['path'])) {
1✔
63
                    $paginationPath = (string) $pagePagination['path'];
1✔
64
                }
65
            }
66
            $pagesTotal = \count($pages);
1✔
67
            // is pagination not necessary?
68
            if ($pagesTotal <= $paginationPerPage) {
1✔
69
                continue;
1✔
70
            }
71
            // sorts (by date by default)
72
            $pages = $pages->sortByDate();
1✔
73
            /*
74
             * sortby: date|updated|title|weight
75
             *
76
             * sortby:
77
             *   variable: date|updated
78
             *   desc_title: false|true
79
             *   reverse: false|true
80
             */
81
            if ($page->hasVariable('sortby')) {
1✔
82
                $sortby = (string) $page->getVariable('sortby');
1✔
83
                // options?
84
                $sortby = $page->getVariable('sortby')['variable'] ?? $sortby;
1✔
85
                $descTitle = $page->getVariable('sortby')['desc_title'] ?? false;
1✔
86
                $reverse = $page->getVariable('sortby')['reverse'] ?? false;
1✔
87
                // sortby: date, title or weight
88
                $sortMethod = sprintf('sortBy%s', ucfirst(str_replace('updated', 'date', $sortby)));
1✔
89
                if (!method_exists($pages, $sortMethod)) {
1✔
90
                    throw new RuntimeException(sprintf('In "%s" section "%s" is not a valid value for "sortby" variable.', $page->getId(), $sortby));
×
91
                }
92
                $pages = $pages->$sortMethod(['variable' => $sortby, 'descTitle' => $descTitle, 'reverse' => $reverse]);
1✔
93
            }
94
            // builds paginator
95
            $paginatorPagesCount = \intval(ceil($pagesTotal / $paginationPerPage));
1✔
96
            for ($i = 0; $i < $paginatorPagesCount; $i++) {
1✔
97
                $itPagesInPagination = new \LimitIterator($pages->getIterator(), ($i * $paginationPerPage), $paginationPerPage);
1✔
98
                $pagesInPagination = new PagesCollection(
1✔
99
                    $page->getId() . '-page-' . ($i + 1),
1✔
100
                    iterator_to_array($itPagesInPagination)
1✔
101
                );
1✔
102
                $alteredPage = clone $page;
1✔
103
                if ($i == 0) { // first page (ie: blog/page/1 -> blog)
1✔
104
                    $pageId = $page->getId();
1✔
105
                    $alteredPage
1✔
106
                        ->setVariable('alias', [
1✔
107
                            sprintf('%s/%s/%s', $path, $paginationPath, 1),
1✔
108
                        ]);
1✔
109
                } else { // others pages (ie: blog/page/X)
110
                    $pageId = Page::slugify(sprintf('%s/%s/%s', $page->getId(), $paginationPath, $i + 1));
1✔
111
                    $alteredPage
1✔
112
                        ->setId($pageId)
1✔
113
                        ->setVirtual(true)
1✔
114
                        ->setPath(Page::slugify(sprintf('%s/%s/%s', $path, $paginationPath, $i + 1)))
1✔
115
                        ->unVariable('menu')
1✔
116
                        ->unVariable('alias')
1✔
117
                        ->unVariable('aliases') // backward compatibility
1✔
118
                        ->unVariable('langref')
1✔
119
                        ->setVariable('paginated', true);
1✔
120
                }
121
                // set paginator values
122
                $paginator = [
1✔
123
                    'pages'       => $pagesInPagination,
1✔
124
                    'pages_total' => $pagesTotal,
1✔
125
                    'totalpages'  => $pagesTotal, // backward compatibility
1✔
126
                    'count'       => $paginatorPagesCount,
1✔
127
                    'current'     => $i + 1,
1✔
128
                ];
1✔
129
                // adds links
130
                $paginator['links'] = ['first' => $page->getId() ?: 'index'];
1✔
131
                if ($i == 1) {
1✔
132
                    $paginator['links'] += ['prev' => $page->getId() ?: 'index'];
1✔
133
                }
134
                if ($i > 1) {
1✔
135
                    $paginator['links'] += ['prev' => Page::slugify(sprintf(
1✔
136
                        '%s/%s/%s',
1✔
137
                        $page->getId(),
1✔
138
                        $paginationPath,
1✔
139
                        $i
1✔
140
                    ))];
1✔
141
                }
142
                $paginator['links'] += ['self' => $pageId ?: 'index'];
1✔
143
                if ($i < $paginatorPagesCount - 1) {
1✔
144
                    $paginator['links'] += ['next' => Page::slugify(sprintf(
1✔
145
                        '%s/%s/%s',
1✔
146
                        $page->getId(),
1✔
147
                        $paginationPath,
1✔
148
                        $i + 2
1✔
149
                    ))];
1✔
150
                }
151
                $paginator['links'] += ['last' => Page::slugify(sprintf(
1✔
152
                    '%s/%s/%s',
1✔
153
                    $page->getId(),
1✔
154
                    $paginationPath,
1✔
155
                    $paginatorPagesCount
1✔
156
                ))];
1✔
157
                $paginator['links'] += ['path' => Page::slugify(sprintf('%s/%s', $page->getId(), $paginationPath))];
1✔
158
                // set paginator to cloned page
159
                $alteredPage->setPaginator($paginator);
1✔
160
                $alteredPage->setVariable('pagination', $paginator); // backward compatibility
1✔
161
                // updates date with the first element of the collection
162
                $alteredPage->setVariable('date', $pagesInPagination->first()->getVariable('date'));
1✔
163

164
                $this->generatedPages->add($alteredPage);
1✔
165
            }
166
        }
167
    }
168
}
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc