Completed
Push — master ( a2fb8e...063c96 )
by Henry
24:41
created

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

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\Db;
5
use Redaxscript\Html;
6
use Redaxscript\Model;
7
use Redaxscript\Module;
8
use Redaxscript\Validator;
9
use Redaxscript\View\ViewAbstract;
10
11
/**
12
 * helper class to create a breadcrumb navigation
13
 *
14
 * @since 2.1.0
15
 *
16
 * @package Redaxscript
17
 * @category View
18
 * @author Henry Ruhs
19
 * @author Gary Aylward
20
 */
21
22
class Breadcrumb extends ViewAbstract
23
{
24
	/**
25
	 * array of the breadcrumb
26
	 *
27
	 * @var array
28
	 */
29
30
	protected $_breadcrumbArray = [];
31
32
	/**
33
	 * options of the breadcrumb
34
	 *
35
	 * @var array
36
	 */
37
38
	protected $_optionArray =
39
	[
40
		'className' =>
41
		[
42
			'list' => 'rs-list-breadcrumb',
43
			'divider' => 'rs-item-divider'
44
		],
45
		'divider' => null
46
	];
47
48
	/**
49
	 * stringify the breadcrumb
50
	 *
51
	 * @since 3.0.0
52
	 *
53
	 * @return string
54
	 */
55
56 2
	public function __toString() : string
57
	{
58 2
		return $this->render();
59
	}
60
61
	/**
62
	 * init the class
63
	 *
64
	 * @since 2.6.0
65
	 *
66
	 * @param array $optionArray options of the breadcrumb
67
	 */
68
69 11
	public function init(array $optionArray = [])
70
	{
71 11
		$settingModel = new Model\Setting();
72 11
		$this->_optionArray = array_replace_recursive($this->_optionArray, $optionArray);
73 11
		if (!$this->_optionArray['divider'])
74
		{
75 11
			$this->_optionArray['divider'] = $settingModel->get('divider');
76
		}
77 11
		$this->_create();
78 11
	}
79
80
	/**
81
	 * get the breadcrumb array
82
	 *
83
	 * @since 2.1.0
84
	 *
85
	 * @return array
86
	 */
87
88 9
	public function getArray() : array
89
	{
90 9
		return $this->_breadcrumbArray;
91
	}
92
93
	/**
94
	 * render the breadcrumb
95
	 *
96
	 * @since 2.1.0
97
	 *
98
	 * @return string
99
	 */
100
101 2
	public function render() : string
102
	{
103 2
		$output = Module\Hook::trigger('breadcrumbStart');
104 2
		$parameterRoute = $this->_registry->get('parameterRoute');
105
106
		/* html element */
107
108 2
		$element = new Html\Element();
109
		$listElement = $element
110 2
			->copy()
111 2
			->init('ul',
112
			[
113 2
				'class' => $this->_optionArray['className']['list']
114
			]);
115 2
		$itemElement = $element->copy()->init('li');
116 2
		$linkElement = $element->copy()->init('a');
117
118
		/* breadcrumb keys */
119
120 2
		$breadcrumbKeys = array_keys($this->_breadcrumbArray);
121 2
		$lastKey = end($breadcrumbKeys);
122
123
		/* process breadcrumb */
124
125 2
		foreach ($this->_breadcrumbArray as $key => $valueArray)
126
		{
127 2
			$title = is_array($valueArray) && array_key_exists('title', $valueArray) ? $valueArray['title'] : null;
128 2
			$route = is_array($valueArray) && array_key_exists('route', $valueArray) ? $valueArray['route'] : null;
129 2
			if ($title)
130
			{
131 2
				$itemElement->clear();
132
133
				/* append link */
134
135 2
				if ($route)
136
				{
137 1
					$itemElement->append(
138
						$linkElement
139 1
							->attr('href', $parameterRoute . $route)
140 1
							->text($title)
141
					);
142
				}
143
144
				/* else append text */
145
146
				else
147
				{
148 2
					$itemElement->text($title);
149
				}
150 2
				$listElement->append($itemElement);
151
152
				/* append divider */
153
154 2
				if ($key !== $lastKey && $this->_optionArray['divider'])
155
				{
156 1
					$listElement->append(
157
						$itemElement
158 1
							->copy()
159 1
							->addClass($this->_optionArray['className']['divider'])
160 2
							->text($this->_optionArray['divider'])
161
					);
162
				}
163
			}
164
		}
165
166
		/* collect list output */
167
168 2
		$output .= $listElement;
169 2
		$output .= Module\Hook::trigger('breadcrumbEnd');
170 2
		return $output;
171
	}
172
173
	/**
174
	 * create the breadcrumb array
175
	 *
176
	 * @since 2.1.0
177
	 *
178
	 * @param int $key key of the item
179
	 */
180
181 11
	protected function _create(int $key = 0)
182
	{
183 11
		$aliasValidator = new Validator\Alias();
184 11
		$title = $this->_registry->get('useTitle');
185 11
		$firstParameter = $this->_registry->get('firstParameter');
186 11
		$firstTable = $this->_registry->get('firstTable');
187 11
		$fullRoute = $this->_registry->get('fullRoute');
188 11
		$lastId = $this->_registry->get('lastId');
189
190
		/* title */
191
192 11
		if ($title)
193
		{
194 1
			$this->_breadcrumbArray[$key]['title'] = $title;
195
		}
196
197
		/* else home */
198
199 10
		else if (!$fullRoute)
200
		{
201 1
			$this->_breadcrumbArray[$key]['title'] = $this->_language->get('home');
202
		}
203
204
		/* else administration */
205
206 9
		else if ($firstParameter === 'admin')
207
		{
208 2
			$this->_createAdmin($key);
209
		}
210
211
		/* else default alias */
212
213 7
		else if ($firstParameter && $aliasValidator->validate($firstParameter, 'system') && $this->_language->get($firstParameter))
0 ignored issues
show
It seems like $firstParameter defined by $this->_registry->get('firstParameter') on line 185 can also be of type array; however, Redaxscript\Validator\Alias::validate() does only seem to accept null|string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
It seems like $firstParameter defined by $this->_registry->get('firstParameter') on line 185 can also be of type array; however, Redaxscript\Language::get() does only seem to accept null|string, maybe add an additional type check?

If a method or function can return multiple different values and unless you are sure that you only can receive a single value in this context, we recommend to add an additional type check:

/**
 * @return array|string
 */
function returnsDifferentValues($x) {
    if ($x) {
        return 'foo';
    }

    return array();
}

$x = returnsDifferentValues($y);
if (is_array($x)) {
    // $x is an array.
}

If this a common case that PHP Analyzer should handle natively, please let us know by opening an issue.

Loading history...
214
		{
215 1
			$this->_breadcrumbArray[$key]['title'] = $this->_language->get($firstParameter);
216
		}
217
218
		/* handle error */
219
220 6
		else if (!$lastId)
221
		{
222 1
			$this->_breadcrumbArray[$key]['title'] = $this->_language->get('error');
223
		}
224
225
		/* query title from content */
226
227 5
		else if ($firstTable)
228
		{
229 5
			$this->_createContent($key);
230
		}
231 11
	}
232
233
	/**
234
	 * create the breadcrumb array for the administration
235
	 *
236
	 * @since 2.1.0
237
	 *
238
	 * @param int $key key of the item
239
	 */
240
241 2
	protected function _createAdmin(int $key = 0)
242
	{
243 2
		$adminParameter = $this->_registry->get('adminParameter');
244 2
		$tableParameter = $this->_registry->get('tableParameter');
245 2
		$lastParameter = $this->_registry->get('lastParameter');
246 2
		$fullRoute = $this->_registry->get('fullRoute');
247
248
		/* join first title */
249
250 2
		$this->_breadcrumbArray[$key]['title'] = $this->_language->get('administration');
251
252
		/* admin parameter */
253
254 2
		if ($adminParameter)
255
		{
256 1
			$this->_breadcrumbArray[$key]['route'] = 'admin';
257
		}
258
259
		/* join admin title */
260
261 2
		if ($adminParameter && $this->_language->get($adminParameter))
262
		{
263 1
			$key++;
264 1
			$this->_breadcrumbArray[$key]['title'] = $this->_language->get($adminParameter);
265
266
			/* set the route */
267
268 1
			if ($adminParameter !== $lastParameter)
269
			{
270 1
				$this->_breadcrumbArray[$key]['route'] = $fullRoute;
271
			}
272
273
			/* join table title */
274
275 1
			if ($tableParameter && $this->_language->get($tableParameter))
276
			{
277 1
				$key++;
278 1
				$this->_breadcrumbArray[$key]['title'] = $this->_language->get($tableParameter);
279
			}
280
		}
281 2
	}
282
283
	/**
284
	 * create the breadcrumb array for the content
285
	 *
286
	 * @since 2.1.0
287
	 *
288
	 * @param int $key
289
	 */
290
291 5
	protected function _createContent(int $key = 0)
292
	{
293 5
		$firstParameter = $this->_registry->get('firstParameter');
294 5
		$secondParameter = $this->_registry->get('secondParameter');
295 5
		$thirdParameter = $this->_registry->get('thirdParameter');
296 5
		$lastParameter = $this->_registry->get('lastParameter');
297 5
		$firstTable = $this->_registry->get('firstTable');
298 5
		$secondTable = $this->_registry->get('secondTable');
299 5
		$thirdTable = $this->_registry->get('thirdTable');
300
301
		/* join first title */
302
303 5
		$this->_breadcrumbArray[$key]['title'] = Db::forTablePrefix($firstTable)->where('alias', $firstParameter)->findOne()->title;
304
305
		/* set the route */
306
307 5
		if ($firstParameter !== $lastParameter)
308
		{
309 3
			$this->_breadcrumbArray[$key]['route'] = $firstParameter;
310
		}
311
312
		/* join second title */
313
314 5
		if ($secondTable)
315
		{
316 3
			$key++;
317 3
			$this->_breadcrumbArray[$key]['title'] = Db::forTablePrefix($secondTable)->where('alias', $secondParameter)->findOne()->title;
318
319
			/* set the route */
320
321 3
			if ($secondParameter !== $lastParameter)
322
			{
323 1
				$this->_breadcrumbArray[$key]['route'] = $firstParameter . '/' . $secondParameter;
324
			}
325
326
			/* join third title */
327
328 3
			if ($thirdTable)
329
			{
330 1
				$key++;
331 1
				$this->_breadcrumbArray[$key]['title'] = Db::forTablePrefix($thirdTable)->where('alias', $thirdParameter)->findOne()->title;
332
			}
333
		}
334 5
	}
335
}
336