Passed
Push — master ( d8806f...7b7005 )
by Brent
02:58
created

PaginationAdapter::loadConfig()   A

Complexity

Conditions 3
Paths 3

Size

Total Lines 17
Code Lines 10

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 3
eloc 10
nc 3
nop 1
dl 0
loc 17
rs 9.4285
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
        $this->loadConfig($page);
33
34
        $index = 0;
35
        $result = [];
36
37
        while ($index < $this->pageCount) {
38
            $pageEntries = array_splice($this->entries, 0, $this->entriesPerPage);
39
            $pageIndex = $index + 1;
40
41
            if ($filter === null || $pageIndex === (int) $filter) {
42
                $paginatedPage = $this->createPaginatedPage($page, $pageIndex, $pageEntries);
43
                $result[$paginatedPage->getId()] = $paginatedPage;
44
            }
45
46
            $index += 1;
47
        }
48
49
        $this->createMainPage(rtrim($page->getId(), '/'), $result);
50
51
        return $result;
52
    }
53
54
    private function createPaginatedPage(Page $page, int $pageIndex, array $pageEntries) : Page {
55
        $url = "{$page->getId()}/page-{$pageIndex}";
56
        $pagination = $this->createPagination($page->getId(), $pageIndex);
57
        $paginatedPage = clone $page;
58
59
        $paginatedPage
60
            ->removeAdapter(AdapterFactory::PAGINATION_ADAPTER)
61
            ->setVariableValue($this->variable, $pageEntries)
62
            ->setVariableIsParsed($this->variable)
63
            ->setVariableValue('pagination', $pagination)
64
            ->setVariableIsParsed('pagination')
65
            ->setId($url);
66
67
        return $paginatedPage;
68
    }
69
70
    private function createMainPage(string $pageId, array &$result) {
71
        $firstPage = reset($result);
72
73
        if (!$firstPage) {
74
            return;
75
        }
76
77
        $mainPage = clone $firstPage;
78
        $mainPage->setId($pageId);
79
        $result[$pageId] = $mainPage;
80
    }
81
82
    private function createPagination($pageId, $pageIndex) {
83
        $next = count($this->entries) ? $pageIndex + 1 : null;
84
        $nextUrl = $next ? "{$pageId}/page-{$next}" : null;
85
        $previous = $pageIndex > 1 ? $pageIndex - 1 : null;
86
        $previousUrl = $previous ? "{$pageId}/page-{$previous}" : null;
87
88
        return [
89
            'current'  => $pageIndex,
90
            'previous' => $previous ? [
91
                'url'   => $previousUrl,
92
                'index' => $previous,
93
            ] : null,
94
            'next'     => $next ? [
95
                'url'   => $nextUrl,
96
                'index' => $next,
97
            ] : null,
98
            'pages'    => $this->pageCount,
99
        ];
100
    }
101
102
    private function loadConfig(Page $page) {
103
        $config = $page->getAdapterConfig(AdapterFactory::PAGINATION_ADAPTER);
104
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