Completed
Push — master ( 14c945...6811c1 )
by Henry
05:37
created

Panel::_renderLogout()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 27

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
dl 0
loc 27
ccs 0
cts 13
cp 0
rs 9.488
c 0
b 0
f 0
cc 1
nc 1
nop 0
crap 2
1
<?php
2
namespace Redaxscript\Admin\View\Helper;
3
4
use Redaxscript\Admin;
5
use Redaxscript\Html;
6
use Redaxscript\Module;
7
use Redaxscript\Validator;
8
use function array_key_exists;
9
use function array_replace_recursive;
10
use function count;
11
12
/**
13
 * helper class to create the admin panel
14
 *
15
 * @since 4.0.0
16
 *
17
 * @package Redaxscript
18
 * @category View
19
 * @author Henry Ruhs
20
 */
21
22
class Panel extends Admin\View\ViewAbstract
23
{
24
	/**
25
	 * options of the panel
26
	 *
27
	 * @var array
28
	 */
29
30
	protected $_optionArray =
31
	[
32
		'className' =>
33
		[
34
			'list' =>
35
			[
36
				'panel' => 'rs-admin-fn-dropdown rs-admin-list-panel',
37
				'content' => 'rs-admin-fn-content-panel rs-admin-list-panel-children',
38
				'access' => 'rs-admin-fn-content-panel rs-admin-list-panel-children',
39
				'system' => 'rs-admin-fn-content-panel rs-admin-list-panel-children',
40
				'notification' => 'rs-admin-fn-content-panel rs-admin-list-panel-children rs-admin-list-notification'
41
			],
42
			'item' =>
43
			[
44
				'content' => 'rs-admin-item-panel',
45
				'access' => 'rs-admin-item-panel',
46
				'system' => 'rs-admin-item-panel',
47
				'profile' => 'rs-admin-item-panel',
48
				'notification' => 'rs-admin-item-panel',
49
				'logout' => 'rs-admin-item-panel rs-admin-item-panel-logout'
50
			],
51
			'link' =>
52
			[
53
				'view' => 'rs-admin-link-panel rs-admin-link-panel-view',
54
				'new' => 'rs-admin-link-panel rs-admin-link-panel-new',
55
				'system' => 'rs-admin-link-panel rs-admin-link-panel-system',
56
				'profile' => 'rs-admin-link-panel rs-admin-link-panel-profile',
57
				'logout' => 'rs-admin-link-panel rs-admin-link-panel-logout'
58
			],
59
			'label' =>
60
			[
61
				'content' => 'rs-admin-fn-toggle-panel rs-admin-label-panel rs-admin-label-panel-content',
62
				'access' => 'rs-admin-fn-toggle-panel rs-admin-label-panel rs-admin-label-panel-access',
63
				'system' => 'rs-admin-fn-toggle-panel rs-admin-label-panel rs-admin-label-panel-system',
64
				'notification' => 'rs-admin-fn-toggle-panel rs-admin-label-panel rs-admin-label-panel-notification'
65
			],
66
			'note' =>
67
			[
68
				'success' => 'rs-admin-is-success',
69
				'warning' => 'rs-admin-is-warning',
70
				'error' => 'rs-admin-is-error',
71
				'info' => 'rs-admin-is-info'
72
			],
73
			'text' => 'rs-admin-text-panel-group',
74
			'input' => 'rs-admin-fn-status-panel',
75
			'sup' => 'rs-admin-sup-panel-notification'
76
		]
77
	];
78
79
	/**
80
	 * init the class
81
	 *
82
	 * @since 4.0.0
83
	 *
84
	 * @param array $optionArray options of the panel
85
	 *
86
	 * @return self
87
	 */
88
89
	public function init(array $optionArray = []) : self
90
	{
91
		$this->_optionArray = array_replace_recursive($this->_optionArray, $optionArray);
92
		return $this;
93
	}
94
95
	/**
96
	 * render the view
97
	 *
98
	 * @since 4.0.0
99
	 *
100
	 * @return string
101
	 */
102
103
	public function render() : string
104
	{
105
		$output = Module\Hook::trigger('adminPanelStart');
106
		$outputItem = null;
107
108
		/* html element */
109
110
		$listElement = new Html\Element();
111
		$listElement->init('ul',
112
		[
113
			'class' => $this->_optionArray['className']['list']['panel']
114
		]);
115
116
		/* collect item output */
117
118
		if ($this->_hasPermission('contents'))
119
		{
120
			$outputItem .= $this->_renderContent();
121
		}
122
		if ($this->_hasPermission('access'))
123
		{
124
			$outputItem .= $this->_renderAccess();
125
		}
126
		if ($this->_hasPermission('system'))
127
		{
128
			$outputItem .= $this->_renderSystem();
129
		}
130
		if ($this->_hasPermission('profile'))
131
		{
132
			$outputItem .= $this->_renderProfile();
133
		}
134
		if ($this->_hasPermission('notification'))
135
		{
136
			$outputItem .= $this->_renderNotification();
137
		}
138
		$outputItem .= $this->_renderLogout();
139
140
		/* collect output */
141
142
		if ($outputItem)
143
		{
144
			$output .= $listElement->html($outputItem);
145
		}
146
		$output .= Module\Hook::trigger('adminPanelEnd');
147
		return $output;
148
	}
149
150
	/**
151
	 * has the permission
152
	 *
153
	 * @since 4.0.0
154
	 *
155
	 * @param string $type
156
	 *
157
	 * @return bool
158
	 */
159
160
	protected function _hasPermission(string $type = null) : bool
161
	{
162
		$permissionArray = [];
163
		$accessValidator = new Validator\Access();
164
		if ($this->_registry->get('categoriesEdit'))
165
		{
166
			$permissionArray['categories'] = $permissionArray['contents'] = true;
167
		}
168
		if ($this->_registry->get('articlesEdit'))
169
		{
170
			$permissionArray['articles'] = $permissionArray['contents'] = true;
171
		}
172
		if ($this->_registry->get('extrasEdit'))
173
		{
174
			$permissionArray['extras'] = $permissionArray['contents'] = true;
175
		}
176
		if ($this->_registry->get('commentsEdit'))
177
		{
178
			$permissionArray['comments'] = $permissionArray['contents'] = true;
179
		}
180
		if ($this->_registry->get('usersEdit'))
181
		{
182
			$permissionArray['users'] = $permissionArray['access'] = true;
183
		}
184
		if ($this->_registry->get('groupsEdit'))
185
		{
186
			$permissionArray['groups'] = $permissionArray['access'] = true;
187
		}
188
		if ($this->_registry->get('modulesEdit'))
189
		{
190
			$permissionArray['modules'] = $permissionArray['system'] = true;
191
		}
192
		if ($this->_registry->get('settingsEdit'))
193
		{
194
			$permissionArray['settings'] = $permissionArray['system'] = true;
195
		}
196
		if ($this->_registry->get('myId'))
197
		{
198
			$permissionArray['profile'] = true;
199
		}
200
		if ($accessValidator->validate(1, $this->_registry->get('myGroups')))
0 ignored issues
show
Bug introduced by Henry Ruhs
It seems like $this->_registry->get('myGroups') targeting Redaxscript\Registry::get() can also be of type array; however, Redaxscript\Validator\Access::validate() does only seem to accept null|string, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
201
		{
202
			$permissionArray['notification'] = true;
203
		}
204
		return array_key_exists($type, $permissionArray);
205
	}
206
207
	/**
208
	 * render the content
209
	 *
210
	 * @since 4.0.0
211
	 *
212
	 * @return string|null
213
	 */
214
215
	protected function _renderContent() : ?string
216
	{
217
		$output = null;
218
		$parameterRoute = $this->_registry->get('parameterRoute');
219
		$contentArray =
220
		[
221
			'categories',
222
			'articles',
223
			'extras',
224
			'comments'
225
		];
226
227
		/* html element */
228
229
		$element = new Html\Element();
230
		$listElement = $element
231
			->copy()
232
			->init('ul',
233
			[
234
				'class' => $this->_optionArray['className']['list']['content']
235
			]);
236
		$itemElement = $element->copy()->init('li');
237
		$linkElement = $element->copy()->init('a');
238
		$textElement = $element
239
			->copy()
240
			->init('span',
241
			[
242
				'class' => $this->_optionArray['className']['text']
243
			]);
244
		$labelElement = $element
245
			->copy()
246
			->init('label',
247
			[
248
				'class' => $this->_optionArray['className']['label']['content'],
249
				'for' => self::class . '\Content'
250
			])
251
			->text($this->_language->get('contents'));
0 ignored issues
show
Bug introduced by Henry Ruhs
It seems like $this->_language->get('contents') targeting Redaxscript\Language::get() can also be of type array; however, Redaxscript\Html\Element::text() does only seem to accept string|integer|null, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
252
		$inputElement = $element
253
			->copy()
254
			->init('input',
255
			[
256
				'id' => self::class . '\Content',
257
				'class' => $this->_optionArray['className']['input'],
258
				'type' => 'radio',
259
				'name' => self::class . '\Panel'
260
			]);
261
262
		/* process contents */
263
264
		foreach ($contentArray as $type)
265
		{
266
			$tableNew = $this->_registry->get($type . 'New');
267
			if ($this->_hasPermission($type))
268
			{
269
				$listElement->append(
270
					$itemElement
271
						->copy()
272
						->html(
273
							$textElement
274
								->copy()
275
								->append(
276
									$linkElement
277
										->copy()
278
										->addClass($this->_optionArray['className']['link']['view'])
279
										->attr('href', $parameterRoute . 'admin/view/' . $type)
280
										->text($this->_language->get($type))
0 ignored issues
show
Bug introduced by Henry Ruhs
It seems like $this->_language->get($type) targeting Redaxscript\Language::get() can also be of type array; however, Redaxscript\Html\Element::text() does only seem to accept string|integer|null, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
281
								)
282
								->append($tableNew ? $linkElement
0 ignored issues
show
Bug introduced by redaxmedia
It seems like $tableNew ? $linkElement...age->get('new')) : null can also be of type object<Redaxscript\Html\Element>; however, Redaxscript\Html\HtmlAbstract::append() 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...
283
									->copy()
284
									->addClass($this->_optionArray['className']['link']['new'])
285
									->attr('href', $parameterRoute . 'admin/new/' . $type)
286
									->text($this->_language->get('new')) : null
0 ignored issues
show
Bug introduced by Henry Ruhs
It seems like $this->_language->get('new') targeting Redaxscript\Language::get() can also be of type array; however, Redaxscript\Html\Element::text() does only seem to accept string|integer|null, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
287
								)
288
						)
289
				);
290
			}
291
		}
292
293
		/* collect output */
294
295
		$output .= $itemElement
296
			->copy()
297
			->addClass($this->_optionArray['className']['item']['content'])
298
			->html($inputElement . $labelElement . $listElement);
299
		return $output;
300
	}
