Test Failed
Push — master ( e52611...5d5118 )
by Paul
04:30
created

ButtonGenerator::validateRequired()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 17
Code Lines 11

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
cc 4
eloc 11
nc 4
nop 1
dl 0
loc 17
ccs 0
cts 12
cp 0
crap 20
rs 9.9
c 0
b 0
f 0
1
<?php
2
3
namespace GeminiLabs\SiteReviews\Shortcodes;
4
5
use GeminiLabs\SiteReviews\Database;
6
use GeminiLabs\SiteReviews\Shortcodes\ButtonGenerator;
7
8
abstract class ButtonGenerator
9
{
10
	/**
11
	 * @var array
12
	 */
13
	public $properties;
14
15
	/**
16
	 * @var string
17
	 */
18
	public $tag;
19
20
	/**
21
	 * @var array
22
	 */
23
	protected $errors = [];
24
25
	/**
26
	 * @var array
27
	 */
28
	protected $required = [];
29
30
	/**
31
	 * @return array
32
	 */
33
	abstract public function fields();
34
35
	/**
36
	 * @param string $tag
37
	 * @return static
38
	 */
39
	public function register( $tag, array $args )
40
	{
41
		$this->tag = $tag;
42
		$this->properties = wp_parse_args( $args, [
43
			'btn_close' => esc_html__( 'Close', 'site-reviews' ),
44
			'btn_okay' => esc_html__( 'Insert Shortcode', 'site-reviews' ),
45
			'errors' => $this->errors,
46
			'fields' => $this->getFields(),
47
			'label' => '['.$tag.']',
48
			'required' => $this->required,
49
			'title' => esc_html__( 'Shortcode', 'site-reviews' ),
50
		]);
51
		return $this;
52
	}
53
54
	/**
55
	 * @return array
56
	 */
57
	protected function generateFields( array $fields )
58
	{
59
		$generatedFields = array_map( function( $field ) {
60
			if( empty( $field ))return;
61
			$field = $this->normalize( $field );
62
			if( !method_exists( $this, $method = 'normalize'.ucfirst( $field['type'] )))return;
63
			return $this->$method( $field );
64
		}, $fields );
65
		return array_values( array_filter( $generatedFields ));
66
	}
67
68
	/**
69
	 * @return array
70
	 */
71
	protected function getFields()
72
	{
73
		$fields = $this->generateFields( $this->fields() );
74
		if( !empty( $this->errors )) {
75
			$errors = [];
76
			foreach( $this->required as $name => $alert ) {
77
				if( false !== array_search( $name, array_column( $fields, 'name' )))continue;
78
				$errors[] = $this->errors[$name];
79
			}
80
			$this->errors = $errors;
81
		}
82
		return empty( $this->errors )
83
			? $fields
84
			: $this->errors;
85
	}
86
87
	/**
88
	 * @return array
89
	 */
90
	protected function normalize( array $field )
91
	{
92
		return wp_parse_args( $field, [
93
			'items' => [],
94
			'type' => '',
95
		]);
96
	}
97
98
	/**
99
	 * @return void|array
100
	 */
101
	protected function normalizeCheckbox( array $field )
102
	{
103
		return $this->normalizeField( $field, [
104
			'checked' => false,
105
			'label' => '',
106
			'minHeight' => '',
107
			'minWidth' => '',
108
			'name' => false,
109
			'text' => '',
110
			'tooltip' => '',
111
			'type' => '',
112
			'value' => '',
113
		]);
114
	}
115
116
	/**
117
	 * @return void|array
118
	 */
119
	protected function normalizeContainer( array $field )
120
	{
121
		if( !array_key_exists( 'html', $field ) && !array_key_exists( 'items', $field ))return;
122
		$field['items'] = $this->generateFields( $field['items'] );
123
		return $field;
124
	}
125
126
	/**
127
	 * @return void|array
128
	 */
129
	protected function normalizeField( array $field, array $defaults )
130
	{
131
		if( !$this->validate( $field ))return;
132
		return array_filter( shortcode_atts( $defaults, $field ), function( $value ) {
133
			return $value !== '';
134
		});
135
	}
136
137
	/**
138
	 * @return void|array
139
	 */
140
	protected function normalizeListbox( array $field )
141
	{
142
		$listbox = $this->normalizeField( $field, [
143
			'label' => '',
144
			'minWidth' => '',
145
			'name' => false,
146
			'options' => [],
147
			'placeholder' => esc_attr__( '- Select -', 'site-reviews' ),
148
			'tooltip' => '',
149
			'type' => '',
150
			'value' => '',
151
		]);
152
		if( !is_array( $listbox ))return;
153
		if( !array_key_exists( '', $listbox['options'] )) {
154
			$listbox['options'] = ['' => $listbox['placeholder']] + $listbox['options'];
155
		}
156
		foreach( $listbox['options'] as $value => $text ) {
157
			$listbox['values'][] = [
158
				'text' => $text,
159
				'value' => $value,
160
			];
161
		}
162
		return $listbox;
163
	}
164
165
	/**
166
	 * @return void|array
167
	 */
168
	protected function normalizePost( array $field )
169
	{
170
		if( !is_array( $field['query_args'] )) {
171
			$field['query_args'] = [];
172
		}
173
		$posts = get_posts( wp_parse_args( $field['query_args'], [
174
			'order' => 'ASC',
175
			'orderby' => 'title',
176
			'post_type' => 'post',
177
			'posts_per_page' => 30,
178
		]));
179
		if( !empty( $posts )) {
180
			$options = [];
181
			foreach( $posts as $post ) {
182
				$options[$post->ID] = esc_html( $post->post_title );
183
			}
184
			$field['options'] = $options;
185
			$field['type'] = 'listbox';
186
			return $this->normalizeListbox( $field );
187
		}
188
		$this->validate( $field );
189
	}
190
191
	/**
192
	 * @return void|array
193
	 */
194
	protected function normalizeTextbox( array $field )
195
	{
196
		return $this->normalizeField( $field, [
197
			'hidden' => false,
198
			'label' => '',
199
			'maxLength' => '',
200
			'minHeight' => '',
201
			'minWidth' => '',
202
			'multiline' => false,
203
			'name' => false,
204
			'size' => '',
205
			'text' => '',
206
			'tooltip' => '',
207
			'type' => '',
208
			'value' => '',
209
		]);
210
	}
211
212
	/**
213
	 * @return bool
214
	 */
215
	protected function validate( array $field )
216
	{
217
		$args = shortcode_atts([
218
			'label' => '',
219
			'name' => false,
220
			'required' => false,
221
		], $field );
222
		if( !$args['name'] ) {
223
			return false;
224
		}
225
		return $this->validateErrors( $args ) && $this->validateRequired( $args );
226
	}
227
228
	/**
229
	 * @return bool
230
	 */
231
	protected function validateErrors( array $args )
232
	{
233
		if( !isset( $args['required']['error'] )) {
234
			return true;
235
		}
236
		$this->errors[$args['name']] = $this->normalizeContainer([
237
			'html' => $args['required']['error'],
238
			'type' => 'container',
239
		]);
240
		return false;
241
	}
242
243
	/**
244
	 * @return bool
245
	 */
246
	protected function validateRequired( array $args )
247
	{
248
		if( $args['required'] == false ) {
249
			return true;
250
		}
251
		$alert = esc_html__( 'Some of the shortcode options are required.', 'site-reviews' );
252
		if( isset( $args['required']['alert'] )) {
253
			$alert = $args['required']['alert'];
254
		}
255
		else if( !empty( $args['label'] )) {
256
			$alert = sprintf(
257
				esc_html_x( 'The "%s" option is required.', 'the option label', 'site-reviews' ),
258
				str_replace( ':', '', $args['label'] )
259
			);
260
		}
261
		$this->required[$args['name']] = $alert;
262
		return false;
263
	}
264
}
265