Completed
Push — issues/611 ( 661115...758b1c )
by Ravinder
21:11
created

admin/shortcodes/abstract-shortcode-generator.php (1 issue)

Labels
Severity

Upgrade to new PHP Analysis Engine

These results are based on our legacy PHP analysis, consider migrating to our new PHP analysis engine instead. Learn more

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(
0 ignored issues
show
shortcode_atts(array('na...'label' => ''), $field) cannot be passed to extract() as the parameter $var_array expects a reference.
Loading history...
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