Passed
Push — master ( 6b8ca8...3384db )
by Paul
04:57
created

Builder::buildFormLabel()   A

Complexity

Conditions 3
Paths 2

Size

Total Lines 6
Code Lines 4

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
dl 0
loc 6
ccs 0
cts 5
cp 0
rs 9.4285
c 0
b 0
f 0
cc 3
eloc 4
nc 2
nop 0
crap 12
1
<?php
2
3
namespace GeminiLabs\SiteReviews\Modules\Html;
4
5
use GeminiLabs\SiteReviews\Defaults\BuilderDefaults;
6
use GeminiLabs\SiteReviews\Helper;
7
use GeminiLabs\SiteReviews\Modules\Html\Attributes;
8
9
class Builder
10
{
11
	const INPUT_TYPES = [
12
		'button', 'checkbox', 'date', 'datetime-local', 'email', 'file', 'hidden', 'image', 'month',
13
		'number', 'password', 'radio', 'range', 'reset', 'search', 'submit', 'tel', 'text', 'time',
14
		'url', 'week',
15
	];
16
17
	const TAGS_FORM = [
18
		'input', 'select', 'textarea',
19
	];
20
21
	const TAGS_STRUCTURE = [
22
		'div', 'form', 'nav', 'ol', 'section', 'ul',
23
	];
24
25
	const TAGS_TEXT = [
26
		'a', 'h1', 'h2', 'h3', 'h4', 'h5', 'h6', 'i', 'label', 'li', 'option', 'p', 'pre', 'small',
27
		'span',
28
	];
29
30
	/**
31
	 * @var array
32
	 */
33
	public $args = [];
34
35
	/**
36
	 * @var array
37
	 */
38
	public $globals = [];
39
40
	/**
41
	 * @var bool
42
	 */
43
	public $render = false;
44
45
	/**
46
	 * @var string
47
	 */
48
	public $tag;
49
50
	/**
51
	 * @param
52
	 * @return
0 ignored issues
show
Documentation Bug introduced by
The doc comment @return at position 0 could not be parsed: Unknown type name '@return' at position 0 in @return.
Loading history...
53
	 */
54 7
	public function __construct( array $globals = [] )
55
	{
56 7
		$this->globals = $globals;
57 7
	}
58
59
	/**
60
	 * @param string $method
61
	 * @param array $args
62
	 * @return string|void
63
	 */
64 7
	public function __call( $method, $args )
65
	{
66 7
		$instance = new static();
67 7
		$instance->setTagFromMethod( $method );
68 7
		call_user_func_array( [$instance, 'normalize'], $args += ['',''] );
69 7
		$tags = array_merge( static::TAGS_FORM, static::TAGS_STRUCTURE, static::TAGS_TEXT );
70 7
		$generatedTag = in_array( $instance->tag, $tags )
71 7
			? $instance->buildTag()
72 7
			: $instance->buildCustomField();
73 7
		if( !$this->render ) {
74 7
			return $generatedTag;
75
		}
76
		echo $generatedTag;
77
	}
78
79
	/**
80
	 * @param string $property
81
	 * @param mixed $value
82
	 * @return void
83
	 */
84
	public function __set( $property, $value )
85
	{
86
		$properties = [
87
			'args' => 'is_array',
88
			'globals' => 'is_array',
89
			'render' => 'is_bool',
90
			'tag' => 'is_string',
91
		];
92
		if( !isset( $properties[$property] )
93
			|| empty( array_filter( [$value], $properties[$property] ))
94
		)return;
95
		$this->$property = $value;
96
	}
97
98
	/**
99
	 * @return string
100
	 */
101 7
	public function getClosingTag()
102
	{
103 7
		return '</'.$this->tag.'>';
104
	}
105
106
	/**
107
	 * @return string
108
	 */
109 7
	public function getOpeningTag()
110
	{
111 7
		$attributes = glsr( Attributes::class )->{$this->tag}( $this->args )->toString();
112 7
		return '<'.trim( $this->tag.' '.$attributes ).'>';
113
	}
114
115
	/**
116
	 * @return string|void
117
	 */
118
	protected function buildCustomField()
119
	{
120
		$className = glsr( Helper::class )->buildClassName( $this->tag, __NAMESPACE__.'\Fields' );
121
		if( !class_exists( $className )) {
122
			glsr_log()->error( 'Field missing: '.$className );
123
			return;
124
		}
125
		return (new $className( $this ))->build();
126
	}
127
128
	/**
129
	 * @return string|void
130
	 */
131 7
	protected function buildDefaultTag( $text = '' )
132
	{
133 7
		if( empty( $text )) {
134 7
			$text = $this->args['text'];
135
		}
136 7
		return $this->getOpeningTag().$text.$this->getClosingTag();
137
	}
138
139
	/**
140
	 * @return string|void
141
	 */
142
	protected function buildFieldDescription()
143
	{
144
		if( !empty( $this->args['description'] )) {
145
			return $this->small( $this->args['description'] );
1 ignored issue
show
Bug introduced by
The method small() does not exist on GeminiLabs\SiteReviews\Modules\Html\Builder. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

145
			return $this->/** @scrutinizer ignore-call */ small( $this->args['description'] );
Loading history...
146
		}
147
	}
148
149
	/**
150
	 * @return string|void
151
	 */
152
	protected function buildFormInput()
153
	{
154
		if( !in_array( $this->args['type'], ['checkbox', 'radio'] )) {
155
			return $this->buildFormLabel().$this->getOpeningTag();
156
		}
157
		return empty( $this->args['options'] )
158
			? $this->buildFormInputChoice()
159
			: $this->buildFormInputMultiChoice();
160
	}
161
162
	/**
163
	 * @return string|void
164
	 */
165
	protected function buildFormInputChoice()
166
	{
167
		return $this->label( $this->getOpeningTag().' '.$this->args['text'] );
1 ignored issue
show
Bug introduced by
The method label() does not exist on GeminiLabs\SiteReviews\Modules\Html\Builder. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

167
		return $this->/** @scrutinizer ignore-call */ label( $this->getOpeningTag().' '.$this->args['text'] );
Loading history...
168
	}
169
170
	/**
171
	 * @return string|void
172
	 */
173
	protected function buildFormInputMultiChoice()
174
	{
175
		$options = array_reduce( array_keys( $this->args['options'] ), function( $carry, $key ) {
176
			return $carry.$this->li( $this->{$this->args['type']}([
1 ignored issue
show
Bug introduced by
The method li() does not exist on GeminiLabs\SiteReviews\Modules\Html\Builder. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

176
			return $carry.$this->/** @scrutinizer ignore-call */ li( $this->{$this->args['type']}([
Loading history...
177
				'checked' => in_array( $key, (array)$this->args['value'] ),
178
				'name' => $this->args['name'].'[]',
179
				'text' => $this->args['options'][$key],
180
				'value' => $key,
181
			]));
182
		});
183
		return $this->ul( $options );
1 ignored issue
show
Bug introduced by
The method ul() does not exist on GeminiLabs\SiteReviews\Modules\Html\Builder. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

183
		return $this->/** @scrutinizer ignore-call */ ul( $options );
Loading history...
184
	}
185
186
	/**
187
	 * @return void|string
188
	 */
189
	protected function buildFormLabel()
190
	{
191
		if( empty( $this->args['label'] ) || $this->args['type'] == 'hidden' )return;
192
		return $this->label([
193
			'for' => $this->args['id'],
194
			'text' => $this->args['label'],
195
		]);
196
	}
197
198
	/**
199
	 * @return string|void
200
	 */
201
	protected function buildFormSelect()
202
	{
203
		return $this->buildFormLabel().$this->buildDefaultTag( $this->buildFormSelectOptions() );
204
	}
205
206
	/**
207
	 * @return string|void
208
	 */
209
	protected function buildFormSelectOptions()
210
	{
211
		return array_reduce( array_keys( $this->args['options'] ), function( $carry, $key ) {
212
			return $carry.$this->option([
1 ignored issue
show
Bug introduced by
The method option() does not exist on GeminiLabs\SiteReviews\Modules\Html\Builder. Since you implemented __call, consider adding a @method annotation. ( Ignorable by Annotation )

If this is a false-positive, you can also ignore this issue in your code via the ignore-call  annotation

212
			return $carry.$this->/** @scrutinizer ignore-call */ option([
Loading history...
213
				'selected' => $this->args['value'] == $key,
214
				'text' => $this->args['options'][$key],
215
				'value' => $key,
216
			]);
217
		});
218
	}
219
220
	/**
221
	 * @return string|void
222
	 */
223
	protected function buildFormTextarea()
224
	{
225
		return $this->buildFormLabel().$this->buildDefaultTag();
226
	}
227
228
	/**
229
	 * @return string|void
230
	 */
231 7
	protected function buildTag()
232
	{
233 7
		if( !in_array( $this->tag, static::TAGS_FORM )) {
234 7
			return $this->buildDefaultTag();
235
		}
236
		return call_user_func( [$this, 'buildForm'.ucfirst( $this->tag )] ).$this->buildFieldDescription();
237
	}
238
239
	/**
240
	 * @param string|array ...$params
241
	 * @return void
242
	 */
243 7
	protected function normalize( ...$params )
244
	{
245 7
		if( is_string( $params[0] ) || is_numeric( $params[0] )) {
246 7
			$this->setNameOrTextAttributeForTag( $params[0] );
247
		}
248 7
		if( is_array( $params[0] )) {
249
			$this->args += $params[0];
250
		}
251 7
		else if( is_array( $params[1] )) {
252 7
			$this->args += $params[1];
253
		}
254 7
		$this->args = glsr( BuilderDefaults::class )->merge( $this->args );
255 7
	}
256
257
	/**
258
	 * @param string $value
259
	 * @return void
260
	 */
261 7
	protected function setNameOrTextAttributeForTag( $value )
262
	{
263 7
		$attribute = in_array( $this->tag, static::TAGS_FORM )
264
			? 'name'
265 7
			: 'text';
266 7
		$this->args[$attribute] = $value;
267 7
	}
268
269
	/**
270
	 * @param string $method
271
	 * @return void
272
	 */
273 7
	protected function setTagFromMethod( $method )
274
	{
275 7
		$this->tag = strtolower( $method );
276 7
		if( in_array( $this->tag, static::INPUT_TYPES )) {
277
			$this->args['type'] = $this->tag;
278
			$this->tag = 'input';
279
		}
280 7
	}
281
}
282