Passed
Push — master ( ceec33...d1be46 )
by Paul
05:18
created

Builder   B

Complexity

Total Complexity 39

Size/Duplication

Total Lines 275
Duplicated Lines 0 %

Test Coverage

Coverage 40.2%

Importance

Changes 0
Metric Value
dl 0
loc 275
ccs 41
cts 102
cp 0.402
rs 8.2857
c 0
b 0
f 0
wmc 39

19 Methods

Rating   Name   Duplication   Size   Complexity  
A buildCustomField() 0 8 2
A buildDefaultTag() 0 6 2
A __call() 0 13 3
A getClosingTag() 0 3 1
A __construct() 0 3 1
A getOpeningTag() 0 4 1
A __set() 0 12 3
A buildFormInput() 0 8 3
A buildFieldDescription() 0 7 3
A buildFormInputChoice() 0 3 1
B normalize() 0 12 5
A buildTag() 0 6 2
A buildFormSelect() 0 3 1
A buildFormLabel() 0 6 3
A buildFormTextarea() 0 3 1
A buildFormInputMultiChoice() 0 17 2
A buildFormSelectOptions() 0 7 1
A setNameOrTextAttributeForTag() 0 6 2
A setTagFromMethod() 0 6 2
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 7
	public function __construct( array $globals = [] )
51
	{
52 7
		$this->globals = $globals;
53 7
	}
54
55
	/**
56
	 * @param string $method
57
	 * @param array $args
58
	 * @return string|void
59
	 */
60 7
	public function __call( $method, $args )
61
	{
62 7
		$instance = new static( $this->globals );
63 7
		$instance->setTagFromMethod( $method );
64 7
		call_user_func_array( [$instance, 'normalize'], $args += ['',''] );
65 7
		$tags = array_merge( static::TAGS_FORM, static::TAGS_STRUCTURE, static::TAGS_TEXT );
66 7
		$generatedTag = in_array( $instance->tag, $tags )
67 7
			? $instance->buildTag()
68 7
			: $instance->buildCustomField();
69 7
		if( !$this->render ) {
70 7
			return $generatedTag;
71
		}
72
		echo $generatedTag;
73
	}
74
75
	/**
76
	 * @param string $property
77
	 * @param mixed $value
78
	 * @return void
79
	 */
80
	public function __set( $property, $value )
81
	{
82
		$properties = [
83
			'args' => 'is_array',
84
			'globals' => 'is_array',
85
			'render' => 'is_bool',
86
			'tag' => 'is_string',
87
		];
88
		if( !isset( $properties[$property] )
89
			|| empty( array_filter( [$value], $properties[$property] ))
90
		)return;
91
		$this->$property = $value;
92
	}
93
94
	/**
95
	 * @return string
96
	 */
97 7
	public function getClosingTag()
98
	{
99 7
		return '</'.$this->tag.'>';
100
	}
101
102
	/**
103
	 * @return string
104
	 */
105 7
	public function getOpeningTag()
106
	{
107 7
		$attributes = glsr( Attributes::class )->{$this->tag}( $this->args )->toString();
108 7
		return '<'.trim( $this->tag.' '.$attributes ).'>';
109
	}
110
111
	/**
112
	 * @return string|void
113
	 */
114
	protected function buildCustomField()
115
	{
116
		$className = glsr( Helper::class )->buildClassName( $this->tag, __NAMESPACE__.'\Fields' );
117
		if( !class_exists( $className )) {
118
			glsr_log()->error( 'Field missing: '.$className );
119
			return;
120
		}
121
		return (new $className( $this ))->build();
122
	}
123
124
	/**
125
	 * @return string|void
126
	 */
127 7
	protected function buildDefaultTag( $text = '' )
128
	{
129 7
		if( empty( $text )) {
130 7
			$text = $this->args['text'];
131
		}
132 7
		return $this->getOpeningTag().$text.$this->getClosingTag();
133
	}
134
135
	/**
136
	 * @return string|void
137
	 */
138
	protected function buildFieldDescription()
139
	{
140
		if( empty( $this->args['description'] ))return;
141
		if( !empty( $this->globals['is_widget'] )) {
142
			return $this->small( $this->args['description'] );
143
		}
144
		return $this->p( $this->args['description'], ['class' => 'description'] );
145
	}
146
147
	/**
148
	 * @return string|void
149
	 */
150
	protected function buildFormInput()
151
	{
152
		if( !in_array( $this->args['type'], ['checkbox', 'radio'] )) {
153
			return $this->buildFormLabel().$this->getOpeningTag();
154
		}
155
		return empty( $this->args['options'] )
156
			? $this->buildFormInputChoice()
157
			: $this->buildFormInputMultiChoice();
158
	}
