| 1 |  |  | <?php | 
            
                                                                                                            
                            
            
                                    
            
            
                | 2 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 3 |  |  | /** | 
            
                                                                                                            
                            
            
                                    
            
            
                | 4 |  |  |  * This file is part of Cecil. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 5 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 6 |  |  |  * (c) Arnaud Ligny <[email protected]> | 
            
                                                                                                            
                            
            
                                    
            
            
                | 7 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 8 |  |  |  * For the full copyright and license information, please view the LICENSE | 
            
                                                                                                            
                            
            
                                    
            
            
                | 9 |  |  |  * file that was distributed with this source code. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 10 |  |  |  */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 11 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 12 |  |  | declare(strict_types=1); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 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 |  |  |  * Pagination generator. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 22 |  |  |  * | 
            
                                                                                                            
                            
            
                                    
            
            
                | 23 |  |  |  * This generator creates paginated pages for sections, terms, and the homepage. | 
            
                                                                                                            
                            
            
                                    
            
            
                | 24 |  |  |  * It filters the pages based on their type, checks for pagination settings, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 25 |  |  |  * and generates paginated pages accordingly. | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 26 |  |  |  */ | 
            
                                                                        
                            
            
                                    
            
            
                | 27 |  |  | class Pagination extends AbstractGenerator implements GeneratorInterface | 
            
                                                                        
                            
            
                                    
            
            
                | 28 |  |  | { | 
            
                                                                        
                            
            
                                    
            
            
                | 29 |  |  |     /** | 
            
                                                                        
                            
            
                                    
            
            
                | 30 |  |  |      * {@inheritdoc} | 
            
                                                                        
                            
            
                                    
            
            
                | 31 |  |  |      */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 32 |  |  |     public function generate(): void | 
            
                                                                                                            
                            
            
                                    
            
            
                | 33 |  |  |     { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 34 |  |  |         if (!$this->config->isEnabled('pages.pagination')) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 35 |  |  |             return; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 36 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 37 |  |  |  | 
            
                                                                                                            
                            
            
                                    
            
            
                | 38 |  |  |         // filters list pages (home, sections and terms) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 39 |  |  |         $listPages = $this->builder->getPages()->filter(function (Page $page) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 40 |  |  |             return \in_array($page->getType(), [Type::HOMEPAGE->value, Type::SECTION->value, Type::TERM->value]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 41 |  |  |         }); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 42 |  |  |         /** @var Page $page */ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 43 |  |  |         foreach ($listPages as $page) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 44 |  |  |             // if no pages: continue | 
            
                                                                                                            
                            
            
                                    
            
            
                | 45 |  |  |             if ($page->getPages() === null) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 46 |  |  |                 continue; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 47 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 48 |  |  |             $pages = $page->getPages()->filter(function (Page $page) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 49 |  |  |                 return $page->getType() == Type::PAGE->value && $page->getVariable('published'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 50 |  |  |             }); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 51 |  |  |             // if no published pages: continue | 
            
                                                                                                            
                            
            
                                    
            
            
                | 52 |  |  |             if ($pages === null) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 53 |  |  |                 continue; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 54 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 55 |  |  |             $path = $page->getPath(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 56 |  |  |             // site pagination configuration | 
            
                                                                                                            
                            
            
                                    
            
            
                | 57 |  |  |             $paginationPerPage = \intval($this->config->get('pages.pagination.max') ?? 5); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 58 |  |  |             $paginationPath = $this->config->get('pages.pagination.path') ?? 'page'; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 59 |  |  |             // page pagination configuration | 
            
                                                                                                            
                            
            
                                    
            
            
                | 60 |  |  |             $pagePagination = $page->getVariable('pagination'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 61 |  |  |             if ($pagePagination) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 62 |  |  |                 if (isset($pagePagination['enabled']) && $pagePagination['enabled'] === false) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 63 |  |  |                     continue; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 64 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 65 |  |  |                 if (isset($pagePagination['max'])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 66 |  |  |                     $paginationPerPage = \intval($pagePagination['max']); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 67 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 68 |  |  |                 if (isset($pagePagination['path'])) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 69 |  |  |                     $paginationPath = (string) $pagePagination['path']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 70 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 71 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 72 |  |  |             $pagesTotal = \count($pages); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 73 |  |  |             // is pagination not necessary? | 
            
                                                                                                            
                            
            
                                    
            
            
                | 74 |  |  |             if ($pagesTotal <= $paginationPerPage) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 75 |  |  |                 continue; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 76 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 77 |  |  |             // sorts pages | 
            
                                                                                                            
                            
            
                                    
            
            
                | 78 |  |  |             $sortBy = $page->getVariable('sortby') ?? $this->config->get('pages.sortby'); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 79 |  |  |             $pages = $pages->sortBy($sortBy); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 80 |  |  |             // builds paginator | 
            
                                                                                                            
                            
            
                                    
            
            
                | 81 |  |  |             $paginatorPagesCount = \intval(ceil($pagesTotal / $paginationPerPage)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 82 |  |  |             for ($i = 0; $i < $paginatorPagesCount; $i++) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 83 |  |  |                 $itPagesInPagination = new \LimitIterator($pages->getIterator(), $i * $paginationPerPage, $paginationPerPage); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 84 |  |  |                 $pagesInPagination = new PagesCollection( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 85 |  |  |                     $page->getId() . '-page-' . ($i + 1), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 86 |  |  |                     iterator_to_array($itPagesInPagination) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 87 |  |  |                 ); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 88 |  |  |                 $alteredPage = clone $page; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 89 |  |  |                 // first page (ie: blog/page/1 -> blog) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 90 |  |  |                 $pageId = $page->getId(); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 91 |  |  |                 $alteredPage | 
            
                                                                                                            
                            
            
                                    
            
            
                | 92 |  |  |                     ->setVariable('alias', [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 93 |  |  |                         \sprintf('%s/%s/%s', $path, $paginationPath, 1), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 94 |  |  |                     ]); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 95 |  |  |                 // others pages (ie: blog/page/X) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 96 |  |  |                 if ($i > 0) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 97 |  |  |                     $pageId = Page::slugify(\sprintf('%s/%s/%s', $page->getId(), $paginationPath, $i + 1)); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 98 |  |  |                     $alteredPage | 
            
                                                                                                            
                            
            
                                    
            
            
                | 99 |  |  |                         ->setId($pageId) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 100 |  |  |                         ->setVirtual(true) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 101 |  |  |                         ->setPath(Page::slugify(\sprintf('%s/%s/%s', $path, $paginationPath, $i + 1))) | 
            
                                                                                                            
                            
            
                                    
            
            
                | 102 |  |  |                         ->unVariable('menu') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 103 |  |  |                         ->unVariable('alias') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 104 |  |  |                         ->unVariable('aliases') // backward compatibility | 
            
                                                                                                            
                            
            
                                    
            
            
                | 105 |  |  |                         ->unVariable('langref') | 
            
                                                                                                            
                            
            
                                    
            
            
                | 106 |  |  |                         ->setVariable('paginated', true); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 107 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 108 |  |  |                 // set paginator values | 
            
                                                                                                            
                            
            
                                    
            
            
                | 109 |  |  |                 $paginator = [ | 
            
                                                                                                            
                            
            
                                    
            
            
                | 110 |  |  |                     'pages'       => $pagesInPagination, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 111 |  |  |                     'pages_total' => $pagesTotal, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 112 |  |  |                     'totalpages'  => $pagesTotal, // backward compatibility | 
            
                                                                                                            
                            
            
                                    
            
            
                | 113 |  |  |                     'count'       => $paginatorPagesCount, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 114 |  |  |                     'current'     => $i + 1, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 115 |  |  |                 ]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 116 |  |  |                 // adds links | 
            
                                                                                                            
                            
            
                                    
            
            
                | 117 |  |  |                 $paginator['links'] = ['first' => $page->getId() ?: 'index']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 118 |  |  |                 if ($i == 1) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 119 |  |  |                     $paginator['links'] += ['prev' => $page->getId() ?: 'index']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 120 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 121 |  |  |                 if ($i > 1) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 122 |  |  |                     $paginator['links'] += ['prev' => Page::slugify(\sprintf( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 123 |  |  |                         '%s/%s/%s', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 124 |  |  |                         $page->getId(), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 125 |  |  |                         $paginationPath, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 126 |  |  |                         $i | 
            
                                                                                                            
                            
            
                                    
            
            
                | 127 |  |  |                     ))]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 128 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 129 |  |  |                 $paginator['links'] += ['self' => $pageId ?: 'index']; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 130 |  |  |                 if ($i < $paginatorPagesCount - 1) { | 
            
                                                                                                            
                            
            
                                    
            
            
                | 131 |  |  |                     $paginator['links'] += ['next' => Page::slugify(\sprintf( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 132 |  |  |                         '%s/%s/%s', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 133 |  |  |                         $page->getId(), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 134 |  |  |                         $paginationPath, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 135 |  |  |                         $i + 2 | 
            
                                                                                                            
                            
            
                                    
            
            
                | 136 |  |  |                     ))]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 137 |  |  |                 } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 138 |  |  |                 $paginator['links'] += ['last' => Page::slugify(\sprintf( | 
            
                                                                                                            
                            
            
                                    
            
            
                | 139 |  |  |                     '%s/%s/%s', | 
            
                                                                                                            
                            
            
                                    
            
            
                | 140 |  |  |                     $page->getId(), | 
            
                                                                                                            
                            
            
                                    
            
            
                | 141 |  |  |                     $paginationPath, | 
            
                                                                                                            
                            
            
                                    
            
            
                | 142 |  |  |                     $paginatorPagesCount | 
            
                                                                                                            
                            
            
                                    
            
            
                | 143 |  |  |                 ))]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 144 |  |  |                 $paginator['links'] += ['path' => Page::slugify(\sprintf('%s/%s', $page->getId(), $paginationPath))]; | 
            
                                                                                                            
                            
            
                                    
            
            
                | 145 |  |  |                 // set paginator to cloned page | 
            
                                                                                                            
                            
            
                                    
            
            
                | 146 |  |  |                 $alteredPage->setPaginator($paginator); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 147 |  |  |                 $alteredPage->setVariable('pagination', $paginator); // backward compatibility | 
            
                                                                                                            
                            
            
                                    
            
            
                | 148 |  |  |                 // updates date with the first element of the collection | 
            
                                                                                                            
                            
            
                                    
            
            
                | 149 |  |  |                 $alteredPage->setVariable('date', $pagesInPagination->first()->getVariable('date')); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 150 |  |  |  | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 151 |  |  |                 $this->generatedPages->add($alteredPage); | 
            
                                                                                                            
                            
            
                                    
            
            
                | 152 |  |  |             } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 153 |  |  |         } | 
            
                                                                                                            
                            
            
                                    
            
            
                | 154 |  |  |     } | 
            
                                                                                                            
                                                                
            
                                    
            
            
                | 155 |  |  | } | 
            
                                                        
            
                                    
            
            
                | 156 |  |  |  |