Completed
Push — master ( 4eb4a8...a52438 )
by Henry
07:48
created

includes/Console/Parser.php (1 issue)

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\Console;
3
4
use Redaxscript\Request;
5
use function array_filter;
6
use function array_key_exists;
7
use function array_shift;
8
use function explode;
9
use function is_array;
10
use function next;
11
use function strpos;
12
use function substr;
13
14
/**
15
 * parent class to parse the command line interface
16
 *
17
 * @since 3.0.0
18
 *
19
 * @package Redaxscript
20
 * @category Console
21
 * @author Henry Ruhs
22
 */
23
24
class Parser
25
{
26
	/**
27
	 * instance of the request class
28
	 *
29
	 * @var Request
30
	 */
31
32
	protected $_request;
33
34
	/**
35
	 * array of parsed arguments
36
	 *
37
	 * @var array
38
	 */
39
40
	protected $_argumentArray = [];
41
42
	/**
43
	 * array of parsed options
44
	 *
45
	 * @var array
46
	 */
47
48
	protected $_optionArray = [];
49
50
	/**
51
	 * constructor of the class
52
	 *
53
	 * @since 3.0.0
54
	 *
55
	 * @param Request $request instance of the request class
56
	 */
57 13
58
	public function __construct(Request $request)
59 13
	{
60 13
		$this->_request = $request;
61
	}
62
63
	/**
64
	 * init the class
65
	 *
66
	 * @param string $mode name of the mode
67
	 *
68
	 * @since 3.0.0
69
	 */
70 11
71
	public function init(string $mode = null) : void
72 11
	{
73
		$argumentArray = [];
74 11
		if ($mode === 'cli')
75 11
		{
76
			$argumentArray = $this->_request->getServer('argv');
77 11
			if (is_array($argumentArray) && array_key_exists(0, $argumentArray))
78
			{
79
				array_shift($argumentArray);
80
			}
81 11
		}
82 11
		if ($mode === 'template')
83
		{
84
			$argumentArray = array_filter(explode(' ', $this->_request->getStream('argv')));
85
		}
86
		$this->_parseArgument($argumentArray);
87
	}
88
89
	/**
90
	 * get the value from arguments
91
	 *
92
	 * @since 3.0.0
93
	 *
94 2
	 * @param string $key key of the item
95
	 *
96 2
	 * @return string|null
97
	 */
98 1
99
	public function getArgument(string $key = null) : ?string
100 1
	{
101
		if (is_array($this->_argumentArray) && array_key_exists($key, $this->_argumentArray))
102
		{
103
			return $this->_argumentArray[$key];
104
		}
105
		return null;
106
	}
107
108
	/**
109
	 * get the array from arguments
110
	 *
111 5
	 * @since 4.0.0
112
	 *
113 5
	 * @return array
114
	 */
115
116
	public function getArgumentArray() : array
117
	{
118
		return $this->_argumentArray;
119
	}
120
121
	/**
122
	 * get the value from options
123
	 *
124
	 * @since 3.0.0
125
	 *
126 2
	 * @param string $key key of the item
127
	 *
128 2
	 * @return string|null
129
	 */
130 1
131
	public function getOption(string $key = null) : ?string
132 1
	{
133
		if (is_array($this->_optionArray) && array_key_exists($key, $this->_optionArray))
134
		{
135
			return $this->_optionArray[$key];
136
		}
137
		return null;
138
	}
139
140
	/**
141
	 * get the array from options
142
	 *
143 4
	 * @since 4.0.0
144
	 *
145 4
	 * @return array
146
	 */
147
148
	public function getOptionArray() : array
149
	{
150
		return $this->_optionArray;
151
	}
152
153
	/**
154
	 * set the value to arguments
155
	 *
156
	 * @since 3.0.0
157 7
	 *
158
	 * @param string $key key of the item
159 7
	 * @param string|int $value value of the item
160 7
	 */
161
162
	public function setArgument(string $key = null, $value = null) : void
163
	{
164
		$this->_argumentArray[$key] = $value;
165
	}
166
167
	/**
168
	 * set the value to options
169
	 *
170
	 * @since 3.0.0
171 5
	 *
172
	 * @param string $key key of the item
173 5
	 * @param string|int $value value of the item
174 5
	 */
175
176
	public function setOption(string $key = null, $value = null) : void
177
	{
178
		$this->_optionArray[$key] = $value;
179
	}
180
181
	/**
182
	 * parse raw argument
183
	 *
184 11
	 * @since 3.0.0
185
	 *
186 11
	 * @param array|null $argumentArray raw argument to be parsed
187 11
	 */
188 11
189
	protected function _parseArgument(?array $argumentArray = []) : void
190 8
	{
191
		$doSkip = false;
192 8
		$argumentKey = 0;
193 8
		if (is_array($argumentArray))
194
		{
195 4
			foreach ($argumentArray as $value)
196 4
			{
197 4
				$next = next($argumentArray);
198 4
				if (strpos($value, '-') === 0)
199
				{
200 8
					$offset = strpos($value, '--') === 0 ? 2 : 1;
201
					$optionArray = $this->_parseOption($value, $next, $offset);
202 6
					$doSkip = $optionArray['value'] === $next;
203
					$this->setOption($optionArray['key'], $optionArray['value']);
204
				}
205
				else if ($value && !$doSkip)
206 11
				{
207
					$this->setArgument($argumentKey++, $value);
208
				}
209
			}
210
		}
211
	}
212
213
	/**
214
	 * parse raw option
215
	 *
216
	 * @since 3.0.0
217
	 *
218
	 * @param string $option raw option to be parsed
219
	 * @param string $next raw next to be parsed
220 4
	 * @param int $offset offset of the raw option
221
	 *
222 4
	 * @return array
223 4
	 */
224
225
	protected function _parseOption(string $option = null, string $next = null, int $offset = null) : array
226
	{
227 4
		$equalPosition = strpos($option, '=');
228 4
		if ($equalPosition)
229
		{
230
			return
231
			[
232
				'key' => substr($option, $offset, $equalPosition - $offset),
233 4
				'value' => substr($option, $equalPosition + 1)
234 4
			];
235
		}
236
		return
237
		[
238
			'key' => substr($option, $offset),
239
			'value' => !$next || strpos($next, '-') === 0 ? true : $next
0 ignored issues
show
Bug Best Practice introduced by
The expression $next of type null|string is loosely compared to false; 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...
240
		];
241
	}
242
}
243