Passed
Push — develop ( 3f9e31...b937e4 )
by Brent
03:14
created

PaginationAdapter::validateConfig()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 9
Code Lines 5

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 5
nc 3
nop 2
dl 0
loc 9
rs 9.6666
c 0
b 0
f 0
1
<?php
2
3
namespace Brendt\Stitcher\Adapter;
4
5
use Brendt\Stitcher\Exception\ConfigurationException;
6
use Brendt\Stitcher\Exception\VariableNotFoundException;
7
use Brendt\Stitcher\Factory\AdapterFactory;
8
use Brendt\Stitcher\Site\Page;
9
10
/**
11
 * The PaginationAdapter takes a page with a collection of entries and generates pagination for that collection.
12
 *
13
 * Sample configuration:
14
 *
15
 *  /examples:
16
 *      template: examples/overview
17
 *      data:
18
 *          collection: collection.yml
19
 *      adapters:
20
 *      pagination:
21
 *          variable: collection
22
 *          entriesPerPage: 4
23
 */
24
class PaginationAdapter extends AbstractAdapter
25
{
26
    private $pageCount = null;
27
    private $variable = null;
28
    private $entriesPerPage = null;
29
    private $entries = [];
30
31
    public function transformPage(Page $page, $filter = null) : array {
32
        $config = $page->getAdapterConfig(AdapterFactory::PAGINATION_ADAPTER);
33
        $this->loadConfig($config, $page);
34
35
        $index = 0;
36
        $result = [];
37
38
        while ($index < $this->pageCount) {
39
            $pageEntries = array_splice($this->entries, 0, $this->entriesPerPage);
40
            $pageIndex = $index + 1;
41
42
            if ($filter === null || $pageIndex === (int) $filter) {
43
                $paginatedPage = $this->createPaginatedPage($page, $pageIndex, $pageEntries);
44
                $result[$paginatedPage->getId()] = $paginatedPage;
45
            }
46
47
            $index += 1;
48
        }
49
50
51
        $this->createMainPage(rtrim($page->getId(), '/'), $result);
52
53
        return $result;
54
    }
55
56
    private function createPaginatedPage(Page $page, int $pageIndex, array $pageEntries) : Page {
57
        $url = "{$page->getId()}/page-{$pageIndex}";
58
        $pagination = $this->createPagination($page->getId(), $pageIndex);
59
        $paginatedPage = clone $page;
60
61
        $paginatedPage
62
            ->removeAdapter(AdapterFactory::PAGINATION_ADAPTER)
63
            ->setVariableValue($this->variable, $pageEntries)
64
            ->setVariableIsParsed($this->variable)
65
            ->setVariableValue('pagination', $pagination)
66
            ->setVariableIsParsed('pagination')
67
            ->setId($url);
68
69
        return $paginatedPage;
70
    }
71
72
    private function createMainPage(string $pageId, array &$result) {
73
        $firstPage = reset($result);
74
75
        if (!$firstPage) {
76
            return;
77
        }
78
79
        $mainPage = clone $firstPage;
80
        $mainPage->setId($pageId);
81
        $result[$pageId] = $mainPage;
82
    }
83
84
    private function createPagination($pageId, $pageIndex) {
85
        $next = count($this->entries) ? $pageIndex + 1 : null;
86
        $nextUrl = $next ? "{$pageId}/page-{$next}" : null;
87
        $previous = $pageIndex > 1 ? $pageIndex - 1 : null;
88
        $previousUrl = $previous ? "{$pageId}/page-{$previous}" : null;
89
90
        return [
91
            'current'  => $pageIndex,
92
            'previous' => $previous ? [
93
                'url'   => $previousUrl,
94
                'index' => $previous,
95
            ] : null,
96
            'next'     => $next ? [
97
                'url'   => $nextUrl,
98
                'index' => $next,
99
            ] : null,
100
            'pages'    => $this->pageCount,
101
        ];
102
    }
103
104
    private function loadConfig(array $config, Page $page) {
105
        if (!isset($config['variable'])) {
106
            throw new ConfigurationException('The configuration entry `variable` is required when using the Pagination adapter');
107
        }
108
109
        $this->variable = $config['variable'] ?? null;
110
        
111
        if (!$page->getVariable($this->variable)) {
112
            throw new VariableNotFoundException("Variable \"{$this->variable}\" was not set as a data variable for page \"{$page->getId()}\"");
113
        }
114
115
        $this->entries = (array) $this->getData($page->getVariable($this->variable));
116
        $this->entriesPerPage = (int) $config['entriesPerPage'] ?? 10;
117
        $this->pageCount = (int) ceil(count($this->entries) / $this->entriesPerPage);
118
    }
119
}
120