Test Failed
Push — master ( a58c94...1bcec0 )
by Brent
03:26
created

PaginationAdapter::createPagination()   B

Complexity

Conditions 7
Paths 64

Size

Total Lines 19
Code Lines 16

Duplication

Lines 0
Ratio 0 %

Importance

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