301
302
	/**
303
	 * render the access
304
	 *
305
	 * @since 4.0.0
306
	 *
307
	 * @return string|null
308
	 */
309
310
	protected function _renderAccess() : ?string
311
	{
312
		$output = null;
313
		$parameterRoute = $this->_registry->get('parameterRoute');
314
		$accessArray =
315
		[
316
			'users',
317
			'groups'
318
		];
319
320
		/* html element */
321
322
		$element = new Html\Element();
323
		$listElement = $element
324
			->copy()
325
			->init('ul',
326
			[
327
				'class' => $this->_optionArray['className']['list']['access']
328
			]);
329
		$itemElement = $element->copy()->init('li');
330
		$linkElement = $element->copy()->init('a');
331
		$textElement = $element
332
			->copy()
333
			->init('span',
334
			[
335
				'class' => $this->_optionArray['className']['text']
336
			]);
337
		$labelElement = $element
338
			->copy()
339
			->init('label',
340
			[
341
				'class' => $this->_optionArray['className']['label']['access'],
342
				'for' => self::class . '\Access'
343
			])
344
			->text($this->_language->get('access'));
0 ignored issues
show
Bug introduced by Henry Ruhs
It seems like $this->_language->get('access') targeting Redaxscript\Language::get() can also be of type array; however, Redaxscript\Html\Element::text() does only seem to accept string|integer|null, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
345
		$inputElement = $element
346
			->copy()
347
			->init('input',
348
			[
349
				'id' => self::class . '\Access',
350
				'class' => $this->_optionArray['className']['input'],
351
				'type' => 'radio',
352
				'name' => self::class . '\Panel'
353
			]);
354
355
		/* process access */
356
357
		foreach ($accessArray as $type)
358
		{
359
			$tableNew = $this->_registry->get($type . 'New');
360
			if ($this->_hasPermission($type))
361
			{
362
				$listElement->append(
363
					$itemElement
364
						->copy()
365
						->html(
366
							$textElement
367
								->copy()
368
								->append(
369
									$linkElement
370
										->copy()
371
										->addClass($this->_optionArray['className']['link']['view'])
372
										->attr('href', $parameterRoute . 'admin/view/' . $type)
373
										->text($this->_language->get($type))
0 ignored issues
show
Bug introduced by Henry Ruhs
It seems like $this->_language->get($type) targeting Redaxscript\Language::get() can also be of type array; however, Redaxscript\Html\Element::text() does only seem to accept string|integer|null, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
374
								)
375
								->append($tableNew ? $linkElement
0 ignored issues
show
Bug introduced by redaxmedia
It seems like $tableNew ? $linkElement...age->get('new')) : null can also be of type object<Redaxscript\Html\Element>; however, Redaxscript\Html\HtmlAbstract::append() 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...
376
									->copy()
377
									->addClass($this->_optionArray['className']['link']['new'])
378
									->attr('href', $parameterRoute . 'admin/new/' . $type)
379
									->text($this->_language->get('new')) : null
0 ignored issues
show
Bug introduced by Henry Ruhs
It seems like $this->_language->get('new') targeting Redaxscript\Language::get() can also be of type array; however, Redaxscript\Html\Element::text() does only seem to accept string|integer|null, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
380
								)
381
						)
382
				);
383
			}
384
		}
