Completed
Pull Request — master (#193)
by
unknown
09:54
created

Field::set_value_from_input()   A

Complexity

Conditions 3
Paths 4

Size

Total Lines 11
Code Lines 7

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 12

Importance

Changes 0
Metric Value
cc 3
eloc 7
c 0
b 0
f 0
nc 4
nop 1
dl 0
loc 11
ccs 0
cts 3
cp 0
crap 12
rs 9.4285
1
<?php
2
3
namespace Carbon_Fields\Field;
4
5
use Carbon_Fields\Datastore\Datastore_Interface;
6
use Carbon_Fields\Exception\Incorrect_Syntax_Exception;
7
8
/**
9
 * Base field class.
10
 * Defines the key container methods and their default implementations.
11
 * Implements factory design pattern.
12
 **/
13
class Field {
14
	/**
15
	 * Stores all the field Backbone templates
16
	 *
17
	 * @see factory()
18
	 * @see add_template()
19
	 * @var array
20
	 */
21
	protected $templates = array();
22
23
	/**
24
	 * Globally unique field identificator. Generated randomly
25
	 *
26
	 * @var string
27
	 */
28
	protected $id;
29
30
	/**
31
	 * Stores the initial <kbd>$type</kbd> variable passed to the <code>factory()</code> method
32
	 *
33
	 * @see factory
34
	 * @var string
35
	 */
36
	public $type;
37
38
	/**
39
	 * Field value
40
	 *
41
	 * @var mixed
42
	 */
43
	protected $value;
44
45
	/**
46
	 * Default field value
47
	 *
48
	 * @var mixed
49
	 */
50
	protected $default_value;
51
52
	/**
53
	 * Sanitized field name used as input name attribute during field render
54
	 *
55
	 * @see factory()
56
	 * @see set_name()
57
	 * @var string
58
	 */
59
	protected $name;
60
61
	/**
62
	 * The base field name which is used in the container.
63
	 *
64
	 * @see set_base_name()
65
	 * @var string
66
	 */
67
	protected $base_name;
68
69
	/**
70
	 * Field name used as label during field render
71
	 *
72
	 * @see factory()
73
	 * @see set_label()
74
	 * @var string
75
	 */
76
	protected $label;
77
78
	/**
79
	 * Additional text containing information and guidance for the user
80
	 *
81
	 * @see help_text()
82
	 * @var string
83
	 */
84
	protected $help_text;
85
86
	/**
87
	 * Field DataStore instance to which save, load and delete calls are delegated
88
	 *
89
	 * @see set_datastore()
90
	 * @see get_datastore()
91
	 * @var Datastore_Interface
92
	 */
93
	protected $store;
94
95
	/**
96
	 * The type of the container this field is in
97
	 *
98
	 * @see get_context()
99
	 * @var string
100
	 */
101
	protected $context;
102
103
	/**
104
	 * Whether or not this value should be auto loaded. Applicable to theme options only.
105
	 *
106
	 * @see set_autoload()
107
	 * @var bool
108
	 **/
109
	protected $autoload = false;
110
111
	/**
112
	 * Whether or not this field will be initialized when the field is in the viewport (visible).
113
	 *
114
	 * @see set_lazyload()
115
	 * @var bool
116
	 **/
117
	protected $lazyload = false;
118
119
	/**
120
	 * The width of the field.
121
	 *
122
	 * @see set_width()
123
	 * @var int
124
	 **/
125
	protected $width = 0;
126
127
	/**
128
	 * Custom CSS classes.
129
	 *
130
	 * @see add_class()
131
	 * @var array
132
	 **/
133
	protected $classes = array();
134
135
	/**
136
	 * Whether or not this field is required.
137
	 *
138
	 * @see set_required()
139
	 * @var bool
140
	 **/
141
	protected $required = false;
142
143
	/**
144
	 * Prefix to be prepended to the field name during load, save, delete and <strong>render</strong>
145
	 *
146
	 * @var string
147
	 **/
148
	protected $name_prefix = '_';
149
150
	/**
151
	 * Stores the field conditional logic rules.
152
	 *
153
	 * @var array
154
	 **/
155
	protected $conditional_logic = array();
156
157
	/**
158
	 * Whether the field should be included in the response of the requests to the REST API
159
	 *
160
	 * @see  set_rest_visibility
161
	 * @see  get_rest_visibility
162
	 * @var boolean
163
	 */
164
	protected $visible_in_rest = true;
165 14
166
	/**
167 14
	 * Create a new field of type $type and name $name and label $label.
168
	 *
169
	 * @param string $type
170
	 * @param string $name lower case and underscore-delimited
171 14
	 * @param string $label (optional) Automatically generated from $name if not present
172
	 * @return object $field
173 14
	 **/
174
	public static function factory( $type, $name, $label = null ) {
175 14
		// backward compatibility: `file` type used to be called `attachment`
176 4
		if ( $type === 'attachment' ) {
177 1
			$type = 'file';
178 1
		}
179
180 11
		$type = str_replace( ' ', '_', ucwords( str_replace( '_', ' ', $type ) ) );
181 10
182
		$class = __NAMESPACE__ . '\\' . $type . '_Field';
183 10
184 View Code Duplication
		if ( ! class_exists( $class ) ) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
185
			Incorrect_Syntax_Exception::raise( 'Unknown field "' . $type . '".' );
186
			$class = __NAMESPACE__ . '\\Broken_Field';
187
		}
188
189
		$field = new $class( $name, $label );
190
		$field->type = $type;
191 14
192 14
		return $field;
193
	}
194
195
	/**
196
	 * An alias of factory().
197
	 *
198
	 * @see Field::factory()
199
	 **/
200 11
	public static function make( $type, $name, $label = null ) {
201 11
		return self::factory( $type, $name, $label );
202 10
	}
203 10
204
	/**
205
	 * Create a field from a certain type with the specified label.
206 10
	 * @param string $name  Field name
207 10
	 * @param string $label Field label
208 10
	 */
209 View Code Duplication
	protected function __construct( $name, $label ) {
0 ignored issues
show
Duplication introduced by
This method seems to be duplicated in your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
210 10
		$this->set_name( $name );
211 10
		$this->set_label( $label );
212
		$this->set_base_name( $name );
213
214
		// Pick random ID
215
		$random_string = md5( mt_rand() . $this->get_name() . $this->get_label() );
216
		$random_string = substr( $random_string, 0, 5 ); // 5 chars should be enough
217
		$this->id = 'carbon-' . $random_string;
218
219
		$this->init();
220
	}
221
222
	/**
223
	 * Boot the field once the container is attached.
224
	 **/
225
	public function boot() {
226
		$this->admin_init();
227
228
		$this->add_template( $this->get_type(), array( $this, 'template' ) );
229
230
		add_action( 'admin_footer', array( get_class(), 'admin_hook_scripts' ), 5 );
231
		add_action( 'admin_footer', array( get_class(), 'admin_hook_styles' ), 5 );
232
233
		add_action( 'admin_footer', array( get_class( $this ), 'admin_enqueue_scripts' ), 5 );
234
	}
235
236
	/**
237
	 * Perform instance initialization after calling setup()
238
	 **/
239
	public function init() {}
240
241
	/**
242
	 * Instance initialization when in the admin area.
243
	 * Called during field boot.
244
	 **/
245
	public function admin_init() {}
246
247
	/**
248
	 * Enqueue admin scripts.
249
	 * Called once per field type.
250
	 **/
251
	public static function admin_enqueue_scripts() {}
252
253
	/**
254
	 * Prints the main Underscore template
255
	 **/
256
	public function template() { }
257
258
	/**
259
	 * Returns all the Backbone templates
260
	 *
261
	 * @return array
262
	 **/
263
	public function get_templates() {
264
		return $this->templates;
265
	}
266
267
	/**
268
	 * Adds a new Backbone template
269
	 **/
270
	public function add_template( $name, $callback ) {
271
		$this->templates[ $name ] = $callback;
272
	}
273
274
	/**
275
	 * Delegate load to the field DataStore instance
276
	 **/
277
	public function load() {
278
		$this->store->load( $this );
279
280
		if ( $this->get_value() === false ) {
281
			$this->set_value( $this->default_value );
282
		}
283
	}
284
285
	/**
286
	 * Delegate save to the field DataStore instance
287
	 **/
288
	public function save() {
289
		return $this->store->save( $this );
290
	}
291
292
	/**
293
	 * Delegate delete to the field DataStore instance
294
	 **/
295
	public function delete() {
296
		return $this->store->delete( $this );
297
	}
298
299
	/**
300
	 * Load the field value from an input array based on it's name
301
	 *
302
	 * @param array $input (optional) Array of field names and values. Defaults to $_POST
303
	 **/
304
	public function set_value_from_input( $input = null ) {
305
		if ( is_null( $input ) ) {
306
			$input = $_POST;
0 ignored issues
show
introduced by
Detected access of super global var $_POST, probably need manual inspection.
Loading history...
introduced by
Detected usage of a non-sanitized input variable: $_POST
Loading history...
307
		}
308
309
		if ( ! isset( $input[ $this->name ] ) ) {
310
			$this->set_value( null );
311
		} else {
312
			$this->set_value( stripslashes_deep( $input[ $this->name ] ) );
313
		}
314
	}
315
316
	/**
317
	 * Assign DataStore instance for use during load, save and delete
318
	 *
319
	 * @param object $store
320
	 * @return object $this
321
	 **/
322
	public function set_datastore( Datastore_Interface $store ) {
323
		$this->store = $store;
324
		return $this;
325
	}
326
327
	/**
328
	 * Return the DataStore instance used by the field
329
	 *
330
	 * @return object $store
331
	 **/
332
	public function get_datastore() {
333
		return $this->store;
334
	}
335
336
	/**
337
	 * Assign the type of the container this field is in
338
	 *
339
	 * @param string
340
	 * @return object $this
341
	 **/
342
	public function set_context( $context ) {
343
		$this->context = $context;
344
		return $this;
345
	}
346
347
	/**
348
	 * Return the type of the container this field is in
349
	 *
350
	 * @return string
351
	 **/
352
	public function get_context() {
353
		return $this->context;
354
	}
355
356
	/**
357
	 * Directly modify the field value
358
	 *
359
	 * @param mixed $value
360
	 **/
361
	public function set_value( $value ) {
362
		$this->value = $value;
363
	}
364
365
	/**
366
	 * Set default field value
367
	 *
368
	 * @param mixed $default_value
369
	 **/
370
	public function set_default_value( $default_value ) {
371
		$this->default_value = $default_value;
372
		return $this;
373
	}
374
375
	/**
376
	 * Get default field value
377
	 *
378
	 * @return mixed
379
	 **/
380
	public function get_default_value() {
381
		return $this->default_value;
382
	}
383
384
	/**
385
	 * Return the field value
386
	 *
387
	 * @return mixed
388
	 **/
389
	public function get_value() {
390
		return $this->value;
391
	}
392
393
	/**
394
	 * Set field name.
395
	 * Use only if you are completely aware of what you are doing.
396
	 *
397
	 * @param string $name Field name, either sanitized or not
398
	 **/
399
	public function set_name( $name ) {
400
		$name = preg_replace( '~\s+~', '_', mb_strtolower( $name ) );
401
402
		if ( empty( $name ) ) {
403
			Incorrect_Syntax_Exception::raise( 'Field name can\'t be empty' );
404
		}
405
406
		if ( $this->name_prefix && strpos( $name, $this->name_prefix ) !== 0 ) {
407
			$name = $this->name_prefix . $name;
408
		}
409
410
		$this->name = $name;
411
	}
412
413
	/**
414
	 * Return the field name
415
	 *
416
	 * @return string
417
	 **/
418
	public function get_name() {
419
		return $this->name;
420
	}
421
422
	/**
423
	 * Set field base name as defined in the container.
424
	 **/
425
	public function set_base_name( $name ) {
426
		$this->base_name = $name;
427
	}
428
429
	/**
430
	 * Return the field base name.
431
	 *
432
	 * @return string
433
	 **/
434
	public function get_base_name() {
435
		return $this->base_name;
436
	}
437
438
	/**
439
	 * Set field name prefix. Calling this method will update the current field
440
	 * name and the conditional logic fields.
441
	 *
442
	 * @param string $prefix
443
	 * @return object $this
444
	 **/
445
	public function set_prefix( $prefix ) {
446
		$escaped_prefix = preg_quote( $this->name_prefix, '~' );
447
		$this->name = preg_replace( '~^' . $escaped_prefix . '~', '', $this->name );
448
		$this->name_prefix = $prefix;
449
		$this->name = $this->name_prefix . $this->name;
450
451
		return $this;
452
	}
453
454
	/**
455
	 * Set field label.
456
	 *
457
	 * @param string $label If null, the label will be generated from the field name
458
	 **/
459
	public function set_label( $label ) {
460
		// Try to guess field label from it's name
461 View Code Duplication
		if ( is_null( $label ) ) {
0 ignored issues
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
462
			// remove the leading underscore(if it's there)
463
			$label = preg_replace( '~^_~', '', $this->name );
464
465
			// remove the leading "crb_"(if it's there)
466
			$label = preg_replace( '~^crb_~', '', $label );
467
468
			// split the name into words and make them capitalized
469
			$label = mb_convert_case( str_replace( '_', ' ', $label ), MB_CASE_TITLE );
470
		}
471
472
		$this->label = $label;
473
	}
474
475
	/**
476
	 * Return field label.
477
	 *
478
	 * @return string
479
	 **/
480
	public function get_label() {
481
		return $this->label;
482
	}
483
484
	/**
485
	 * Set additional text to be displayed during field render,
486
	 * containing information and guidance for the user
487
	 *
488
	 * @return object $this
489
	 **/
490
	public function set_help_text( $help_text ) {
491
		$this->help_text = $help_text;
492
		return $this;
493
	}
494
495
	/**
496
	 * Alias for set_help_text()
497
	 *
498
	 * @see set_help_text()
499
	 * @return object $this
500
	 **/
501
	public function help_text( $help_text ) {
502
		return $this->set_help_text( $help_text );
503
	}
504
505
	/**
506
	 * Return the field help text
507
	 *
508
	 * @return object $this
509
	 **/
510
	public function get_help_text() {
511
		return $this->help_text;
512
	}
513
514
	/**
515
	 * Whether or not this value should be auto loaded. Applicable to theme options only.
516
	 *
517
	 * @param bool $autoload
518
	 * @return object $this
519
	 **/
520
	public function set_autoload( $autoload ) {
521
		$this->autoload = $autoload;
522
		return $this;
523
	}
524
525
	/**
526
	 * Return whether or not this value should be auto loaded.
527
	 *
528
	 * @return bool
529
	 **/
530
	public function get_autoload() {
531
		return $this->autoload;
532
	}
533
534
	/**
535
	 * Whether or not this field will be initialized when the field is in the viewport (visible).
536
	 *
537
	 * @param bool $lazyload
538
	 * @return object $this
539
	 **/
540
	public function set_lazyload( $lazyload ) {
541
		$this->lazyload = $lazyload;
542
		return $this;
543
	}
544
545
	/**
546
	 * Return whether or not this field should be lazyloaded.
547
	 *
548
	 * @return bool
549
	 **/
550
	public function get_lazyload() {
551
		return $this->lazyload;
552
	}
553
554
	/**
555
	 * Set the field width.
556
	 *
557
	 * @param int $width
558
	 * @return object $this
559
	 **/
560
	public function set_width( $width ) {
561
		$this->width = (int) $width;
562
		return $this;
563
	}
564
565
	/**
566
	 * Get the field width.
567
	 *
568
	 * @return int $width
569
	 **/
570
	public function get_width() {
571
		return $this->width;
572
	}
573
574
	/**
575
	 *  Add custom CSS class to the field html container.
576
	 *
577
	 * @param string|array $classes
578
	 * @return object $this
579
	 **/
580
	public function add_class( $classes ) {
581
		if ( ! is_array( $classes ) ) {
582
			$classes = array_values( array_filter( explode( ' ', $classes ) ) );
583
		}
584
585
		$this->classes = array_map( 'sanitize_html_class', $classes );
586
		return $this;
587
	}
588
589
	/**
590
	 * Get the field custom CSS classes.
591
	 *
592
	 * @return array
593
	 **/
594
	public function get_classes() {
595
		return $this->classes;
596
	}
597
598
	/**
599
	 * Whether this field is mandatory for the user
600
	 *
601
	 * @param bool $required
602
	 * @return object $this
603
	 **/
604 1
	public function set_required( $required = true ) {
605 1
		$this->required = $required;
606
		return $this;
607
	}
608
609
	/**
610
	 * HTML id attribute getter.
611
	 * @return string
612 1
	 */
613 1
	public function get_id() {
614 1
		return $this->id;
615
	}
616
617
	/**
618
	 * HTML id attribute setter
619
	 * @param string $id
620
	 */
621
	public function set_id( $id ) {
622
		$this->id = $id;
623
	}
624
625
	/**
626
	 * Return whether this field is mandatory for the user
627
	 *
628
	 * @return bool
629
	 **/
630
	public function is_required() {
631
		return $this->required;
632
	}
633
634
	/**
635
	 * Returns the type of the field based on the class.
636
	 * The class is stripped by the "CarbonFields" prefix.
637
	 * Also the "Field" suffix is removed.
638
	 * Then underscores and backslashes are removed.
639
	 *
640
	 * @return string
641
	 */
642
	public function get_type() {
643
		$class = get_class( $this );
644
645
		return $this->clean_type( $class );
646
	}
647
648
	/**
649
	 * Cleans up an object class for usage as HTML class
650
	 *
651
	 * @return string
652
	 */
653
	protected function clean_type( $type ) {
654
		$remove = array(
655
			'_',
656
			'\\',
657
			'CarbonFields',
658
			'Field',
659
		);
660
		$clean_class = str_replace( $remove, '', $type );
661
662
		return $clean_class;
663
	}
664
665
	/**
666
	 * Return an array of html classes to be used for the field container
667
	 *
668
	 * @return array
669
	 */
670
	public function get_html_class() {
671
		$html_classes = array();
672
673
		$object_class = get_class( $this );
674
		$html_classes[] = $this->get_type();
675
676
		$parent_class = $object_class;
677
		while ( $parent_class = get_parent_class( $parent_class ) ) {
678
			$clean_class = $this->clean_type( $parent_class );
679
680
			if ( $clean_class ) {
681
				$html_classes[] = $clean_class;
682
			}
683
		}
684
685
		return $html_classes;
686
	}
687
688
	/**
689
	 * Allows the value of a field to be processed after loading.
690
	 * Can be implemented by the extending class if necessary.
691
	 *
692
	 * @return array
693
	 */
694
	public function process_value() {
695
696
	}
697
698
	/**
699
	 * Returns an array that holds the field data, suitable for JSON representation.
700
	 * This data will be available in the Underscore template and the Backbone Model.
701
	 *
702
	 * @param bool $load  Should the value be loaded from the database or use the value from the current instance.
703
	 * @return array
704
	 */
705
	public function to_json( $load ) {
706
		if ( $load ) {
707
			$this->load();
708
		}
709
710
		$this->process_value();
711
712
		$field_data = array(
713
			'id' => $this->get_id(),
714
			'type' => $this->get_type(),
715
			'label' => $this->get_label(),
716
			'name' => $this->get_name(),
717
			'base_name' => $this->get_base_name(),
718
			'value' => $this->get_value(),
719
			'default_value' => $this->get_default_value(),
720
			'help_text' => $this->get_help_text(),
721
			'context' => $this->get_context(),
722
			'required' => $this->is_required(),
723
			'lazyload' => $this->get_lazyload(),
724
			'width' => $this->get_width(),
725
			'classes' => $this->get_classes(),
726
			'conditional_logic' => $this->get_conditional_logic(),
727
		);
728 8
729 8
		return $field_data;
730
	}
731 3
732
	/**
733
	 * Set the field visibility conditional logic.
734
	 *
735
	 * @param array
736
	 */
737
	public function set_conditional_logic( $rules ) {
738
		$this->conditional_logic = $this->parse_conditional_rules( $rules );
739 3
740 3
		return $this;
741
	}
742
743
	/**
744
	 * Get the conditional logic rules
745
	 *
746
	 * @return array
747
	 */
748
	public function get_conditional_logic() {
749
		return $this->conditional_logic;
750
	}
751
752
	/**
753
	 * Configuration function for setting the field visibility in the response of the requests to the REST API
754
	 * 
755
	 * @param  bool $visible
756
	 * @return object $this
757
	 */
758
	public function show_in_rest( $visible ) {
759
		$this->set_rest_visibility( $visible );
760
761
		return $this;
762
	}
763
764
	/**
765
	 * Set the REST visibility of the field
766
	 * 
767
	 * @param bool $visible
768
	 */
769
	public function set_rest_visibility( $visible ) {
770
		$this->visible_in_rest = $visible;
771
	}
772
773
	/**
774
	 * Get the REST visibility of the field
775
	 * 
776
	 * @return bool True if the field is visible
777
	 */
778
	public function get_rest_visibility() {
779
		return $this->visible_in_rest;
780
	}
781
782
	/**
783
	 * Validate and parse the conditional logic rules.
784
	 *
785
	 * @param array $rules
786
	 * @return array
787
	 */
788
	protected function parse_conditional_rules( $rules ) {
789
		if ( ! is_array( $rules ) ) {
790
			Incorrect_Syntax_Exception::raise( 'Conditional logic rules argument should be an array.' );
791
		}
792
793
		$allowed_operators = array( '=', '!=', '>', '>=', '<', '<=', 'IN', 'NOT IN' );
794
		$allowed_relations = array( 'AND', 'OR' );
795
796
		$parsed_rules = array(
797
			'relation' => 'AND',
798
			'rules' => array(),
799
		);
800
801
		foreach ( $rules as $key => $rule ) {
802
			// Check if we have a relation key
803
			if ( $key === 'relation' ) {
804
				$relation = strtoupper( $rule );
805
806 View Code Duplication
				if ( ! in_array( $relation, $allowed_relations ) ) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
807
					Incorrect_Syntax_Exception::raise( 'Invalid relation type ' . $rule . '. ' .
808
					'The rule should be one of the following: "' . implode( '", "', $allowed_relations ) . '"' );
809
				}
810
811
				$parsed_rules['relation'] = $relation;
812
				continue;
813
			}
814
815
			// Check if the rule is valid
816
			if ( ! is_array( $rule ) || empty( $rule['field'] ) ) {
817
				Incorrect_Syntax_Exception::raise( 'Invalid conditional logic rule format. ' .
818
				'The rule should be an array with the "field" key set.' );
819
			}
820
821
			// Check the compare operator
822
			if ( empty( $rule['compare'] ) ) {
823
				$rule['compare'] = '=';
824
			}
825 View Code Duplication
			if ( ! in_array( $rule['compare'], $allowed_operators ) ) {
1 ignored issue
show
Duplication introduced by
This code seems to be duplicated across your project.

Duplicated code is one of the most pungent code smells. If you need to duplicate the same code in three or more different places, we strongly encourage you to look into extracting the code into a single class or operation.

You can also find more detailed suggestions in the “Code” section of your repository.

Loading history...
826
				Incorrect_Syntax_Exception::raise( 'Invalid conditional logic compare operator: <code>' .
827
					$rule['compare'] . '</code><br>Allowed operators are: <code>' .
828
				implode( ', ', $allowed_operators ) . '</code>' );
829
			}
830
			if ( $rule['compare'] === 'IN' || $rule['compare'] === 'NOT IN' ) {
831
				if ( ! is_array( $rule['value'] ) ) {
832
					Incorrect_Syntax_Exception::raise( 'Invalid conditional logic value format. ' .
833
					'An array is expected, when using the "' . $rule['compare'] . '" operator.' );
834
				}
835
			}
836
837
			// Check the value
838
			if ( ! isset( $rule['value'] ) ) {
839
				$rule['value'] = '';
840
			}
841
842
			$parsed_rules['rules'][] = $rule;
843
		}
844
845
		return $parsed_rules;
846
	}
