PluginProbe ʕ •ᴥ•ʔ
Menu Icons by Themeisle – Add Icons to Navigation Menus / 0.13.24
Menu Icons by Themeisle – Add Icons to Navigation Menus v0.13.24
0.13.24 trunk 0.1.0 0.1.1 0.1.2 0.1.3 0.1.4 0.1.5 0.10.0 0.10.1 0.10.2 0.11.0 0.11.1 0.11.2 0.11.3 0.11.4 0.11.5 0.12.0 0.12.1 0.12.10 0.12.11 0.12.12 0.12.2 0.12.3 0.12.4 0.12.5 0.12.6 0.12.7 0.12.8 0.12.9 0.13.0 0.13.1 0.13.10 0.13.11 0.13.12 0.13.13 0.13.14 0.13.15 0.13.16 0.13.17 0.13.18 0.13.19 0.13.2 0.13.20 0.13.21 0.13.22 0.13.23 0.13.3 0.13.4 0.13.5 0.13.6 0.13.7 0.13.8 0.13.9 0.2.0 0.2.1 0.2.2 0.2.3 0.3.0 0.3.1 0.3.2 0.4.0 0.5.0 0.5.1 0.6.0 0.7.0 0.8.0 0.8.1 0.9.0 0.9.2
menu-icons / includes / library / form-fields.php
menu-icons / includes / library Last commit date
font-awesome 1 year ago compat.php 10 years ago form-fields.php 8 months ago functions.php 8 years ago
form-fields.php
602 lines
1 <?php
2
3 /**
4 * Form Fields
5 *
6 * A prototype for the new "Form Fields" plugin, a standalone plugin and
7 * extension for the upcoming "Settings" plugin, a rewrite of KC Settings.
8 *
9 * @author Dzikri Aziz <kvcrvt@gmail.com>
10 */
11
12 /**
13 * Form Fields
14 */
15 abstract class Kucrut_Form_Field {
16
17 /**
18 * Holds field & argument defaults
19 *
20 * @since 0.1.0
21 * @var array
22 * @access protected
23 */
24 protected static $defaults = array(
25 'field' => array(
26 'id' => '',
27 'type' => 'text',
28 'value' => null,
29 'default' => null,
30 'attributes' => array(),
31 'description' => '',
32 'choices' => array(),
33 ),
34 'args' => array(
35 'keys' => array(),
36 'inline_description' => false,
37 ),
38 );
39
40 /**
41 * Holds field attributes
42 *
43 * @since 0.1.0
44 * @var array
45 * @access protected
46 */
47 protected static $types = array(
48 'text' => 'Kucrut_Form_Field_Text',
49 'number' => 'Kucrut_Form_Field_Text',
50 'url' => 'Kucrut_Form_Field_Text',
51 'color' => 'Kucrut_Form_Field_Text',
52 'date' => 'Kucrut_Form_Field_Text',
53 'hidden' => 'Kucrut_Form_Field_Text',
54 'checkbox' => 'Kucrut_Form_Field_Checkbox',
55 'radio' => 'Kucrut_Form_Field_Radio',
56 'textarea' => 'Kucrut_Form_Field_Textarea',
57 'select' => 'Kucrut_Form_Field_Select',
58 'select_multiple' => 'Kucrut_Form_Field_Select_Multiple',
59 'select_pages' => 'Kucrut_Form_Field_Select_Pages',
60 'special' => 'Kucrut_Form_Field_Special',
61 );
62
63 /**
64 * Holds forbidden attributes
65 *
66 * @since 0.1.0
67 * @var array
68 * @access protected
69 */
70 protected static $forbidden_attributes = array(
71 'id',
72 'name',
73 'value',
74 'checked',
75 'multiple',
76 );
77
78 /**
79 * URL path to this directory
80 *
81 * @since 0.1.0
82 * @var string
83 * @access protected
84 */
85 protected static $url_path;
86
87 /**
88 * Holds allowed html tags
89 *
90 * @since 0.1.0
91 * @var array
92 * @access protected
93 */
94 protected $allowed_html = array(
95 'a' => array(
96 'href' => true,
97 'target' => true,
98 'title' => true,
99 ),
100 'code' => true,
101 'em' => true,
102 'p' => array( 'class' => true ),
103 'span' => array( 'class' => true ),
104 'strong' => true,
105 );
106
107 /**
108 * Holds constructed field
109 *
110 * @since 0.1.0
111 * @var array
112 * @access protected
113 */
114 protected $field;
115
116
117 /**
118 * Holds field attributes
119 *
120 * @since 0.1.0
121 * @var array
122 * @access protected
123 */
124 protected $attributes = array();
125
126 /**
127 * Holds field arguments
128 *
129 * @since 0.1.0
130 * @var stdClass
131 * @access protected
132 */
133 protected $args;
134
135
136 /**
137 * Loader
138 *
139 * @param string URL path to this directory
140 */
141 final public static function load( $url_path = null ) {
142 // Set URL path for assets
143 if ( ! is_null( $url_path ) ) {
144 self::$url_path = $url_path;
145 } else {
146 self::$url_path = plugin_dir_url( __FILE__ );
147 }
148
149 // Supported field types
150 self::$types = apply_filters(
151 'form_field_types',
152 self::$types
153 );
154 }
155
156
157 /**
158 * Create field
159 *
160 * @param array $field Field array
161 * @param array $args Extra field arguments
162 */
163 final public static function create( array $field, $args = array() ) {
164 $field = wp_parse_args( $field, self::$defaults['field'] );
165 if ( ! isset( self::$types[ $field['type'] ] )
166 || ! is_subclass_of( self::$types[ $field['type'] ], __CLASS__ )
167 ) {
168 trigger_error(
169 sprintf(
170 // translators: %1$s - the name of the class, %2$s - the type of the field.
171 esc_html__( '%1$s: Type %2$s is not supported, reverting to text.', 'menu-icons' ),
172 __CLASS__,
173 esc_html( $field['type'] )
174 ),
175 E_USER_WARNING
176 );
177 $field['type'] = 'text';
178 }
179
180 if ( is_null( $field['value'] ) && ! is_null( $field['default'] ) ) {
181 $field['value'] = $field['default'];
182 }
183
184 foreach ( self::$forbidden_attributes as $key ) {
185 unset( $field['attributes'][ $key ] );
186 }
187
188 $args = (object) wp_parse_args( $args, self::$defaults['args'] );
189 $class = self::$types[ $field['type'] ];
190
191 return new $class( $field, $args );
192 }
193
194
195 /**
196 * Constructor
197 *
198 * @since 0.1.0
199 * @param array $field Field array
200 * @param object $args Extra field arguments
201 */
202 public function __construct( $field, $args ) {
203 $this->field = $field;
204 $this->args = $args;
205
206 if ( ! is_array( $this->args->keys ) ) {
207 $this->args->keys = array();
208 }
209 $this->args->keys[] = $field['id'];
210
211 $this->attributes['id'] = $this->create_id();
212 $this->attributes['name'] = $this->create_name();
213
214 $this->attributes = wp_parse_args(
215 $this->attributes,
216 (array) $field['attributes']
217 );
218
219 $this->set_properties();
220 }
221
222
223 /**
224 * Attribute
225 *
226 * @since 0.1.0
227 * @param string $key Attribute key
228 * @return mixed NULL if attribute doesn't exist
229 */
230 public function __get( $key ) {
231 foreach ( array( 'attributes', 'field' ) as $group ) {
232 if ( isset( $this->{$group}[ $key ] ) ) {
233 return $this->{$group}[ $key ];
234 }
235 }
236
237 return null;
238 }
239
240
241 /**
242 * Create id/name attribute
243 *
244 * @since 0.1.0
245 * @param string $format Attribute format
246 */
247 protected function create_id_name( $format ) {
248 return call_user_func_array(
249 'sprintf',
250 array_merge(
251 array( $format ),
252 $this->args->keys
253 )
254 );
255 }
256
257
258 /**
259 * Create id attribute
260 *
261 * @since 0.1.0
262 * @access protected
263 * @return string
264 */
265 protected function create_id() {
266 $format = implode( '-', $this->args->keys );
267
268 return $this->create_id_name( $format );
269 }
270
271
272 /**
273 * Create name attribute
274 *
275 * @since 0.1.0
276 * @access protected
277 * @return string
278 */
279 protected function create_name() {
280 $format = '%s';
281 $format .= str_repeat( '[%s]', ( count( $this->args->keys ) - 1 ) );
282
283 return $this->create_id_name( $format );
284 }
285
286
287 /**
288 * Set field properties
289 *
290 * @since 0.1.0
291 */
292 protected function set_properties() {}
293
294
295 /**
296 * Build field attributes
297 *
298 * @since 0.1.0
299 * @param array $excludes Attributes to be excluded
300 * @return string
301 */
302 protected function build_attributes( $excludes = array() ) {
303 $excludes = array_filter( (array) $excludes );
304 $attributes = '';
305
306 foreach ( $this->attributes as $key => $value ) {
307 if ( in_array( $key, $excludes, true ) ) {
308 continue;
309 }
310
311 if ( 'class' === $key ) {
312 $value = implode( ' ', (array) $value );
313 }
314
315 $attributes .= sprintf(
316 ' %s="%s"',
317 esc_attr( $key ),
318 esc_attr( $value )
319 );
320 }
321
322 return $attributes;
323 }
324
325
326 /**
327 * Print field
328 *
329 * @since 0.1.0
330 */
331 abstract public function render();
332
333
334 /**
335 * Print field description
336 *
337 * @since 0.1.0
338 */
339 public function description() {
340 if ( ! empty( $this->field['description'] ) ) {
341 $tag = ( ! empty( $this->args->inline_description ) ) ? 'span' : 'p';
342
343 printf( // WPCS: XSS ok.
344 '<%1$s class="description">%2$s</%1$s>',
345 $tag,
346 wp_kses( $this->field['description'], $this->allowed_html )
347 );
348 }
349 }
350 }
351
352
353 /**
354 * Field: text
355 */
356 class Kucrut_Form_Field_Text extends Kucrut_Form_Field {
357
358 protected $template = '<input type="%s" value="%s"%s />';
359
360
361 protected function set_properties() {
362 if ( ! is_string( $this->field['value'] ) ) {
363 $this->field['value'] = '';
364 }
365
366 if ( in_array( $this->field['type'], array( 'text', 'url' ), true ) ) {
367 if ( ! isset( $this->attributes['class'] ) ) {
368 $this->attributes['class'] = array();
369 }
370 $this->attributes['class'] = array_unique(
371 array_merge(
372 array( 'regular-text' ),
373 $this->attributes['class']
374 )
375 );
376 }
377 }
378
379
380 public function render() {
381 printf( // WPCS: xss ok
382 $this->template,
383 esc_attr( $this->field['type'] ),
384 esc_attr( $this->field['value'] ),
385 $this->build_attributes()
386 );
387 $this->description();
388 }
389 }
390
391
392 /**
393 * Field: Textarea
394 */
395 class Kucrut_Form_Field_Textarea extends Kucrut_Form_Field {
396
397 protected $template = '<textarea%s>%s</textarea>';
398
399 protected $attributes = array(
400 'class' => 'widefat',
401 'cols' => 50,
402 'rows' => 5,
403 );
404
405
406 protected function set_properties() {
407 if ( ! is_string( $this->field['value'] ) ) {
408 $this->field['value'] = '';
409 }
410 }
411
412
413 public function render() {
414 printf( // WPCS: XSS ok.
415 $this->template,
416 $this->build_attributes(),
417 esc_textarea( $this->field['value'] )
418 );
419 }
420 }
421
422
423 /**
424 * Field: Checkbox
425 */
426 class Kucrut_Form_Field_Checkbox extends Kucrut_Form_Field {
427
428 protected $template = '<label><input type="%s" value="%s"%s%s /> %s</label><br />';
429
430
431 protected function set_properties() {
432 $this->field['value'] = array_filter( (array) $this->field['value'] );
433 $this->attributes['name'] .= '[]';
434 }
435
436
437 protected function checked( $value ) {
438 return checked( in_array( $value, $this->field['value'], true ), true, false );
439 }
440
441
442 public function render() {
443 foreach ( $this->field['choices'] as $value => $label ) {
444 printf( // WPCS: XSS ok.
445 $this->template,
446 $this->field['type'],
447 esc_attr( $value ),
448 $this->checked( $value ),
449 $this->build_attributes( 'id' ),
450 esc_html( $label )
451 );
452 }
453 }
454 }
455
456
457 /**
458 * Field: Radio
459 */
460 class Kucrut_Form_Field_Radio extends Kucrut_Form_Field_Checkbox {
461
462 protected function set_properties() {
463 if ( ! is_string( $this->field['value'] ) ) {
464 $this->field['value'] = '';
465 }
466 }
467
468
469 protected function checked( $value ) {
470 return checked( $value, $this->field['value'], false );
471 }
472 }
473
474
475 /**
476 * Field: Select
477 */
478 class Kucrut_Form_Field_Select extends Kucrut_Form_Field {
479
480 protected $template = '<option value="%s"%s>%s</option>';
481
482
483 protected function set_properties() {
484 if ( ! is_string( $this->field['value'] ) ) {
485 $this->field['value'] = '';
486 }
487 }
488
489
490 protected function selected( $value ) {
491 return selected( ( $value === $this->field['value'] ), true, false );
492 }
493
494
495 public function render() {
496 ?>
497 <select<?php echo $this->build_attributes() // xss ok ?>>
498 <?php foreach ( $this->field['choices'] as $index => $choice ) : ?>
499 <?php
500 if ( is_array( $choice ) ) {
501 $value = $choice['value'];
502 $label = $choice['label'];
503 } else {
504 $value = $index;
505 $label = $choice;
506 }
507 ?>
508 <?php
509 printf( // WPCS: XSS ok.
510 $this->template,
511 esc_attr( $value ),
512 $this->selected( $value ),
513 esc_html( $label )
514 );
515 ?>
516 <?php endforeach; ?>
517 </select>
518 <?php
519 }
520 }
521
522
523 /**
524 * Field: Multiple Select
525 */
526 class Kucrut_Form_Field_Select_Multiple extends Kucrut_Form_Field_Select {
527
528 protected function set_properties() {
529 $this->field['value'] = array_filter( (array) $this->field['value'] );
530 $this->attributes['name'] .= '[]';
531 $this->attributes['multiple'] = 'multiple';
532 }
533
534
535 protected function selected( $value ) {
536 return selected( in_array( $value, $this->field['value'], true ), true, false );
537 }
538 }
539
540
541 /**
542 * Field: Select Pages
543 */
544 class Kucrut_Form_Field_Select_Pages extends Kucrut_Form_Field_Select {
545
546 protected $wp_dropdown_pages_args = array(
547 'depth' => 0,
548 'child_of' => 0,
549 'option_none_value' => '',
550 );
551
552
553 public function __construct( $field, $args ) {
554 $this->wp_dropdown_pages_args['show_option_none'] = __( '&mdash; Select &mdash;', 'menu-icons' );
555 parent::__construct( $field, $args );
556 }
557
558
559 public function set_properties() {
560 parent::set_properties();
561
562 if ( empty( $this->args->wp_dropdown_pages_args ) ) {
563 $this->args->wp_dropdown_pages_args = array();
564 }
565
566 // Apply defeaults
567 $this->args->wp_dropdown_pages_args = wp_parse_args(
568 $this->args->wp_dropdown_pages_args,
569 $this->wp_dropdown_pages_args
570 );
571
572 // Force some args
573 $this->args->wp_dropdown_pages_args = array_merge(
574 $this->args->wp_dropdown_pages_args,
575 array(
576 'echo' => true,
577 'name' => $this->attributes['name'],
578 'id' => $this->attributes['id'],
579 'selected' => $this->field['value'],
580 )
581 );
582 }
583
584
585 public function render() {
586 wp_dropdown_pages( $this->args->wp_dropdown_pages_args ); // WPCS: XSS ok.
587 }
588 }
589
590
591 /**
592 * Field: Special (Callback)
593 */
594 class Kucrut_Form_Field_Special extends Kucrut_Form_Field {
595 public function render() {
596 call_user_func_array(
597 $this->field['render_cb'],
598 array( $this )
599 );
600 }
601 }
602