Passed
Push — master ( d8e403...d1c323 )
by Paul
05:05
created

Field::build()   B

Complexity

Conditions 5
Paths 5

Size

Total Lines 13
Code Lines 8

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 30

Importance

Changes 0
Metric Value
cc 5
eloc 8
nc 5
nop 0
dl 0
loc 13
ccs 0
cts 13
cp 0
crap 30
rs 8.8571
c 0
b 0
f 0
1
<?php
2
3
namespace GeminiLabs\SiteReviews\Modules\Html;
4
5
use GeminiLabs\SiteReviews\Application;
6
use GeminiLabs\SiteReviews\Database\OptionManager;
7
use GeminiLabs\SiteReviews\Helper;
8
use GeminiLabs\SiteReviews\Modules\Html\Builder;
9
use GeminiLabs\SiteReviews\Modules\Html\Template;
10
11
class Field
12
{
13
	const MULTI_FIELD_TYPES = ['radio', 'checkbox'];
14
15
	/**
16
	 * @var array
17
	 */
18
	public $field;
19
20
	public function __construct( array $field = [] )
21
	{
22
		$this->field = wp_parse_args( $field, [
23
			'is_hidden' => false,
24
			'is_multi' => false,
25
			'is_setting' => false,
26
			'is_valid' => true,
27
			'path' => '',
28
		]);
29
		$this->normalize();
30
	}
31
32
	/**
33
	 * @return string
34
	 */
35
	public function __toString()
36
	{
37
		return (string)$this->build();
38
	}
39
40
	/**
41
	 * @return string
42
	 */
43
	public function build()
44
	{
45
		if( !$this->field['is_valid'] )return;
46
		if( $this->field['type'] == 'hidden' ) {
47
			return glsr( Builder::class )->hidden( $this->field );
48
		}
49
		if( !$this->field['is_setting'] ) {
50
			return $this->buildField();
51
		}
52
		if( !$this->field['is_multi'] ) {
53
			return $this->buildSettingField();
54
		}
55
		return $this->buildSettingMultiField();
56
	}
57
58
	/**
59
	 * @return void
60
	 */
61
	public function render()
62
	{
63
		echo $this->build();
64
	}
65
66
	/**
67
	 * @return string
68
	 */
69
	protected function buildField()
70
	{
71
		return glsr( Template::class )->build( 'partials/form/field', [
72
			'context' => [
73
				'class' => $this->getFieldClass(),
74
				'field' => glsr( Builder::class )->{$this->field['type']}( $this->field ),
75
			],
76
		]);
77
	}
78
79
	/**
80
	 * @return string
81
	 */
82
	protected function buildSettingField()
83
	{
84
		$this->field['data-depends'] = $this->getFieldDependsOn();
85
		return glsr( Template::class )->build( 'partials/form/table-row', [
86
			'context' => [
87
				'class' => $this->getFieldClass(),
88
				'field' => glsr( Builder::class )->{$this->field['type']}( $this->field ),
89
				'label' => glsr( Builder::class )->label( $this->field['legend'], ['for' => $this->field['id']] ),
90
			],
91
		]);
92
	}
93
94
	/**
95
	 * @return string
96
	 */
97
	protected function buildSettingMultiField()
98
	{
99
		return glsr( Template::class )->build( 'partials/form/table-row-multiple', [
100
			'context' => [
101
				'class' => $this->getFieldClass(),
102
				'depends_on' => $this->getFieldDependsOn(),
103
				'field' => glsr( Builder::class )->{$this->field['type']}( $this->field ),
104
				'label' => glsr( Builder::class )->label( $this->field['legend'], ['for' => $this->field['id']] ),
105
				'legend' => $this->field['legend'],
106
			],
107
		]);
108
	}
109
110
	/**
111
	 * @return string
112
	 */
113
	protected function getFieldClass()
114
	{
115
		$classes = [];
116
		if( $this->field['is_hidden'] ) {
117
			$classes[] = 'hidden';
118
		}
119
		if( !empty( $this->field['required'] )) {
120
			$classes[] = 'glsr-required';
121
		}
122
		return implode( ' ', $classes );
123
	}
124
125
	/**
126
	 * @return string
127
	 */
128
	protected function getFieldDefault()
129
	{
130
		return isset( $this->field['default'] )
131
			? $this->field['default']
132
			: '';
133
	}
134
135
	/**
136
	 * @return string
137
	 */
138
	protected function getFieldDependsOn()
139
	{
140
		return !empty( $this->field['depends_on'] )
141
			? $this->field['depends_on']
142
			: '';
143
	}
144
145
	/**
146
	 * @return string
147
	 */
148
	protected function getFieldPrefix()
149
	{
150
		return $this->field['is_setting']
151
			? OptionManager::databaseKey()
152
			: Application::ID;
153
	}
154
155
	/**
156
	 * @param string $path
157
	 * @param string|array $expectedValue
158
	 * @return bool
159
	 */
160
	protected function isFieldHidden( $path, $expectedValue )
161
	{
162
		$optionValue = glsr( OptionManager::class )->get(
163
			$path,
164
			glsr( Helper::class )->getPathValue( $path, glsr()->defaults )
165
		);
166
		if( is_array( $expectedValue )) {
167
			return !in_array( $optionValue, $expectedValue );
168
		}
169
		return $optionValue != $expectedValue;
170
	}
171
172
	/**
173
	 * @return bool
174
	 */
175
	protected function isFieldValid()
176
	{
177
		$isValid = true;
178
		$missingValues = [];
179
		$requiredValues = [
180
			// 'label', 'name', 'type',
0 ignored issues
show
Unused Code Comprehensibility introduced by
67% 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...
181
			'name', 'type',
182
		];
183
		foreach( $requiredValues as $value ) {
184
			if( isset( $this->field[$value] ))continue;
185
			$missingValues[] = $value;
186
			$isValid = $this->field['is_valid'] = false;
187
		}
188
		if( !empty( $missingValues )) {
189
			glsr_log()
190
				->warning( 'Field is missing: '.implode( ', ', $missingValues ))
191
				->info( $this->field );
192
		}
193
		return $isValid;
194
	}
195
196
	/**
197
	 * @return void
198
	 */
199
	protected function normalize()
200
	{
201
		if( !$this->isFieldValid() )return;
202
		$field = $this->field;
203
		foreach( $field as $key => $value ) {
204
			$methodName = glsr( Helper::class )->buildMethodName( $key, 'normalize' );
205
			if( !method_exists( $this, $methodName ))continue;
206
			$this->$methodName();
207
		}
208
		$this->normalizeFieldId();
209
		$this->normalizeFieldType();
210
		$this->normalizeFieldValue();
211
	}
212
213
	/**
214
	 * @return void
215
	 */
216
	protected function normalizeDependsOn()
217
	{
218
		if( empty( $this->field['depends_on'] ) || !is_array( $this->field['depends_on'] ))return;
219
		$path = key( $this->field['depends_on'] );
220
		$value = $this->field['depends_on'][$path];
221
		$this->field['depends_on'] = json_encode([
222
			'name' => glsr( Helper::class )->convertPathToName( $path, OptionManager::databaseKey() ),
223
			'value' => $value,
224
		], JSON_HEX_APOS|JSON_HEX_QUOT );
225
		$this->field['is_hidden'] = $this->isFieldHidden( $path, $value );
226
	}
227
228
	/**
229
	 * @return void
230
	 */
231
	protected function normalizeFieldId()
232
	{
233
		if( isset( $this->field['id'] ) || empty( $this->field['label'] ))return;
234
		$this->field['id'] = glsr( Helper::class )->convertNameToId( $this->field['name'] );
235
	}
236
237
	/**
238
	 * @return void
239
	 */
240
	protected function normalizeFieldType()
241
	{
242
		$className = glsr( Helper::class )->buildClassName( $this->field['type'], __NAMESPACE__.'\Fields' );
243
		if( class_exists( $className )) {
244
			$this->field = array_merge(
245
				wp_parse_args( $this->field, $className::defaults() ),
246
				$className::required()
247
			);
248
		}
249
		if( in_array( $this->field['type'], static::MULTI_FIELD_TYPES )) {
250
			$this->field['is_multi'] = true;
251
		}
252
	}
253
254
	/**
255
	 * @return void
256
	 */
257
	protected function normalizeFieldValue()
258
	{
259
		if( isset( $this->field['value'] ))return;
260
		$this->field['value'] = glsr( OptionManager::class )->get(
261
			$this->field['path'],
262
			$this->getFieldDefault()
263
		);
264
	}
265
266
	/**
267
	 * @return void
268
	 */
269
	protected function normalizeLabel()
270
	{
271
		if( !$this->field['is_setting'] )return;
272
		$this->field['legend'] = $this->field['label'];
273
		unset( $this->field['label'] );
274
	}
275
276
	/**
277
	 * @return void
278
	 */
279
	protected function normalizeName()
280
	{
281
		$this->field['path'] = $this->field['name'];
282
		$this->field['name'] = glsr( Helper::class )->convertPathToName(
283
			$this->field['name'],
284
			$this->getFieldPrefix()
285
		);
286
	}
287
}
288