Completed
Push — master ( da58d4...61a0f7 )
by Henry
06:34
created

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