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( !$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[$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
|
|
|
|
This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.
Consider making the comparison explicit by using
empty(..)
or! empty(...)
instead.