Test Failed
Push — develop ( 32ca41...230235 )
by Brent
04:59
created

PaginationAdapter::transform()   A

Complexity

Conditions 2
Paths 2

Size

Total Lines 21

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 6

Importance

Changes 0
Metric Value
cc 2
nc 2
nop 1
dl 0
loc 21
ccs 0
cts 13
cp 0
crap 6
rs 9.584
c 0
b 0
f 0
1
<?php
2
3
namespace Stitcher\Page\Adapter;
4
5
use Stitcher\Exception\InvalidPaginationAdapter;
6
use Stitcher\Page\Adapter;
7
use Stitcher\Configureable;
8
use Stitcher\Variable\VariableParser;
9
10
class PaginationAdapter implements Adapter, Configureable
11
{
12
    /** @var \Stitcher\Variable\VariableParser */
13
    private $variableParser;
14
15
    /** @var mixed */
16
    private $variable;
17
18
    /** @var int */
19
    private $perPage;
20
21
    /** @var string */
22
    private $parameter;
23
24
    public function __construct(
25
        array $adapterConfiguration,
26
        VariableParser $variableParser
27
    ) {
28
        if (! $this->isValidConfiguration($adapterConfiguration)) {
29
            throw InvalidPaginationAdapter::create();
30
        }
31
32
        $this->variable = $adapterConfiguration['variable'];
33
        $this->parameter = $adapterConfiguration['parameter'];
34
        $this->perPage = $adapterConfiguration['perPage'] ?? 12;
35
        $this->variableParser = $variableParser;
36
    }
37
38
    public static function make(
39
        array $adapterConfiguration,
40
        VariableParser $variableParser
41
    ): PaginationAdapter {
42
        return new self($adapterConfiguration, $variableParser);
43
    }
44
45
    public function transform(array $pageConfiguration): array
46
    {
47
        $paginationPageConfiguration = [];
48
        $entries = $this->getEntries($pageConfiguration);
49
        $pageCount = (int) ceil(\count($entries) / $this->perPage);
50
51
        for ($pageIndex = 1; $pageIndex <= $pageCount; $pageIndex++) {
52
            $entriesForPage = array_splice($entries, 0, $this->perPage);
53
54
            $entryConfiguration = $this->createPageConfiguration(
55
                $pageConfiguration,
56
                $entriesForPage,
57
                $pageIndex,
58
                $pageCount
59
            );
60
61
            $paginationPageConfiguration[$entryConfiguration['id']] = $entryConfiguration;
62
        }
63
64
        return $paginationPageConfiguration;
65
    }
66
67
    public function isValidConfiguration($subject): bool
68
    {
69
        return
70
            \is_array($subject)
71
            && isset($subject['variable'])
72
            && isset($subject['parameter']);
73
    }
74
75
    protected function getEntries(array $pageConfiguration): ?array
76
    {
77
        $variable = $pageConfiguration['variables'][$this->variable] ?? null;
78
        $entries = $this->variableParser->parse($variable)['entries']
79
            ?? $this->variableParser->parse($variable)
80
            ?? $variable;
81
82
        return $entries;
83
    }
84
85
    protected function createPageConfiguration(
86
        array $entryConfiguration,
87
        array $entriesForPage,
88
        int $pageIndex,
89
        int $pageCount
90
    ): array {
91
        $pageId = rtrim($entryConfiguration['id'], '/');
92
        $paginatedId = $this->createPaginatedUrl($pageId, $pageIndex);
93
94
        $entryConfiguration['id'] = $paginatedId;
95
        $entryConfiguration['variables'][$this->variable] = $entriesForPage;
96
97
        $paginationVariable = $this->createPaginationVariable($pageId, $pageIndex, $pageCount);
98
        $entryConfiguration['variables']['_pagination'] = $paginationVariable;
99
100
        unset($entryConfiguration['config']['pagination']);
101
102
        return $entryConfiguration;
103
    }
104
105
    protected function createPaginationVariable(
106
        string $pageId,
107
        int $pageIndex,
108
        int $pageCount
109
    ): array {
110
        return [
111
            'current'  => $pageIndex,
112
            'previous' => $this->createPreviousPagination($pageId, $pageIndex),
113
            'next'     => $this->createNextPagination($pageId, $pageIndex, $pageCount),
114
            'pages'    => $pageCount,
115
        ];
116
    }
117
118
    protected function createPreviousPagination(
119
        string $pageId,
120
        int $pageIndex
121
    ): ?array {
122
        if ($pageIndex <= 1) {
123
            return null;
124
        }
125
126
        $previous = $pageIndex - 1;
127
128
        return [
129
            'url'   => $this->createPaginatedUrl($pageId, $previous),
130
            'index' => $previous,
131
        ];
132
    }
133
134
    protected function createNextPagination(
135
        string $pageId,
136
        int $pageIndex,
137
        int $pageCount
138
    ): ?array {
139
        if ($pageIndex >= $pageCount) {
140
            return null;
141
        }
142
143
        $next = $pageIndex + 1;
144
145
        return [
146
            'url'   => $this->createPaginatedUrl($pageId, $next),
147
            'index' => $next,
148
        ];
149
    }
150
151
    protected function createPaginatedUrl(string $pageId, int $index): string
152
    {
153
        return str_replace('{' .$this->parameter. '}', $index, $pageId);
154
    }
155
}
156