|
1
|
|
|
<?php |
|
|
|
|
|
|
2
|
|
|
/** |
|
3
|
|
|
* Shortcode Dialog Generator abstract class |
|
4
|
|
|
* |
|
5
|
|
|
* @package Give/Admin |
|
6
|
|
|
* @author Paul Ryley |
|
7
|
|
|
* @copyright Copyright (c) 2016, WordImpress |
|
8
|
|
|
* @license https://opensource.org/licenses/gpl-license GNU Public License |
|
9
|
|
|
* @version 1.0 |
|
10
|
|
|
* @since 1.3 |
|
11
|
|
|
*/ |
|
12
|
|
|
|
|
13
|
|
|
// Exit if accessed directly. |
|
14
|
|
|
if ( ! defined( 'ABSPATH' ) ) { |
|
15
|
|
|
exit; |
|
16
|
|
|
} |
|
17
|
|
|
|
|
18
|
|
|
/** |
|
19
|
|
|
* Class Give_Shortcode_Generator |
|
20
|
|
|
*/ |
|
21
|
|
|
abstract class Give_Shortcode_Generator { |
|
22
|
|
|
|
|
23
|
|
|
/** |
|
24
|
|
|
* The current class name |
|
25
|
|
|
* |
|
26
|
|
|
* @since 1.0 |
|
27
|
|
|
*/ |
|
28
|
|
|
public $self; |
|
29
|
|
|
|
|
30
|
|
|
/** |
|
31
|
|
|
* The current shortcode |
|
32
|
|
|
* |
|
33
|
|
|
* @since 1.0 |
|
34
|
|
|
*/ |
|
35
|
|
|
public $shortcode; |
|
36
|
|
|
|
|
37
|
|
|
/** |
|
38
|
|
|
* The current shortcode tag |
|
39
|
|
|
* |
|
40
|
|
|
* @since 1.0 |
|
41
|
|
|
*/ |
|
42
|
|
|
public $shortcode_tag; |
|
43
|
|
|
|
|
44
|
|
|
/** |
|
45
|
|
|
* Shortcode field errors |
|
46
|
|
|
* |
|
47
|
|
|
* @since 1.0 |
|
48
|
|
|
*/ |
|
49
|
|
|
protected $errors; |
|
50
|
|
|
|
|
51
|
|
|
/** |
|
52
|
|
|
* Required shortcode fields |
|
53
|
|
|
* |
|
54
|
|
|
* @since 1.0 |
|
55
|
|
|
*/ |
|
56
|
|
|
protected $required; |
|
57
|
|
|
|
|
58
|
|
|
/** |
|
59
|
|
|
* Class constructor |
|
60
|
|
|
* |
|
61
|
|
|
* @param string $shortcode The shortcode tag |
|
62
|
|
|
* |
|
63
|
|
|
* @since 1.0 |
|
64
|
|
|
*/ |
|
65
|
|
|
public function __construct( $shortcode ) { |
|
66
|
|
|
|
|
67
|
|
|
$this->shortcode_tag = $shortcode; |
|
68
|
|
|
|
|
69
|
|
|
add_action( 'admin_init', array( $this, 'init' ) ); |
|
70
|
|
|
|
|
71
|
|
|
} |
|
72
|
|
|
|
|
73
|
|
|
/** |
|
74
|
|
|
* Kick things off for the shortcode generator |
|
75
|
|
|
* |
|
76
|
|
|
* @since 1.3.0.2 |
|
77
|
|
|
*/ |
|
78
|
|
|
public function init() { |
|
79
|
|
|
|
|
80
|
|
|
if ( $this->shortcode_tag ) { |
|
81
|
|
|
|
|
82
|
|
|
$this->self = get_class( $this ); |
|
83
|
|
|
|
|
84
|
|
|
$this->errors = array(); |
|
85
|
|
|
$this->required = array(); |
|
86
|
|
|
|
|
87
|
|
|
// Generate the fields, errors, and requirements |
|
88
|
|
|
$fields = $this->get_fields(); |
|
89
|
|
|
|
|
90
|
|
|
$defaults = array( |
|
91
|
|
|
'btn_close' => esc_html__( 'Close', 'give' ), |
|
92
|
|
|
'btn_okay' => esc_html__( 'Insert Shortcode', 'give' ), |
|
93
|
|
|
'errors' => $this->errors, |
|
94
|
|
|
'fields' => $fields, |
|
95
|
|
|
'label' => '[' . $this->shortcode_tag . ']', |
|
96
|
|
|
'required' => $this->required, |
|
97
|
|
|
'title' => esc_html__( 'Insert Shortcode', 'give' ), |
|
98
|
|
|
); |
|
99
|
|
|
|
|
100
|
|
|
if ( user_can_richedit() ) { |
|
101
|
|
|
|
|
102
|
|
|
Give_Shortcode_Button::$shortcodes[ $this->shortcode_tag ] = wp_parse_args( $this->shortcode, $defaults ); |
|
103
|
|
|
|
|
104
|
|
|
} |
|
105
|
|
|
} |
|
106
|
|
|
|
|
107
|
|
|
} |
|
108
|
|
|
|
|
109
|
|
|
|
|
110
|
|
|
/** |
|
111
|
|
|
* Define the shortcode attribute fields |
|
112
|
|
|
* |
|
113
|
|
|
* @return false|array |
|
114
|
|
|
* |
|
115
|
|
|
* @since 1.0 |
|
116
|
|
|
*/ |
|
117
|
|
|
public function define_fields() { |
|
118
|
|
|
|
|
119
|
|
|
return false; |
|
120
|
|
|
} |
|
121
|
|
|
|
|
122
|
|
|
/** |
|
123
|
|
|
* Generate the shortcode dialog fields |
|
124
|
|
|
* |
|
125
|
|
|
* @param array $defined_fields |
|
126
|
|
|
* |
|
127
|
|
|
* @return array |
|
128
|
|
|
* |
|
129
|
|
|
* @since 1.0 |
|
130
|
|
|
*/ |
|
131
|
|
|
protected function generate_fields( $defined_fields ) { |
|
132
|
|
|
|
|
133
|
|
|
$fields = array(); |
|
134
|
|
|
|
|
135
|
|
|
if ( is_array( $defined_fields ) ) { |
|
136
|
|
|
|
|
137
|
|
|
foreach ( $defined_fields as $field ) { |
|
138
|
|
|
|
|
139
|
|
|
$defaults = array( |
|
140
|
|
|
'label' => false, |
|
141
|
|
|
'name' => false, |
|
142
|
|
|
'options' => array(), |
|
143
|
|
|
'placeholder' => false, |
|
144
|
|
|
'tooltip' => false, |
|
145
|
|
|
'type' => '', |
|
146
|
|
|
); |
|
147
|
|
|
|
|
148
|
|
|
$field = wp_parse_args( (array) $field, $defaults ); |
|
149
|
|
|
$method = 'generate_' . strtolower( $field['type'] ); |
|
150
|
|
|
|
|
151
|
|
|
if ( method_exists( $this, $method ) ) { |
|
152
|
|
|
|
|
153
|
|
|
$field = call_user_func( array( $this, $method ), $field ); |
|
154
|
|
|
|
|
155
|
|
|
if ( $field ) { |
|
156
|
|
|
$fields[] = $field; |
|
157
|
|
|
} |
|
158
|
|
|
} |
|
159
|
|
|
} |
|
160
|
|
|
} |
|
161
|
|
|
|
|
162
|
|
|
return $fields; |
|
163
|
|
|
} |
|
164
|
|
|
|
|
165
|
|
|
/** |
|
166
|
|
|
* Get the generated shortcode dialog fields |
|
167
|
|
|
* |
|
168
|
|
|
* @return array |
|
169
|
|
|
* |
|
170
|
|
|
* @since 1.0 |
|
171
|
|
|
*/ |
|
172
|
|
|
protected function get_fields() { |
|
173
|
|
|
|
|
174
|
|
|
$defined_fields = $this->define_fields(); |
|
175
|
|
|
$generated_fields = $this->generate_fields( $defined_fields ); |
|
176
|
|
|
|
|
177
|
|
|
$errors = array(); |
|
178
|
|
|
|
|
179
|
|
|
if ( ! empty( $this->errors ) ) { |
|
180
|
|
|
foreach ( $this->required as $name => $alert ) { |
|
181
|
|
|
if ( false === array_search( $name, array_column( $generated_fields, 'name' ) ) ) { |
|
182
|
|
|
|
|
183
|
|
|
$errors[] = $this->errors[ $name ]; |
|
184
|
|
|
} |
|
185
|
|
|
} |
|
186
|
|
|
|
|
187
|
|
|
$this->errors = $errors; |
|
188
|
|
|
} |
|
189
|
|
|
|
|
190
|
|
|
if ( ! empty( $errors ) ) { |
|
191
|
|
|
|
|
192
|
|
|
return $errors; |
|
193
|
|
|
} |
|
194
|
|
|
|
|
195
|
|
|
return $generated_fields; |
|
196
|
|
|
} |
|
197
|
|
|
|
|
198
|
|
|
/** |
|
199
|
|
|
* Generate a TinyMCE container field |
|
200
|
|
|
* |
|
201
|
|
|
* @param array $field |
|
202
|
|
|
* |
|
203
|
|
|
* @return array|false |
|
204
|
|
|
* |
|
205
|
|
|
* @since 1.0 |
|
206
|
|
|
*/ |
|
207
|
|
|
protected function generate_container( $field ) { |
|
208
|
|
|
|
|
209
|
|
|
if ( array_key_exists( 'html', $field ) ) { |
|
210
|
|
|
|
|
211
|
|
|
return array( |
|
212
|
|
|
'type' => $field['type'], |
|
213
|
|
|
'html' => $field['html'], |
|
214
|
|
|
); |
|
215
|
|
|
} |
|
216
|
|
|
|
|
217
|
|
|
return false; |
|
218
|
|
|
} |
|
219
|
|
|
|
|
220
|
|
|
/** |
|
221
|
|
|
* Generate a TinyMCE listbox field |
|
222
|
|
|
* |
|
223
|
|
|
* @param array $field |
|
224
|
|
|
* |
|
225
|
|
|
* @return array|false |
|
226
|
|
|
* |
|
227
|
|
|
* @since 1.0 |
|
228
|
|
|
*/ |
|
229
|
|
|
protected function generate_listbox( $field ) { |
|
230
|
|
|
|
|
231
|
|
|
$listbox = shortcode_atts( array( |
|
232
|
|
|
'label' => '', |
|
233
|
|
|
'minWidth' => '', |
|
234
|
|
|
'name' => false, |
|
235
|
|
|
'tooltip' => '', |
|
236
|
|
|
'type' => '', |
|
237
|
|
|
'value' => '', |
|
238
|
|
|
'classes' => '' |
|
239
|
|
|
), $field ); |
|
240
|
|
|
|
|
241
|
|
|
if ( $this->validate( $field ) ) { |
|
242
|
|
|
|
|
243
|
|
|
$new_listbox = array(); |
|
244
|
|
|
|
|
245
|
|
|
foreach ( $listbox as $key => $value ) { |
|
246
|
|
|
|
|
247
|
|
|
if ( $key == 'value' && empty( $value ) ) { |
|
248
|
|
|
$new_listbox[ $key ] = $listbox['name']; |
|
249
|
|
|
} else if ( $value ) { |
|
250
|
|
|
$new_listbox[ $key ] = $value; |
|
251
|
|
|
} |
|
252
|
|
|
} |
|
253
|
|
|
|
|
254
|
|
|
// do not reindex array! |
|
255
|
|
|
$field['options'] = array( |
|
256
|
|
|
'' => ( $field['placeholder'] ? $field['placeholder'] : esc_attr__( '- Select -', 'give' ) ), |
|
257
|
|
|
) + $field['options']; |
|
258
|
|
|
|
|
259
|
|
|
foreach ( $field['options'] as $value => $text ) { |
|
260
|
|
|
$new_listbox['values'][] = array( |
|
261
|
|
|
'text' => $text, |
|
262
|
|
|
'value' => $value, |
|
263
|
|
|
); |
|
264
|
|
|
} |
|
265
|
|
|
|
|
266
|
|
|
return $new_listbox; |
|
267
|
|
|
} |
|
268
|
|
|
|
|
269
|
|
|
return false; |
|
270
|
|
|
} |
|
271
|
|
|
|
|
272
|
|
|
/** |
|
273
|
|
|
* Generate a TinyMCE listbox field for a post_type |
|
274
|
|
|
* |
|
275
|
|
|
* @param array $field |
|
276
|
|
|
* |
|
277
|
|
|
* @return array|false |
|
278
|
|
|
* |
|
279
|
|
|
* @since 1.0 |
|
280
|
|
|
*/ |
|
281
|
|
|
protected function generate_post( $field ) { |
|
282
|
|
|
|
|
283
|
|
|
$args = array( |
|
284
|
|
|
'post_type' => 'post', |
|
285
|
|
|
'orderby' => 'title', |
|
286
|
|
|
'order' => 'ASC', |
|
287
|
|
|
'posts_per_page' => 30, |
|
288
|
|
|
); |
|
289
|
|
|
|
|
290
|
|
|
$args = wp_parse_args( (array) $field['query_args'], $args ); |
|
291
|
|
|
$posts = get_posts( $args ); |
|
292
|
|
|
$options = array(); |
|
293
|
|
|
|
|
294
|
|
|
if ( $posts ) { |
|
295
|
|
|
foreach ( $posts as $post ) { |
|
296
|
|
|
$options[ absint( $post->ID ) ] = ( empty( $post->post_title ) ? sprintf( __( 'Untitled (#%s)', 'give' ), $post->ID ) : $post->post_title ); |
|
297
|
|
|
} |
|
298
|
|
|
|
|
299
|
|
|
$field['type'] = 'listbox'; |
|
300
|
|
|
$field['options'] = $options; |
|
301
|
|
|
|
|
302
|
|
|
return $this->generate_listbox( $field ); |
|
303
|
|
|
} |
|
304
|
|
|
|
|
305
|
|
|
// perform validation here before returning false |
|
306
|
|
|
$this->validate( $field ); |
|
307
|
|
|
|
|
308
|
|
|
return false; |
|
309
|
|
|
} |
|
310
|
|
|
|
|
311
|
|
|
/** |
|
312
|
|
|
* Generate a TinyMCE textbox field |
|
313
|
|
|
* |
|
314
|
|
|
* @param array $field |
|
315
|
|
|
* |
|
316
|
|
|
* @return array|false |
|
317
|
|
|
* |
|
318
|
|
|
* @since 1.0 |
|
319
|
|
|
*/ |
|
320
|
|
|
protected function generate_textbox( $field ) { |
|
321
|
|
|
|
|
322
|
|
|
$textbox = shortcode_atts( array( |
|
323
|
|
|
'label' => '', |
|
324
|
|
|
'maxLength' => '', |
|
325
|
|
|
'minHeight' => '', |
|
326
|
|
|
'minWidth' => '', |
|
327
|
|
|
'multiline' => false, |
|
328
|
|
|
'name' => false, |
|
329
|
|
|
'tooltip' => '', |
|
330
|
|
|
'type' => '', |
|
331
|
|
|
'value' => '', |
|
332
|
|
|
'classes' => '' |
|
333
|
|
|
), $field ); |
|
334
|
|
|
|
|
335
|
|
|
if ( $this->validate( $field ) ) { |
|
336
|
|
|
return array_filter( $textbox, array( $this, 'return_textbox_value' ) ); |
|
337
|
|
|
} |
|
338
|
|
|
|
|
339
|
|
|
return false; |
|
340
|
|
|
} |
|
341
|
|
|
|
|
342
|
|
|
/** |
|
343
|
|
|
* Validate Textbox Value |
|
344
|
|
|
* |
|
345
|
|
|
* @param $value |
|
346
|
|
|
* |
|
347
|
|
|
* @return bool |
|
348
|
|
|
*/ |
|
349
|
|
|
function return_textbox_value( $value ) { |
|
|
|
|
|
|
350
|
|
|
return $value !== ''; |
|
351
|
|
|
} |
|
352
|
|
|
|
|
353
|
|
|
/** |
|
354
|
|
|
* Perform validation for a single field |
|
355
|
|
|
* |
|
356
|
|
|
* Returns true or false depending on whether the field has a 'name' attribute. |
|
357
|
|
|
* This method also populates the shortcode's $errors and $required arrays. |
|
358
|
|
|
* |
|
359
|
|
|
* @param array $field |
|
360
|
|
|
* |
|
361
|
|
|
* @return bool |
|
362
|
|
|
* |
|
363
|
|
|
* @since 1.0 |
|
364
|
|
|
*/ |
|
365
|
|
|
protected function validate( $field ) { |
|
366
|
|
|
|
|
367
|
|
|
extract( shortcode_atts( |
|
|
|
|
|
|
368
|
|
|
array( |
|
369
|
|
|
'name' => false, |
|
370
|
|
|
'required' => false, |
|
371
|
|
|
'label' => '', |
|
372
|
|
|
), $field ) |
|
373
|
|
|
); |
|
374
|
|
|
|
|
375
|
|
|
if ( $name ) { |
|
376
|
|
|
|
|
377
|
|
|
if ( isset( $required['error'] ) ) { |
|
378
|
|
|
|
|
379
|
|
|
$error = array( |
|
380
|
|
|
'type' => 'container', |
|
381
|
|
|
'html' => $required['error'], |
|
382
|
|
|
); |
|
383
|
|
|
|
|
384
|
|
|
$this->errors[ $name ] = $this->generate_container( $error ); |
|
385
|
|
|
} |
|
386
|
|
|
|
|
387
|
|
|
if ( ! ! $required || is_array( $required ) ) { |
|
388
|
|
|
|
|
389
|
|
|
$alert = esc_html__( 'Some of the shortcode options are required.', 'give' ); |
|
390
|
|
|
|
|
391
|
|
|
if ( isset( $required['alert'] ) ) { |
|
392
|
|
|
|
|
393
|
|
|
$alert = $required['alert']; |
|
394
|
|
|
|
|
395
|
|
|
} else if ( ! empty( $label ) ) { |
|
396
|
|
|
|
|
397
|
|
|
$alert = sprintf( |
|
398
|
|
|
/* translators: %s: option label */ |
|
399
|
|
|
esc_html__( 'The "%s" option is required.', 'give' ), |
|
400
|
|
|
str_replace( ':', '', $label ) |
|
401
|
|
|
); |
|
402
|
|
|
} |
|
403
|
|
|
|
|
404
|
|
|
$this->required[ $name ] = $alert; |
|
405
|
|
|
} |
|
406
|
|
|
|
|
407
|
|
|
return true; |
|
408
|
|
|
} |
|
409
|
|
|
|
|
410
|
|
|
return false; |
|
411
|
|
|
} |
|
412
|
|
|
} |
|
413
|
|
|
|
The PSR-1: Basic Coding Standard recommends that a file should either introduce new symbols, that is classes, functions, constants or similar, or have side effects. Side effects are anything that executes logic, like for example printing output, changing ini settings or writing to a file.
The idea behind this recommendation is that merely auto-loading a class should not change the state of an application. It also promotes a cleaner style of programming and makes your code less prone to errors, because the logic is not spread out all over the place.
To learn more about the PSR-1, please see the PHP-FIG site on the PSR-1.