Completed
Push — master ( 0ea243...da58d4 )
by Henry
10:25 queued 33s
created

includes/View/Helper/Pagination.php (2 issues)

Check for loose comparison of integers.

Best Practice Bug Major

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

1
<?php
2
namespace Redaxscript\View\Helper;
3
4
use Redaxscript\Html;
5
use Redaxscript\Module;
6
use Redaxscript\View\ViewAbstract;
7
use function array_replace_recursive;
8
use function max;
9
use function min;
10
use function range;
11
12
/**
13
 * helper class to create the pagination
14
 *
15
 * @since 4.0.0
16
 *
17
 * @package Redaxscript
18
 * @category View
19
 * @author Henry Ruhs
20
 */
21
22
class Pagination extends ViewAbstract
23
{
24
	/**
25
	 * options of the pagination
26
	 *
27
	 * @var array
28
	 */
29
30
	protected $_optionArray =
31
	[
32
		'className' =>
33
		[
34
			'list' => 'rs-list-pagination',
35
			'item' =>
36
			[
37
				'first' => 'rs-item-first',
38
				'previous' => 'rs-item-previous',
39
				'next' => 'rs-item-next',
40
				'last' => 'rs-item-last',
41
				'number' => 'rs-item-number',
42
				'active' => 'rs-item-active'
43
			]
44
		]
45
	];
46
47
	/**
48
	 * init the class
49
	 *
50
	 * @since 4.0.0
51
	 *
52
	 * @param array $optionArray options of the pagination
53
	 */
54
55 12
	public function init(array $optionArray = []) : void
56
	{
57 12
		$this->_optionArray = array_replace_recursive($this->_optionArray, $optionArray);
58 12
	}
59
60
	/**
61
	 * render the view
62
	 *
63
	 * @since 4.0.0
64
	 *
65
	 * @param string $route
66
	 * @param int $current
67
	 * @param int $total
68
	 * @param int $range
69
	 *
70
	 * @return string
71
	 */
72
73 12
	public function render(string $route = null, int $current = null, int $total = null, int $range = 0) : string
74
	{
75 12
		$output = Module\Hook::trigger('paginationStart');
76 12
		$outputItem = null;
77 12
		$numberArray = $current && $total ? $this->_getNumberArray($current, $total, $range) : [];
0 ignored issues
show
Bug Best Practice introduced by
The expression $current of type null|integer is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
Bug Best Practice introduced by
The expression $total of type null|integer is loosely compared to true; this is ambiguous if the integer can be zero. You might want to explicitly use !== null instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For integer values, zero is a special case, in particular the following results might be unexpected:

0   == false // true
0   == null  // true
123 == false // false
123 == null  // false

// It is often better to use strict comparison
0 === false // false
0 === null  // false
Loading history...
78 12
		$parameterRoute = $this->_registry->get('parameterRoute');
79
80
		/* html element */
81
82 12
		$element = new Html\Element();
83
		$listElement = $element
84 12
			->copy()
85 12
			->init('ul',
86
			[
87 12
				'class' => $this->_optionArray['className']['list']
88
			]);
89 12
		$itemElement = $element->copy()->init('li');
90 12
		$linkElement = $element->copy()->init('a');
91 12
		$textElement = $element->copy()->init('span');
92
93
		/* first and previous */
94
95 12
		if ($current > 1)
96
		{
97
			$outputItem .= $itemElement
98 10
				->copy()
99 10
				->addClass($this->_optionArray['className']['item']['first'])
100 10
				->html(
101
					$linkElement
102 10
						->copy()
103 10
						->attr('href', $parameterRoute . $route)
104 10
						->text($this->_language->get('first'))
105
				);
106
			$outputItem .= $itemElement
107 10
				->copy()
108 10
				->addClass($this->_optionArray['className']['item']['previous'])
109 10
				->html(
110
					$linkElement
111 10
						->copy()
112 10
						->attr(
113
						[
114 10
							'href' => $parameterRoute . $route . '/' . ($current - 1),
115 10
							'rel' => 'prev'
116
						])
117 10
						->text($this->_language->get('previous'))
118
				);
119
		}
120
121
		/* process number */
122
123 12
		foreach ($numberArray as $value)
124
		{
125
			$outputItem .= $itemElement
126 12
				->copy()
127 12
				->addClass($this->_optionArray['className']['item']['number'])
128 12
				->addClass($value === $current ? $this->_optionArray['className']['item']['active'] : null)
129 12
				->html(
130 12
					$value === $current ? $textElement->text($value) : $linkElement
131 11
						->copy()
132 11
						->attr('href', $parameterRoute . $route . '/' . $value)
133 12
						->text($value)
134
				);
135
		}
136
137
		/* next and last */
138
139 12
		if ($current && $current < $total)
140
		{
141
			$outputItem .= $itemElement
142 10
				->copy()
143 10
				->addClass($this->_optionArray['className']['item']['next'])
144 10
				->html(
145
					$linkElement
146 10
						->copy()
147 10
						->attr(
148
						[
149 10
							'href' => $parameterRoute . $route . '/' . ($current + 1),
150 10
							'rel' => 'next'
151
						])
152 10
						->text($this->_language->get('next'))
153
				);
154
			$outputItem .= $itemElement
155 10
				->copy()
156 10
				->addClass($this->_optionArray['className']['item']['last'])
157 10
				->html(
158
					$linkElement
159 10
						->copy()
160 10
						->attr('href', $parameterRoute . $route . '/' . $total)
161 10
						->text($this->_language->get('last'))
162
				);
163
		}
164
165
		/* collect output */
166
167 12
		if ($outputItem)
168
		{
169 12
			$output .= $listElement->html($outputItem);
170
		}
171 12
		$output .= Module\Hook::trigger('paginationEnd');
172 12
		return $output;
173
	}
174
175
	/**
176
	 * get the number array
177
	 *
178
	 * @since 4.0.0
179
	 *
180
	 * @param int $current
181
	 * @param int $total
182
	 * @param int $range
183
	 *
184
	 * @return array
185
	 */
186
187 12
	protected function _getNumberArray(int $current = null, int $total = null, int $range = 0) : array
188
	{
189 12
		$start = $current - $range;
190 12
		$end = $current + $range;
191
192
		/* start and end */
193
194 12
		for ($i = $start; $i <= $end; $i++)
195
		{
196 12
			if ($i < 1)
197
			{
198 2
				$end++;
199
			}
200 12
			if ($i > $total)
201
			{
202 2
				$start--;
203
			}
204
		}
205 12
		return range(max(1, $start), min($total, $end));
206
	}
207
}
208