Passed
Push — master ( 9b46a7...ed8579 )
by Paul
03:56
created

TinymcePopupGenerator   A

Complexity

Total Complexity 34

Size/Duplication

Total Lines 255
Duplicated Lines 0 %

Test Coverage

Coverage 67.96%

Importance

Changes 0
Metric Value
eloc 121
dl 0
loc 255
ccs 70
cts 103
cp 0.6796
rs 9.68
c 0
b 0
f 0
wmc 34

13 Methods

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