385
386
		/* collect output */
387
388
		$output .= $itemElement
389
			->copy()
390
			->addClass($this->_optionArray['className']['item']['access'])
391
			->html($inputElement . $labelElement . $listElement);
392
		return $output;
393
	}
394
395
	/**
396
	 * render the system
397
	 *
398
	 * @since 4.0.0
399
	 *
400
	 * @return string|null
401
	 */
402
403
	protected function _renderSystem() : ?string
404
	{
405
		$output = null;
406
		$parameterRoute = $this->_registry->get('parameterRoute');
407
		$systemArray =
408
		[
409
			'modules',
410
			'settings'
411
		];
412
413
		/* html element */
414
415
		$element = new Html\Element();
416
		$listElement = $element
417
			->copy()
418
			->init('ul',
419
			[
420
				'class' => $this->_optionArray['className']['list']['system']
421
			]);
422
		$itemElement = $element->copy()->init('li');
423
		$linkElement = $element
424
			->copy()
425
			->init('a',
426
			[
427
				'class' => $this->_optionArray['className']['link']['system'],
428
			]);
429
		$labelElement = $element
430
			->copy()
431
			->init('label',
432
			[
433
				'class' => $this->_optionArray['className']['label']['system'],
434
				'for' => self::class . '\System'
435
			])
436
			->text($this->_language->get('system'));
0 ignored issues
show
Bug introduced by Henry Ruhs
It seems like $this->_language->get('system') targeting Redaxscript\Language::get() can also be of type array; however, Redaxscript\Html\Element::text() does only seem to accept string|integer|null, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
437
		$inputElement = $element
438
			->copy()
439
			->init('input',
440
			[
441
				'id' => self::class . '\System',
442
				'class' => $this->_optionArray['className']['input'],
443
				'type' => 'radio',
444
				'name' => self::class . '\Panel'
445
			]);
446
447
		/* process system */
448
449
		foreach ($systemArray as $type)
450
		{
451
			if ($this->_hasPermission($type))
452
			{
453
				$listElement->append(
454
					$itemElement
455
						->copy()
456
						->html(
457
							$linkElement
458
								->copy()
459
								->attr('href', $type === 'settings' ? $parameterRoute . 'admin/edit/settings' : $parameterRoute . 'admin/view/' . $type)
460
								->text($this->_language->get($type))
0 ignored issues
show
Bug introduced by Henry Ruhs
It seems like $this->_language->get($type) targeting Redaxscript\Language::get() can also be of type array; however, Redaxscript\Html\Element::text() does only seem to accept string|integer|null, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
461
						)
462
				);
463
			}
464
		}
465
466
		/* collect output */
467
468
		$output .= $itemElement
469
			->copy()
470
			->addClass($this->_optionArray['className']['item']['system'])
471
			->html($inputElement . $labelElement . $listElement);
472
		return $output;
473
	}