847
848
849
	/**
850
	 * Hook administration scripts.
851
	 */
852
	public static function admin_hook_scripts() {
853
		wp_enqueue_media();
854
		wp_enqueue_script( 'carbon-fields', \Carbon_Fields\URL . '/assets/js/fields.js', array( 'carbon-app', 'carbon-containers' ) );
855
		wp_localize_script( 'carbon-fields', 'crbl10n',
856
			array(
857
				'title' => __( 'Files', 'carbon-fields' ),
858
				'geocode_zero_results' => __( 'The address could not be found. ', 'carbon-fields' ),
859
				'geocode_not_successful' => __( 'Geocode was not successful for the following reason: ', 'carbon-fields' ),
860
				'max_num_items_reached' => __( 'Maximum number of items reached (%s items)', 'carbon-fields' ),
861
				'max_num_rows_reached' => __( 'Maximum number of rows reached (%s rows)', 'carbon-fields' ),
862
				'cannot_create_more_rows' => __( 'Cannot create more than %s rows', 'carbon-fields' ),
863
				'complex_no_rows' => __( 'There are no %s yet. Click <a href="#">here</a> to add one.', 'carbon-fields' ),
864
				'complex_add_button' => __( 'Add %s', 'carbon-fields' ),
865
				'complex_min_num_rows_not_reached' => __( 'Minimum number of rows not reached (%1$d %2$s)', 'carbon-fields' ),
866
				'message_form_validation_failed' => __( 'Please fill out all fields correctly. ', 'carbon-fields' ),
867
				'message_required_field' => __( 'This field is required. ', 'carbon-fields' ),
868
				'message_choose_option' => __( 'Please choose an option. ', 'carbon-fields' ),
869
870
				'enter_name_of_new_sidebar' => __( 'Please enter the name of the new sidebar:', 'carbon-fields' ),
871
			)
872
		);
873
	}
874
875
	/**
876
	 * Hook administration styles.
877
	 */
878
	public static function admin_hook_styles() {
879
		wp_enqueue_style( 'thickbox' );
880
	}
881
} // END Field
882