Completed
Push — master ( 402a90...134b49 )
by Henry
16:11
created

includes/Messenger.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;
3
4
/**
5
 * parent class to create a flash message
6
 *
7
 * @since 3.0.0
8
 *
9
 * @package Redaxscript
10
 * @category Messenger
11
 * @author Henry Ruhs
12
 * @author Balázs Szilágyi
13
 */
14
15
class Messenger
16
{
17
	/**
18
	 * instance of the registry class
19
	 *
20
	 * @var Registry
21
	 */
22
23
	protected $_registry;
24
25
	/**
26
	 * array of the action
27
	 *
28
	 * @var array
29
	 */
30
31
	protected $_actionArray =
32
	[
33
		'text' => null,
34
		'route' => null,
35
		'url' => null
36
	];
37
38
	/**
39
	 * options of the messenger
40
	 *
41
	 * @var array
42
	 */
43
44
	protected $_optionArray =
45
	[
46
		'className' =>
47
		[
48
			'box' => ' rs-box-note rs-fn-clearfix',
49
			'title' => 'rs-title-note',
50
			'list' => 'rs-list-note',
51
			'link' => 'rs-button-note',
52
			'redirect' => 'rs-meta-redirect',
53
			'note' =>
54
			[
55
				'success' => 'rs-is-success',
56
				'warning' => 'rs-is-warning',
57
				'error' => 'rs-is-error',
58
				'info' => 'rs-is-info'
59
			]
60
		]
61
	];
62
63
	/**
64
	 * constructor of the class
65
	 *
66
	 * @since 2.4.0
67
	 *
68
	 * @param Registry $registry instance of the registry class
69
	 */
70
71 16
	public function __construct(Registry $registry)
72
	{
73 16
		$this->_registry = $registry;
74 16
	}
75
76
	/**
77
	 * init the class
78
	 *
79
	 * @since 3.0.0
80
	 *
81
	 * @param array $optionArray options of the messenger
82
	 *
83
	 * @return self
84
	 */
85
86 4
	public function init(array $optionArray = []) : self
87
	{
88 4
		$this->_optionArray = array_replace_recursive($this->_optionArray, $optionArray);
89 4
		return $this;
90
	}
91
92
	/**
93
	 * set the absolute redirect url
94
	 *
95
	 * @since 3.0.0
96
	 *
97
	 * @param string $text text of the action
98
	 * @param string $url absolute url of the action
99
	 *
100
	 * @return self
101
	 */
102
103 4
	public function setUrl(string $text = null, string $url = null) : self
104
	{
105 4
		if (strlen($text) && strlen($url))
106
		{
107 2
			$this->_actionArray['text'] = $text;
108 2
			$this->_actionArray['route'] = null;
109 2
			$this->_actionArray['url'] = $url;
110
		}
111 4
		return $this;
112
	}
113
114
	/**
115
	 * set the relative redirect url
116
	 *
117
	 * @since 3.0.0
118
	 *
119
	 * @param string $text text of the action
120
	 * @param string $route relative route of the action
121
	 *
122
	 * @return self
123
	 */
124
125 12
	public function setRoute(string $text = null, string $route = null) : self
126
	{
127 12
		if (strlen($text) && strlen($route))
128
		{
129 4
			$this->_actionArray['text'] = $text;
130 4
			$this->_actionArray['route'] = $route;
131 4
			$this->_actionArray['url'] = null;
132
		}
133 12
		return $this;
134
	}
135
136
	/**
137
	 * do the redirect
138
	 *
139
	 * @since 3.0.0
140
	 *
141
	 * @param int $timeout timeout of the redirect
142
	 *
143
	 * @return self
144
	 */
145
146 4
	public function doRedirect(int $timeout = 2) : self
147
	{
148 4
		$this->_actionArray['redirect'] = $timeout;
149 4
		return $this;
150
	}
151
152
	/**
153
	 * success message
154
	 *
155
	 * @since 3.0.0
156
	 *
157
	 * @param string|array $message message of the success
158
	 * @param string $title title of the success
159
	 *
160
	 * @return string
161
	 */
162
163 3
	public function success($message = null, string $title = null) : string
164
	{
165 3
		return $this->render('success', $message, $title);
166
	}
167
168
	/**
169
	 * info message
170
	 *
171
	 * @since 3.0.0
172
	 *
173
	 * @param string|array $message message of the info
174
	 * @param string $title title of the info
175
	 *
176
	 * @return string
177
	 */
178
179 3
	public function info($message = null, string $title = null) : string
180
	{
181 3
		return $this->render('info', $message, $title);
182
	}
183
184
	/**
185
	 * warning message
186
	 *
187
	 * @since 3.0.0
188
	 *
189
	 * @param string|array $message message of the warning
190
	 * @param string $title message title of the warning
191
	 *
192
	 * @return string
193
	 */
194
195 3
	public function warning($message = null, string $title = null) : string
196
	{
197 3
		return $this->render('warning', $message, $title);
198
	}
199
200
	/**
201
	 * error message
202
	 *
203
	 * @since 3.0.0
204
	 *
205
	 * @param string|array $message message of the error
206
	 * @param string $title title of the error
207
	 *
208
	 * @return string
209
	 */
210
211 3
	public function error($message = null, string $title = null) : string
212
	{
213 3
		return $this->render('error', $message, $title);
214
	}
215
216
	/**
217
	 * render
218
	 *
219
	 * @since 3.0.0
220
	 *
221
	 * @param string $type type of the flash
222
	 * @param string|array $message message of the flash
223
	 * @param string $title title of the flash
224
	 *
225
	 * @return string
226
	 */
227
228 16
	public function render(string $type = null, $message = null, string $title = null) : string
229
	{
230 16
		$output = Module\Hook::trigger('messengerStart');
231
232
		/* html element */
233
234 16
		$element = new Html\Element();
235 16
		if ($title)
0 ignored issues
show
Bug Best Practice introduced by
The expression $title of type null|string 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...
236
		{
237
			$titleElement = $element
238 5
				->copy()
239 5
				->init('h2',
240
				[
241 5
					'class' => $this->_optionArray['className']['title'] . ' ' . $this->_optionArray['className']['note'][$type]
242
				])
243 5
				->text($title);
244
		}
245
		$boxElement = $element
246 16
			->copy()
247 16
			->init('div',
248
			[
249 16
				'class' => $this->_optionArray['className']['box'] . ' ' . $this->_optionArray['className']['note'][$type]
250
			]);
251
252
		/* create a list */
253
254 16
		if (is_array($message) && count($message) > 1)
255
		{
256
			$listElement = $element
257 10
				->copy()
258 10
				->init('ul',
259
				[
260 10
					'class' => $this->_optionArray['className']['list']
261
				]);
262 10
			$itemElement = $element->copy()->init('li');
263
264
			/* collect item output */
265
266 10
			foreach ($message as $value)
267
			{
268
				$listElement
269 10
					->append($itemElement
270 10
					->text($value));
271
			}
272 10
			$boxElement->html($listElement);
273
		}
274
275
		/* else plain text */
276
277
		else
278
		{
279 6
			$boxElement->html(is_array($message) && array_key_exists(0, $message) ? $message[0] : $message);
280
		}
281
282
		/* collect output */
283
284 16
		$output .= $titleElement . $boxElement . $this->_renderAction($type);
0 ignored issues
show
The variable $titleElement does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
285 16
		$output .= Module\Hook::trigger('messengerEnd');
286 16
		return $output;
287
	}
288
289
	/**
290
	 * render action
291
	 *
292
	 * @since 3.0.0
293
	 *
294
	 * @param string $type type of the flash
295
	 *
296
	 * @return string|null
297
	 */
298
299 16
	protected function _renderAction(string $type = null) : ?string
300
	{
301 16
		$output = null;
302 16
		$parameterRoute = $this->_registry->get('parameterRoute');
303 16
		$root = $this->_registry->get('root');
304 16
		if ($this->_actionArray['text'] && ($this->_actionArray['route'] || $this->_actionArray['url']))
305
		{
306 6
			$element = new Html\Element();
307
			$output .= $element
308 6
				->copy()
309 6
				->init('a',
310
				[
311 6
					'href' => $this->_actionArray['route'] ? $parameterRoute . $this->_actionArray['route'] : $this->_actionArray['url'],
312 6
					'class' => $this->_optionArray['className']['link'] . ' ' . $this->_optionArray['className']['note'][$type]
313
				])
314 6
				->text($this->_actionArray['text']);
315
316
			/* meta redirect */
317
318 6
			if (is_numeric($this->_actionArray['redirect']))
319
			{
320
				$output .= $element
321 2
					->copy()
322 2
					->init('meta',
323
					[
324 2
						'class' => $this->_actionArray['redirect'] === 0 ? $this->_optionArray['className']['redirect'] : null,
325 2
						'content' => $this->_actionArray['redirect'] . ';url=' . ($this->_actionArray['route'] ? $root . '/' . $parameterRoute . $this->_actionArray['route'] : $this->_actionArray['url']),
326 2
						'http-equiv' => 'refresh'
327
					]);
328
			}
329
		}
330 16
		return $output;
331
	}
332
}