159
160
	/**
161
	 * @return string|void
162
	 */
163
	protected function buildFormInputChoice()
164
	{
165
		return $this->label( $this->getOpeningTag().' '.$this->args['text'] );
166
	}
167
168
	/**
169
	 * @return string|void
170
	 */
171
	protected function buildFormInputMultiChoice()
172
	{
173
		if( $this->args['type'] == 'checkbox' ) {
174
			$this->args['name'].= '[]';
175
		}
176
		// glsr_log( $this->args );
0 ignored issues
show
Unused Code Comprehensibility introduced by
50% of this comment could be valid code. Did you maybe forget this after debugging?

Sometimes obsolete code just ends up commented out instead of removed. In this case it is better to remove the code once you have checked you do not need it.

The code might also have been commented out for debugging purposes. In this case it is vital that someone uncomments it again or your project may behave in very unexpected ways in production.

This check looks for comments that seem to be mostly valid code and reports them.

Loading history...
177
		$options = array_reduce( array_keys( $this->args['options'] ), function( $carry, $key ) {
178
			return $carry.$this->li( $this->{$this->args['type']}([
179
				'checked' => in_array( $key, (array)$this->args['value'] ),
180
				'name' => $this->args['name'],
181
				'text' => $this->args['options'][$key],
182
				'value' => $key,
183
			]));
184
		});
185
		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

185
		return $this->/** @scrutinizer ignore-call */ ul( $options, [
Loading history...
186
			'class' => $this->args['class'],
187
			'id' => $this->args['id'],
188
		]);
189
	}
190
191
	/**
192
	 * @return void|string
193
	 */
194
	protected function buildFormLabel()
195
	{
196
		if( empty( $this->args['label'] ) || $this->args['type'] == 'hidden' )return;
197
		return $this->label([
198
			'for' => $this->args['id'],
199
			'text' => $this->args['label'],
200
		]);
201
	}
202
203
	/**
204
	 * @return string|void
205
	 */
206
	protected function buildFormSelect()
207
	{
208
		return $this->buildFormLabel().$this->buildDefaultTag( $this->buildFormSelectOptions() );
209
	}
210
211
	/**
212
	 * @return string|void
213
	 */
214
	protected function buildFormSelectOptions()
215
	{
216
		return array_reduce( array_keys( $this->args['options'] ), function( $carry, $key ) {
217
			return $carry.$this->option([
218
				'selected' => $this->args['value'] == $key,
219
				'text' => $this->args['options'][$key],
220
				'value' => $key,
221
			]);
222
		});
223
	}
224
225
	/**
226
	 * @return string|void
227
	 */
228
	protected function buildFormTextarea()
229
	{
230
		return $this->buildFormLabel().$this->buildDefaultTag( $this->args['value'] );
231
	}
232
233
	/**
234
	 * @return string|void
235
	 */
236 7
	protected function buildTag()
237
	{
238 7
		if( !in_array( $this->tag, static::TAGS_FORM )) {
239 7
			return $this->buildDefaultTag();
240
		}
241
		return call_user_func( [$this, 'buildForm'.ucfirst( $this->tag )] ).$this->buildFieldDescription();
242
	}
243
244
	/**
245
	 * @param string|array ...$params
246
	 * @return void
247
	 */
248 7
	protected function normalize( ...$params )
249
	{
250 7
		if( is_string( $params[0] ) || is_numeric( $params[0] )) {
251 7
			$this->setNameOrTextAttributeForTag( $params[0] );
252
		}
253 7
		if( is_array( $params[0] )) {
254
			$this->args += $params[0];
255
		}
256 7
		else if( is_array( $params[1] )) {
257 7
			$this->args += $params[1];
258
		}
259 7
		$this->args = glsr( BuilderDefaults::class )->merge( $this->args );
260 7
	}
261
262
	/**
263
	 * @param string $value
264
	 * @return void
265
	 */
266 7
	protected function setNameOrTextAttributeForTag( $value )
267
	{
268 7
		$attribute = in_array( $this->tag, static::TAGS_FORM )
269
			? 'name'
270 7
			: 'text';
271 7
		$this->args[$attribute] = $value;
272 7
	}
273
274
	/**
275
	 * @param string $method
276
	 * @return void
277
	 */
278 7
	protected function setTagFromMethod( $method )
279
	{
280 7
		$this->tag = strtolower( $method );
281 7
		if( in_array( $this->tag, static::INPUT_TYPES )) {
282
			$this->args['type'] = $this->tag;
283
			$this->tag = 'input';
284
		}
285 7
	}
286
}
287