474
475
	/**
476
	 * render the profile
477
	 *
478
	 * @since 4.0.0
479
	 *
480
	 * @return string
481
	 */
482
483
	protected function _renderProfile() : string
484
	{
485
		$parameterRoute = $this->_registry->get('parameterRoute');
486
		$myId = $this->_registry->get('myId');
487
488
		/* html element */
489
490
		$element = new Html\Element();
491
		$itemElement = $element
492
			->copy()
493
			->init('li',
494
			[
495
				'class' => $this->_optionArray['className']['item']['profile']
496
			]);
497
		$linkElement = $element
498
			->copy()
499
			->init('a',
500
			[
501
				'href' => $parameterRoute . 'admin/edit/users/' . $myId,
502
				'class' => $this->_optionArray['className']['link']['profile']
503
			])
504
			->text($this->_language->get('profile'));
0 ignored issues
show
Bug introduced by Henry Ruhs
It seems like $this->_language->get('profile') targeting Redaxscript\Language::get() can also be of type array; however, Redaxscript\Html\Element::text() does only seem to accept string|integer|null, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
505
506
		/* collect item output */
507
508
		$output = $itemElement->html($linkElement);
509
		return $output;
510
	}
511
512
	/**
513
	 * render the notification
514
	 *
515
	 * @since 4.0.0
516
	 *
517
	 * @return string|null
518
	 */
