Completed
Pull Request — master (#25)
by
unknown
04:49
created

PaginationView   A

Complexity

Total Complexity 22

Size/Duplication

Total Lines 343
Duplicated Lines 0 %

Coupling/Cohesion

Components 1
Dependencies 5

Importance

Changes 0
Metric Value
wmc 22
lcom 1
cbo 5
dl 0
loc 343
rs 10
c 0
b 0
f 0

8 Methods

Rating   Name   Duplication   Size   Complexity  
A __construct() 0 12 2
C renderPageButtons() 0 73 8
B createPageButton() 0 24 3
B createButtonLink() 0 24 4
A prepareClassAttribute() 0 7 1
A getPageRange() 0 21 2
A setPagination() 0 4 1
A jsonEncode() 0 11 1
1
<?php
2
3
namespace Azine\EmailBundle\Services;
4
5
use Symfony\Bundle\FrameworkBundle\Routing\Router;
6
use Symfony\Component\HttpFoundation\RequestStack;
7
8
class PaginationView
9
{
10
11
    /**
12
     * @var Pagination
13
     */
14
    protected $pagination;
15
16
    /**
17
     * @var Router
18
     */
19
    protected $router;
20
21
    /**
22
     * @var string CSS class name for list.
23
     */
24
    protected $listCssClass = 'pagination';
25
26
    /**
27
     * @var array Parameter list for each pagination link.
28
     */
29
    protected $linkOptions = [];
30
31
    /**
32
     * @var string CSS class name for first page button.
33
     */
34
    public $firstPageCssClass = 'first';
35
36
    /**
37
     * @var string CSS class name for last page button.
38
     */
39
    public $lastPageCssClass = 'last';
40
41
    /**
42
     * @var string CSS class name for previous page button.
43
     */
44
    public $prevPageCssClass = 'prev';
45
46
    /**
47
     * @var string CSS class name for next page button.
48
     */
49
    public $nextPageCssClass = 'next';
50
51
    /**
52
     * @var string CSS class name for active page button
53
     */
54
    public $activePageCssClass = 'active';
55
56
    /**
57
     * @var string CSS class for disabled page button.
58
     */
59
    public $disabledPageCssClass = 'disabled';
60
61
    /**
62
     * @var int Max number of buttons to show.
63
     */
64
    public $maxButtonCount = 10;
65
66
    /**
67
     * @var bool Whether to show a link to the first page.
68
     */
69
    public $showFirstPageLink = false;
70
71
    /**
72
     * @var bool Whether to show a link to the last page
73
     */
74
    public $showLastPageLink = false;
75
76
    /**
77
     * @var bool Whether to show a link to the previous page.
78
     */
79
    public $showPrevPageLink = true;
80
81
    /**
82
     * @var bool Whether to show a link to the next page
83
     */
84
    public $showNextPageLink = true;
85
86
    /**
87
     * @var string Next page default label. Will be used if [[showNextPageLink]]
88
     * set to true.
89
     */
90
    public $nextPageLabel = '&rsaquo;';
91
92
    /**
93
     * @var string Precious page default label. Will be used if
94
     * [[showPrevPageLink]] set to true.
95
     */
96
    public $prevPageLabel = '&lsaquo;';
97
98
    /**
99
     * @var string First page default label. Will be used if
100
     * [[showFirstPageLink]] set to true.
101
     */
102
    public $firstPageLabel = '&laquo;';
103
104
    /**
105
     * @var string Last page default label. Will be used if
106
     * [[showLastPageLink]] set to true.
107
     */
108
    public $lastPageLabel = '&raquo;';
109
110
    /**
111
     * PaginationView constructor.
112
     *
113
     * @param RequestStack $request
114
     * @param Router $router
115
     */
116
    public function __construct(
117
        RequestStack $request,
118
        Router $router
119
    ) {
120
        $currentRequest = $request->getCurrentRequest();
121
122
        if ($currentRequest) {
123
            $this->queryParameters = $currentRequest->query->all();
0 ignored issues
show
Bug introduced by
The property queryParameters does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
124
        }
125
126
        $this->router = $router;
127
    }
128
129
    /**
130
     * Render pagination block.
131
     *
132
     * @return string
133
     * @throws \Exception
134
     */
135
    public function renderPageButtons()
136
    {
137
        if (!$this->pagination) {
138
            throw new \Exception(
139
                'Instance of ' . Pagination::class . ' should be specified.'
140
            );
141
        }
142
143
        $pageCount = $this->pagination->getPageCount();
144
145
        if ($pageCount < 2) {
146
            return '';
147
        }
148
149
        $buttons = [];
150
151
        $currentPage = $this->pagination->getCurrentPage();
152
153
        if ($this->showFirstPageLink) {
154
            $buttons[] = $this->createPageButton(
155
                $this->firstPageLabel,
156
                0,
157
                $this->firstPageCssClass,
158
                $currentPage <= 0,
159
                false
160
            );
161
        }
162
163
        if ($this->showPrevPageLink) {
164
            $buttons[] = $this->createPageButton(
165
                $this->prevPageLabel,
166
                max(0, $currentPage - 1),
167
                $this->prevPageCssClass,
168
                $currentPage <= 0,
169
                false
170
            );
171
        }
172
173
        list($startPage, $endPage) = $this->getPageRange();
174
175
        for ($i = $startPage; $i <= $endPage; ++$i) {
176
            $buttons[] = $this->createPageButton(
177
                $i + 1,
178
                $i,
179
                null,
180
                false,
181
                $i == $currentPage
182
            );
183
        }
184
185
        if ($this->showNextPageLink) {
186
            $buttons[] = $this->createPageButton(
187
                $this->nextPageLabel,
188
                min($currentPage + 1, $pageCount - 1),
189
                $this->nextPageCssClass,
190
                $currentPage >= $pageCount - 1,
191
                false
192
            );
193
        }
194
195
        if ($this->showLastPageLink) {
196
            $buttons[] = $this->createPageButton(
197
                $this->lastPageLabel,
198
                $pageCount - 1,
199
                $this->lastPageCssClass,
200
                $currentPage >= $pageCount - 1,
201
                false
202
            );
203
        }
204
205
        return '<ul class = "'.$this->listCssClass .'">'
206
            .implode("\n", $buttons).'</ul>';
207
    }
208
209
    /**
210
     * Render single pagination block button.
211
     *
212
     * @param string $label
213
     * @param int $page
214
     * @param string $class
215
     * @param bool $disabled
216
     * @param bool $active
217
     *
218
     * @return string
219
     */
220
    protected function createPageButton(
221
        $label,
222
        $page,
223
        $class,
224
        $disabled,
225
        $active
226
    ) {
227
        $buttonClassList = [$class];
228
229
        if ($active) {
230
            array_push($buttonClassList, $this->activePageCssClass);
231
        }
232
233
        if ($disabled) {
234
            array_push($buttonClassList, $this->disabledPageCssClass);
235
        }
236
237
        $link = '<a href="'
238
            .$this->createButtonLink($page, $this->pagination->getPageSize())
239
            .'">'.$label.'</a>';
240
241
        return '<li '.$this->prepareClassAttribute($buttonClassList).'>'.$link
242
            .'</li>';
243
    }
244
245
    /**
246
     * Create link for pagination button.
247
     *
248
     * @param int $pageIndex
249
     * @param int $pageSize
250
     * @param bool $absoluteUrl
251
     *
252
     * @return string
253
     */
254
    public function createButtonLink($pageIndex, $pageSize, $absoluteUrl = true)
255
    {
256
        $pageParamName = $this->pagination->getPageParamName();
257
258
        $pageSizeParamName = $this->pagination->getPageSizeParam();
259
260
        if ($pageIndex > 0) {
261
            $this->queryParameters[$pageParamName] = $pageIndex + 1;
262
        } else {
263
            unset($this->queryParameters[$pageParamName]);
264
        }
265
266
        if ($pageSize != $this->pagination->getDefaultPageSize()) {
267
            $this->queryParameters[$pageSizeParamName] = $pageSize;
268
        } else {
269
            unset($this->queryParameters[$pageSizeParamName]);
270
        }
271
272
        return $this->router->generate(
273
            $this->pagination->getRoute(),
274
            $this->queryParameters,
275
            $absoluteUrl ? Router::ABSOLUTE_URL : Router::ABSOLUTE_PATH
276
        );
277
    }
278
279
280
    /**
281
     * Creates string representation of class attribute from array.
282
     *
283
     * @param string $attributeName
0 ignored issues
show
Bug introduced by
There is no parameter named $attributeName. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
284
     * @param array $attributeData
285
     *
286
     * @return string
287
     */
288
    protected function prepareClassAttribute(array $attributeData) {
289
290
        $preparedAttribute = "class ="
291
            .$this->jsonEncode(implode(' ', $attributeData));
292
293
        return $preparedAttribute;
294
    }
295
296
    /**
297
     * Calculate current pagination pages range.
298
     *
299
     * @return array
300
     */
301
    protected function getPageRange()
302
    {
303
        $pageCount = $this->pagination->getPageCount();
304
305
        $beginPage = max(
306
            0,
307
            $this->pagination->getCurrentPage() - floor(
308
                $this->maxButtonCount / 2
309
            )
310
        );
311
312
        $endPage = $beginPage + $this->maxButtonCount - 1;
313
314
        if ($endPage >= $pageCount) {
315
            $endPage = $pageCount - 1;
316
317
            $beginPage = max(0, $endPage - $this->maxButtonCount + 1);
318
        }
319
320
        return [$beginPage, $endPage];
321
    }
322
323
    /**
324
     * @param Pagination $pagination
325
     */
326
    public function setPagination(Pagination $pagination)
327
    {
328
        $this->pagination = $pagination;
329
    }
330
331
332
    /**
333
     * Encodes data for using as html attribute value.
334
     *
335
     * @param mixed $data
336
     *
337
     * @return string
338
     */
339
    public function jsonEncode($data)
340
    {
341
        return json_encode(
342
            $data,
343
            JSON_UNESCAPED_UNICODE
344
            | JSON_HEX_QUOT
345
            | JSON_HEX_TAG
346
            | JSON_HEX_AMP
347
            | JSON_HEX_APOS
348
        );
349
    }
350
}