Control::render()   F
last analyzed

Complexity

Conditions 21
Paths 384

Size

Total Lines 146

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 52
CRAP Score 21

Importance

Changes 0
Metric Value
dl 0
loc 146
ccs 52
cts 52
cp 1
rs 0.8266
c 0
b 0
f 0
cc 21
nc 384
nop 4
crap 21

How to fix   Long Method    Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
namespace Redaxscript\Admin\View\Helper;
3
4
use Redaxscript\Admin\View\ViewAbstract;
5
use Redaxscript\Html;
6
use Redaxscript\Module;
7
use function array_replace_recursive;
8
use function in_array;
9
use function ucfirst;
10
11
/**
12
 * helper class to create the admin control
13
 *
14
 * @since 4.0.0
15
 *
16
 * @package Redaxscript
17
 * @category View
18
 * @author Henry Ruhs
19
 */
20
21
class Control extends ViewAbstract
22
{
23
	/**
24
	 * options of the panel
25
	 *
26
	 * @var array
27
	 */
28
29
	protected $_optionArray =
30
	[
31
		'className' =>
32
		[
33 12
			'list' => 'rs-admin-list-control',
34
			'item' =>
35 12
			[
36 12
				'control' => 'rs-admin-item-control',
37 12
				'disable' => 'rs-admin-item-disable',
38 12
				'enable' => 'rs-admin-item-enable',
39
				'future-posting' => 'rs-admin-item-future-posting',
40
				'unpublish' => 'rs-admin-item-unpublish',
41
				'publish' => 'rs-admin-item-publish',
42 12
				'edit' => 'rs-admin-item-edit',
43
				'delete' => 'rs-admin-item-delete',
44 12
				'install' => 'rs-admin-item-install',
45 12
				'uninstall' => 'rs-admin-item-uninstall'
46
			],
47 12
			'link' =>
48
			[
49
				'delete' => 'rs-admin-js-delete',
50 12
				'uninstall' => 'rs-admin-js-uninstall'
51 12
			]
52
		]
53 12
	];
54
55
	/**
56 12
	 * init the class
57 12
	 *
58
	 * @since 4.0.0
59 12
	 *
60 12
	 * @param array $optionArray options of the panel
61
	 */
62
63
	public function init(array $optionArray = [])
64 12
	{
65
		$this->_optionArray = array_replace_recursive($this->_optionArray, $optionArray);
66 2
	}
67
68 2
	/**
69 2
	 * render the view
70 2
	 *
71
	 * @since 4.0.0
72 2
	 *
73 2
	 * @param string $table name of the table
74 2
	 * @param int $id identifier of the item
75
	 * @param string $alias alias of the item
76
	 * @param int $status status of the item
77
	 *
78
	 * @return string|null
79
	 */
80 12
81
	public function render(string $table = null, int $id = null, string $alias = null, int $status = null) : ?string
82 3
	{
83
		$output = Module\Hook::trigger('adminControlStart');
84
		$outputItem = null;
85 1
		$parameterRoute = $this->_registry->get('parameterRoute');
86 1
		$token = $this->_registry->get('token');
87 1
88
		/* html element */
89 1
90 1
		$element = new Html\Element();
91
		$listElement = $element
92
			->copy()
93
			->init('ul',
94
			[
95 2
				'class' => $this->_optionArray['className']['list']
96
			]);
97 2
		$itemElement = $element
98 2
			->copy()
99 2
			->init('li',
100
			[
101 2
				'class' => $this->_optionArray['className']['item']['control']
102 2
			]);
103 2
		$linkElement = $element
104
			->copy()
105
			->init('a');
106
		$textElement = $element
107
			->copy()
108
			->init('span');
109
110 12
		/* collect enable */
111
112
		if ($this->_hasPermission($table, 'edit') && $this->_showAction($table, 'enable', $id))
113 1
		{
114 1
			$enableAction = $status ? 'disable' : 'enable';
115 1
			$outputItem .= $itemElement
116
				->copy()
117 1
				->addClass($enableAction === 'disable' ? $this->_optionArray['className']['item']['disable'] : $this->_optionArray['className']['item']['enable'])
118 1
				->html(
119 1
					$linkElement
120
						->copy()
121
						->attr('href', $parameterRoute . 'admin/' . $enableAction . '/' . $table . '/' . $id . '/' . $token)
122
						->text($enableAction === 'disable' ? $this->_language->get('disable') : $this->_language->get('enable'))
0 ignored issues
show
Bug introduced by Henry Ruhs
It seems like $enableAction === 'disab...language->get('enable') 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?

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...
123
				);
124
		}
125 12
126
		/* collect publish */
127
128 6
		if ($this->_hasPermission($table, 'edit') && $this->_showAction($table, 'publish', $id))
129 6
		{
130 6
			if ($status === 2)
131
			{
132 6
				$outputItem .= $itemElement
133 6
					->copy()
134 6
					->addClass($this->_optionArray['className']['item']['future-posting'])
135
					->html(
136
						$textElement
137
							->copy()
138
							->text($this->_language->get('future_posting'))
0 ignored issues
show
Bug introduced by Henry Ruhs
It seems like $this->_language->get('future_posting') 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...
139
					);
140 12
			}
141
			else
142
			{
143 3
				$publishAction = $status ? 'unpublish' : 'publish';
144 3
				$outputItem .= $itemElement
145 3
					->copy()
146
					->addClass($publishAction === 'unpublish' ? $this->_optionArray['className']['item']['unpublish'] : $this->_optionArray['className']['item']['publish'])
147 3
					->html(
148 3
						$linkElement
149 3
							->copy()
150 3
							->attr('href', $parameterRoute . 'admin/' . $publishAction . '/' . $table . '/' . $id . '/' . $token)
151
							->text($publishAction === 'unpublish' ? $this->_language->get('unpublish') : $this->_language->get('publish'))
0 ignored issues
show
Bug introduced by Henry Ruhs
It seems like $publishAction === 'unpu...anguage->get('publish') 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?

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...
152
					);
153
			}
154
		}
155
156 12
		/* collect install */
157
158
		if ($this->_hasPermission($table, 'install') && $this->_showAction($table, 'install', $id))
159 1
		{
160 1
			$outputItem .= $itemElement
161 1
				->copy()
162
				->addClass($this->_optionArray['className']['item']['install'])
163 1
				->html(
164 1
					$linkElement
165 1
						->copy()
166
						->attr('href', $parameterRoute . 'admin/install/' . $table . '/' . $alias . '/' . $token)
167
						->text($this->_language->get('install'))
0 ignored issues
show
Bug introduced by Henry Ruhs
It seems like $this->_language->get('install') 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...
168
				);
169
		}
170
171 12
		/* collect edit */
172
173 9
		if ($this->_hasPermission($table, 'edit') && $this->_showAction($table, 'edit', $id))
174
		{
175 12
			$outputItem .= $itemElement
176 12
				->copy()
177
				->addClass($this->_optionArray['className']['item']['edit'])
178
				->html(
179
					$linkElement
180
						->copy()
181
						->attr('href', $parameterRoute . 'admin/edit/' . $table . '/' . $id)
182
						->text($this->_language->get('edit'))
0 ignored issues
show
Bug introduced by Henry Ruhs
It seems like $this->_language->get('edit') 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...
183
				);
184
		}
185
186
		/* collect delete */
187
188
		if ($this->_hasPermission($table, 'delete') && $this->_showAction($table, 'delete', $id))
189
		{
190 12
			$outputItem .= $itemElement
191
				->copy()
192 12
				->addClass($this->_optionArray['className']['item']['delete'])
193
				->html(
194
					$linkElement
195
						->copy()
196
						->addClass($this->_optionArray['className']['link']['delete'])
197
						->attr('href', $parameterRoute . 'admin/delete/' . $table . '/' . $id . '/' . $token)
198
						->text($this->_language->get('delete'))
0 ignored issues
show
Bug introduced by Henry Ruhs
It seems like $this->_language->get('delete') 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...
199
				);
200
		}
201
202
		/* collect uninstall */
203
204
		if ($this->_hasPermission($table, 'uninstall') && $this->_showAction($table, 'uninstall', $id))
205
		{
206
			$outputItem .= $itemElement
207 9
				->copy()
208
				->addClass($this->_optionArray['className']['item']['uninstall'])
209
				->html(
210
					$linkElement
211 9
						->copy()
212
						->addClass($this->_optionArray['className']['link']['uninstall'])
213
						->attr('href', $parameterRoute . 'admin/uninstall/' . $table . '/' . $alias . '/' . $token)
214
						->text($this->_language->get('uninstall'))
0 ignored issues
show
Bug introduced by redaxmedia
It seems like $this->_language->get('uninstall') 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...
215
				);
216
		}
217 9
218
		/* collect output */
219
220
		if ($outputItem)
0 ignored issues
show
Bug Best Practice introduced by redaxmedia
The expression $outputItem of type string|null is loosely compared to true; this is ambiguous if the string can be empty. 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 string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
221
		{
222
			$output .= $listElement->html($outputItem);
223
		}
224 9
		$output .= Module\Hook::trigger('adminControlEnd');
225
		return $output;
226
	}
227
228
	/**
229
	 * has the permission
230
	 *
231 9
	 * @since 4.0.0
232
	 *
233 1
	 * @param string $table name of the table
234
	 * @param string $type
235 9
	 *
236 9
	 * @return bool
237 9
	 */
238 8
239 7
	protected function _hasPermission(string $table = null, string $type = null) : bool
240 9
	{
241
		return (bool)$this->_registry->get($table . ucfirst($type));
242
	}
243
244
	/**
245
	 * show the action
246
	 *
247
	 * @since 4.0.0
248
	 *
249
	 * @param string $table name of the table
250
	 * @param string $type
251
	 * @param int $id
252
	 *
253
	 * @return bool
254
	 */
255
256
	protected function _showAction(string $table = null, string $type = null, int $id = null) : bool
257
	{
258
		$enableArray =
259
		[
260
			'groups',
261
			'users',
262
			'modules'
263
		];
264
		$publishArray =
265
		[
266
			'categories',
267
			'articles',
268
			'extras',
269
			'comments'
270
		];
271
		$deleteArray =
272
		[
273
			'categories',
274
			'articles',
275
			'extras',
276
			'comments',
277
			'groups',
278
			'users'
279
		];
280
		if ($id === 1 && ($type === 'enable' || $type === 'delete') && ($table === 'users' || $table === 'groups'))
281
		{
282
			return false;
283
		}
284
		return $type === 'enable' && in_array($table, $enableArray) && $id ||
0 ignored issues
show
Bug Best Practice introduced by redaxmedia
The expression $id 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...
285
			$type === 'publish' && in_array($table, $publishArray) && $id ||
0 ignored issues
show
Bug Best Practice introduced by redaxmedia
The expression $id 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...
286
			$type === 'delete' && in_array($table, $deleteArray) && $id ||
0 ignored issues
show
Bug Best Practice introduced by redaxmedia
The expression $id 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...
287
			$type === 'install' && $table === 'modules' && !$id ||
0 ignored issues
show
Bug Best Practice introduced by redaxmedia
The expression $id of type null|integer is loosely compared to false; 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...
288
			$type === 'uninstall' && $table === 'modules' && $id ||
0 ignored issues
show
Bug Best Practice introduced by redaxmedia
The expression $id 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...
289
			$type === 'edit' && $id;
0 ignored issues
show
Bug Best Practice introduced by redaxmedia
The expression $id 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...
290
	}
291
}
292