519
520
	protected function _renderNotification() : ?string
521
	{
522
		$output = null;
523
		$adminNotification = new Notification($this->_language);
524
		$adminNotification->init(
525
		[
526
			'className' =>
527
			[
528
				'list' => $this->_optionArray['className']['list']['notification']
529
			]
530
		]);
531
		$notificationArray = $adminNotification->getNotificationArray();
532
		$notificationTotal = 0;
533
534
		/* html element */
535
536
		$element = new Html\Element();
537
		$itemElement = $element
538
			->copy()
539
			->init('li',
540
			[
541
				'class' => $this->_optionArray['className']['item']['notification']
542
			]);
543
		$labelElement = $element
544
			->copy()
545
			->init('label',
546
			[
547
				'class' => $this->_optionArray['className']['label']['notification'],
548
				'for' => self::class . '\Notification'
549
			])
550
			->text($this->_language->get('notification'));
0 ignored issues
show
Bug introduced by Henry Ruhs
It seems like $this->_language->get('notification') targeting Redaxscript\Language::get() can also be of type array; however, Redaxscript\Html\Element::text() does only seem to accept string|integer|null, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
551
		$inputElement = $element
552
			->copy()
553
			->init('input',
554
			[
555
				'id' => self::class . '\Notification',
556
				'class' => $this->_optionArray['className']['input'],
557
				'type' => 'radio',
558
				'name' => self::class . '\Panel',
559
				'checked' => 'checked'
560
			]);
561
		$supElement = $element
562
			->copy()
563
			->init('sup',
564
			[
565
				'class' => $this->_optionArray['className']['sup']
566
			]);
567
568
		/* process notification */
569
570
		foreach ($notificationArray as $key => $value)
571
		{
572
			$supElement->addClass($this->_optionArray['className']['note'][$key]);
573
			$notificationTotal += count($value);
574
		}
575
		$labelElement->append($supElement->text($notificationTotal));
576
577
		/* collect item output */
578
579
		if ($notificationArray)
0 ignored issues
show
Bug Best Practice introduced by redaxmedia
The expression $notificationArray of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using ! empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
580
		{
581
			$output = $itemElement->html($inputElement . $labelElement . $adminNotification->render());
582
		}
583
		return $output;
584
	}
585
586
	/**
587
	 * render the logout
588
	 *
589
	 * @since 4.0.0
590
	 *
591
	 * @return string
592
	 */
593
594
	protected function _renderLogout() : string
595
	{
596
		$parameterRoute = $this->_registry->get('parameterRoute');
597
598
		/* html element */
599
600
		$element = new Html\Element();
601
		$itemElement = $element
602
			->copy()
603
			->init('li',
604
			[
605
				'class' => $this->_optionArray['className']['item']['logout']
606
			]);
607
		$linkElement = $element
608
			->copy()
609
			->init('a',
610
			[
611
				'href' => $parameterRoute . 'logout',
612
				'class' => $this->_optionArray['className']['link']['logout']
613
			])
614
			->text($this->_language->get('logout'));
0 ignored issues
show
Bug introduced by Henry Ruhs
It seems like $this->_language->get('logout') targeting Redaxscript\Language::get() can also be of type array; however, Redaxscript\Html\Element::text() does only seem to accept string|integer|null, maybe add an additional type check?

This check looks at variables that are passed out again to other methods.

If the outgoing method call has stricter type requirements than the method itself, an issue is raised.

An additional type check may prevent trouble.

Loading history...
615
616
		/* collect item output */
617
618
		$output = $itemElement->html($linkElement);
619
		return $output;
620
	}
621
}
622