Completed
Push — master ( a3db22...aec616 )
by Marin
53:38 queued 51:58
created

Field::get_lazyload()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 3
Code Lines 2

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 2
Bugs 1 Features 0
Metric Value
c 2
b 1
f 0
dl 0
loc 3
ccs 0
cts 2
cp 0
rs 10
cc 1
eloc 2
nc 1
nop 0
crap 2
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 int
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 Carbon_DataStore
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 pretended 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
	 * Stores the field options (if any)
159
	 *
160
	 * @var string
161
	 **/
162
	protected $options = array();
163
164
	/**
165
	 * Create a new field of type $type and name $name and label $label.
166
	 *
167
	 * @param string $type
168
	 * @param string $name lower case and underscore-delimited
169
	 * @param string $label (optional) Automatically generated from $name if not present
170
	 * @return object $field
171
	 **/
172
	public static function factory( $type, $name, $label = null ) {
173
		$type = str_replace( ' ', '_', ucwords( str_replace( '_', ' ', $type ) ) );
174
175
		$class = __NAMESPACE__ . '\\' . $type . '_Field';
176
177 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...
178
			Incorrect_Syntax_Exception::raise( 'Unknown field "' . $type . '".' );
179
			$class = __NAMESPACE__ . "\\Broken_Field";
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal \\Broken_Field does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
180
		}
181
182
		if ( strpos( $name, '-' ) !== false ) {
183
			Incorrect_Syntax_Exception::raise( 'Forbidden character "-" in name "' . $name . '".' );
184
			$class = __NAMESPACE__ . "\\Broken_Field";
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal \\Broken_Field does not require double quotes, as per coding-style, please use single quotes.

PHP provides two ways to mark string literals. Either with single quotes 'literal' or with double quotes "literal". The difference between these is that string literals in double quotes may contain variables with are evaluated at run-time as well as escape sequences.

String literals in single quotes on the other hand are evaluated very literally and the only two characters that needs escaping in the literal are the single quote itself (\') and the backslash (\\). Every other character is displayed as is.

Double quoted string literals may contain other variables or more complex escape sequences.

<?php

$singleQuoted = 'Value';
$doubleQuoted = "\tSingle is $singleQuoted";

print $doubleQuoted;

will print an indented: Single is Value

If your string literal does not contain variables or escape sequences, it should be defined using single quotes to make that fact clear.

For more information on PHP string literals and available escape sequences see the PHP core documentation.

Loading history...
185
		}
186
187
		$field = new $class( $name, $label );
188
		$field->type = $type;
189
		$field->add_template( $field->get_type(), array( $field, 'template' ) );
190
191
		return $field;
192
	}
193
194
	/**
195
	 * An alias of factory().
196
	 *
197
	 * @see Field::factory()
198
	 **/
199
	public static function make( $type, $name, $label = null ) {
200
		return self::factory( $type, $name, $label );
201
	}
202
203
	/**
204
	 * Create a field from a certain type with the specified label.
205
	 * @param string $name  Field name
206
	 * @param string $label Field label
207
	 */
208
	protected function __construct( $name, $label ) {
209
		$this->set_name( $name );
210
		$this->set_label( $label );
211
		$this->set_base_name( $name );
212
213
		// Pick random ID
214
		$random_string = md5( mt_rand() . $this->get_name() . $this->get_label() );
215
		$random_string = substr( $random_string, 0, 5 ); // 5 chars should be enough
216
		$this->id = 'carbon-' . $random_string;
0 ignored issues
show
Documentation Bug introduced by
The property $id was declared of type integer, but 'carbon-' . $random_string is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
217
218
		$this->init();
219
		if ( is_admin() ) {
220
			$this->admin_init();
221
		}
222
223
		add_action( 'admin_print_scripts', array( $this, 'admin_hook_scripts' ) );
224
		add_action( 'admin_print_styles', array( $this, 'admin_hook_styles' ) );
225
	}
226
227
	/**
228
	 * Perform instance initialization after calling setup()
229
	 **/
230
	public function init() {}
231
232
	/**
233
	 * Instance initialization when in the admin area. Called during object construction
234
	 **/
235
	public function admin_init() {}
236
237
	/**
238
	 * Enqueue admin scripts.
239
	 * Called once per field type.
240
	 **/
241
	public function admin_enqueue_scripts() {}
242
243
	/**
244
	 * Prints the main Underscore template
245
	 **/
246
	public function template() { }
247
248
	/**
249
	 * Returns all the backbone templates
250
	 *
251
	 * @return array
252
	 **/
253
	public function get_templates() {
254
		return $this->templates;
255
	}
256
257
	/**
258
	 * Adds a new backbone template
259
	 **/
260
	public function add_template( $name, $callback ) {
261
		$this->templates[ $name ] = $callback;
262
	}
263
264
	/**
265
	 * Delegate load to the field DataStore instance
266
	 **/
267
	public function load() {
268
		$this->store->load( $this );
269
270
		if ( $this->get_value() === false ) {
271
			$this->set_value( $this->default_value );
272
		}
273
	}
274
275
	/**
276
	 * Delegate save to the field DataStore instance
277
	 **/
278
	public function save() {
279
		return $this->store->save( $this );
280
	}
281
282
	/**
283
	 * Delegate delete to the field DataStore instance
284
	 **/
285
	public function delete() {
286
		return $this->store->delete( $this );
287
	}
288
289
	/**
290
	 * Load the field value from an input array based on it's name
291
	 *
292
	 * @param array $input (optional) Array of field names and values. Defaults to $_POST
293
	 **/
294
	public function set_value_from_input( $input = null ) {
295
		if ( is_null( $input ) ) {
296
			$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...
297
		}
298
299
		if ( ! isset( $input[ $this->name ] ) ) {
300
			$this->set_value( null );
301
		} else {
302
			$this->set_value( stripslashes_deep( $input[ $this->name ] ) );
303
		}
304
	}
305
306
	/**
307
	 * Assign DataStore instance for use during load, save and delete
308
	 *
309
	 * @param object $store
310
	 * @return object $this
311
	 **/
312
	public function set_datastore( Datastore_Interface $store ) {
313
		$this->store = $store;
0 ignored issues
show
Documentation Bug introduced by
It seems like $store of type object<Carbon_Fields\Dat...re\Datastore_Interface> is incompatible with the declared type object<Carbon_Fields\Field\Carbon_DataStore> of property $store.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
314
		return $this;
315
	}
316
317
	/**
318
	 * Return the DataStore instance used by the field
319
	 *
320
	 * @return object $store
321
	 **/
322
	public function get_datastore() {
323
		return $this->store;
324
	}
325
326
	/**
327
	 * Assign the type of the container this field is in
328
	 *
329
	 * @param string
330
	 * @return object $this
331
	 **/
332
	public function set_context( $context ) {
333
		$this->context = $context;
334
		return $this;
335
	}
336
337
	/**
338
	 * Return the type of the container this field is in
339
	 *
340
	 * @return string
341
	 **/
342
	public function get_context() {
343
		return $this->context;
344
	}
345
346
	/**
347
	 * Directly modify the field value
348
	 *
349
	 * @param mixed $value
350
	 **/
351
	public function set_value( $value ) {
352
		$this->value = $value;
353
	}
354
355
	/**
356
	 * Set default field value
357
	 *
358
	 * @param mixed $default_value
359
	 **/
360
	public function set_default_value( $default_value ) {
361
		$this->default_value = $default_value;
362
		return $this;
363
	}
364
365
	/**
366
	 * Get default field value
367
	 *
368
	 * @return mixed
369
	 **/
370
	public function get_default_value() {
371
		return $this->default_value;
372
	}
373
374
	/**
375
	 * Return the field value
376
	 *
377
	 * @return mixed
378
	 **/
379
	public function get_value() {
380
		return $this->value;
381
	}
382
383
	/**
384
	 * Set field name.
385
	 * Use only if you are completely aware of what you are doing.
386
	 *
387
	 * @param string $name Field name, either sanitized or not
388
	 **/
389
	public function set_name( $name ) {
390
		$name = preg_replace( '~\s+~', '_', strtolower( $name ) );
391
392
		if ( $this->name_prefix && strpos( $name, $this->name_prefix ) !== 0 ) {
393
			$name = $this->name_prefix . $name;
394
		}
395
396
		$this->name = $name;
397
	}
398
399
	/**
400
	 * Return the field name
401
	 *
402
	 * @return string
403
	 **/
404
	public function get_name() {
405
		return $this->name;
406
	}
407
408
	/**
409
	 * Set field base name as defined in the container.
410
	 **/
411
	public function set_base_name( $name ) {
412
		$this->base_name = $name;
413
	}
414
415
	/**
416
	 * Return the field base name.
417
	 *
418
	 * @return string
419
	 **/
420
	public function get_base_name() {
421
		return $this->base_name;
422
	}
423
424
	/**
425
	 * Set field name prefix. Calling this method will update the current field name and the conditional logic fields.
426
	 *
427
	 * @param string $prefix
428
	 * @return object $this
429
	 **/
430
	public function set_prefix( $prefix ) {
431
		$this->name = preg_replace( '~^' . preg_quote( $this->name_prefix, '~' ) . '~', '', $this->name );
432
		$this->name_prefix = $prefix;
433
		$this->name = $this->name_prefix . $this->name;
434
435
		return $this;
436
	}
437
438
	/**
439
	 * Set field label.
440
	 *
441
	 * @param string $label If null, the label will be generated from the field name
442
	 **/
443 View Code Duplication
	public function set_label( $label ) {
1 ignored issue
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...
444
		// Try to guess field label from it's name
445
		if ( is_null( $label ) ) {
446
			// remove the leading underscore(if it's there)
447
			$label = preg_replace( '~^_~', '', $this->name );
448
449
			// remove the leading "crb_"(if it's there)
450
			$label = preg_replace( '~^crb_~', '', $label );
451
452
			// split the name into words and make them capitalized
453
			$label = ucwords( str_replace( '_', ' ', $label ) );
454
		}
455
456
		$this->label = $label;
457
	}
458
459
	/**
460
	 * Return field label.
461
	 * 
462
	 * @return string
463
	 **/
464
	public function get_label() {
465
		return $this->label;
466
	}
467
468
	/**
469
	 * Set additional text to be displayed during field render,
470
	 * containing information and guidance for the user
471
	 *
472
	 * @return object $this
473
	 **/
474
	public function set_help_text( $help_text ) {
475
		$this->help_text = $help_text;
476
		return $this;
477
	}
478
479
	/**
480
	 * Alias for set_help_text()
481
	 *
482
	 * @see set_help_text()
483
	 * @return object $this
484
	 **/
485
	public function help_text( $help_text ) {
486
		return $this->set_help_text( $help_text );
487
	}
488
489
	/**
490
	 * Return the field help text
491
	 *
492
	 * @return object $this
493
	 **/
494
	public function get_help_text() {
495
		return $this->help_text;
496
	}
497
498
	/**
499
	 * Whether or not this value should be auto loaded. Applicable to theme options only.
500
	 *
501
	 * @param bool $autoload
502
	 * @return object $this
503
	 **/
504
	public function set_autoload( $autoload ) {
505
		$this->autoload = $autoload;
506
		return $this;
507
	}
508
509
	/**
510
	 * Return whether or not this value should be auto loaded.
511
	 *
512
	 * @return bool
513
	 **/
514
	public function get_autoload() {
515
		return $this->autoload;
516
	}
517
518
	/**
519
	 * Whether or not this field will be initialized when the field is in the viewport (visible).
520
	 * 
521
	 * @param bool $lazyload
522
	 * @return object $this
523
	 **/
524
	public function set_lazyload( $lazyload ) {
525
		$this->lazyload = $lazyload;
526
		return $this;
527
	}
528
529
	/**
530
	 * Return whether or not this field should be lazyloaded.
531
	 * 
532
	 * @return bool
533
	 **/
534
	public function get_lazyload() {
535
		return $this->lazyload;
536
	}
537
538
	/**
539
	 * Set the field width.
540
	 * 
541
	 * @param int $width
542
	 * @return object $this
543
	 **/
544
	public function set_width( $width ) {
545
		$this->width = (int) $width;
546
		return $this;
547
	}
548
549
	/**
550
	 * Get the field width.
551
	 * 
552
	 * @return int $width
553
	 **/
554
	public function get_width() {
555
		return $this->width;
556
	}
557
558
	/**
559
	 *  Add custom CSS class to the field html container.
560
	 * 
561
	 * @param string|array $classes
562
	 * @return object $this
563
	 **/
564
	public function add_class( $classes ) {
565
		if ( ! is_array( $classes ) ) {
566
			$classes = array_values( array_filter( explode( ' ', $classes ) ) );
567
		}
568
569
		$this->classes = array_map( 'sanitize_html_class', $classes );
570
		return $this;
571
	}
572
573
	/**
574
	 * Get the field custom CSS classes.
575
	 * 
576
	 * @return array
577
	 **/
578
	public function get_classes() {
579
		return $this->classes;
580
	}
581
582
	/**
583
	 * Whether this field is mandatory for the user
584
	 *
585
	 * @param bool $required
586
	 * @return object $this
587
	 **/
588
	public function set_required( $required ) {
589
		$this->required = $required;
590
		return $this;
591
	}
592
593
	/**
594
	 * HTML id attribute getter.
595
	 * @return string
596
	 */
597 1
	public function get_id() {
598 1
		return $this->id;
599
	}
600
601
	/**
602
	 * HTML id attribute setter
603
	 * @param string $id
604
	 */
605 1
	public function set_id( $id ) {
606 1
		$this->id = $id;
0 ignored issues
show
Documentation Bug introduced by
The property $id was declared of type integer, but $id is of type string. Maybe add a type cast?

This check looks for assignments to scalar types that may be of the wrong type.

To ensure the code behaves as expected, it may be a good idea to add an explicit type cast.

$answer = 42;

$correct = false;

$correct = (bool) $answer;
Loading history...
607 1
	}
608
609
	/**
610
	 * Return whether this field is mandatory for the user
611
	 *
612
	 * @return bool
613
	 **/
614
	public function is_required() {
615
		return $this->required;
616
	}
617
618
	/**
619
	 * Returns the type of the field based on the class.
620
	 * The class is stripped by the "CarbonFields" prefix. 
621
	 * Also the "Field" suffix is removed. 
622
	 * Then underscores and backslashes are removed.
623
	 *
624
	 * @return string
625
	 */
626
	public function get_type() {
627
		$class = get_class( $this );
628
629
		return $this->clean_type( $class );
630
	}
631
632
	/**
633
	 * Cleans up an object class for usage as HTML class
634
	 *
635
	 * @return string
636
	 */
637
	protected function clean_type( $type ) {
638
		$remove = array(
639
			'_',
640
			'\\',
641
			'CarbonFields',
642
			'Field',
643
		);
644
		$clean_class = str_replace( $remove, '', $type );
645
646
		return $clean_class;
647
	}
648
649
	/**
650
	 * Return an array of html classes to be used for the field container
651
	 *
652
	 * @return array
653
	 */
654
	public function get_html_class() {
655
		$html_classes = array();
656
657
		$object_class = get_class( $this );
658
		$html_classes[] = $this->get_type();
659
660
		$parent_class = $object_class;
661
		while ( $parent_class = get_parent_class( $parent_class ) ) {
662
			$clean_class = $this->clean_type( $parent_class );
663
664
			if ( $clean_class ) {
665
				$html_classes[] = $clean_class;
666
			}
667
		}
668
669
		return $html_classes;
670
	}
671
672
	/**
673
	 * Allows the value of a field to be processed after loading.
674
	 * Can be implemented by the extending class if necessary.
675
	 * 
676
	 * @return array
677
	 */
678
	public function process_value() {
679
680
	}
681
682
	/**
683
	 * Returns an array that holds the field data, suitable for JSON representation.
684
	 * This data will be available in the Underscore template and the Backbone Model.
685
	 * 
686
	 * @param bool $load  Should the value be loaded from the database or use the value from the current instance.
687
	 * @return array
688
	 */
689
	public function to_json( $load ) {
690
		if ( $load ) {
691
			$this->load();
692
		}
693
694
		$this->process_value();
695
696
		$field_data = array(
697
			'id' => $this->get_id(),
698
			'type' => $this->get_type(),
699
			'label' => $this->get_label(),
700
			'name' => $this->get_name(),
701
			'base_name' => $this->get_base_name(),
702
			'value' => $this->get_value(),
703
			'default_value' => $this->get_default_value(),
704
			'help_text' => $this->get_help_text(),
705
			'context' => $this->get_context(),
706
			'required' => $this->is_required(),
707
			'lazyload' => $this->get_lazyload(),
708
			'width' => $this->get_width(),
709
			'classes' => $this->get_classes(),
710
			'conditional_logic' => $this->get_conditional_logic(),
711
		);
712
713
		return $field_data;
714
	}
715
716
	/**
717
	 * Set the field visibility conditional logic.
718
	 *
719
	 * @param array
720
	 */
721
	public function set_conditional_logic( $rules ) {
722
		$this->conditional_logic = $this->parse_conditional_rules( $rules );
723
724
		return $this;
725
	}
726
727
	/**
728
	 * Get the conditional logic rules
729
	 *
730
	 * @return array
731
	 */
732
	protected function get_conditional_logic() {
733
		return $this->conditional_logic;
734
	}
735
736
	/**
737
	 * Validate and parse the conditional logic rules.
738
	 *
739
	 * @param array $rules
740
	 * @return array
741
	 */
742
	protected function parse_conditional_rules( $rules ) {
743
		if ( ! is_array( $rules ) ) {
744
			Incorrect_Syntax_Exception::raise( 'Conditional logic rules argument should be an array.' );
745
		}
746
747
		$parsed_rules = array(
748
			'relation' => 'AND',
749
			'rules' => array(),
750
		);
751
752
		$allowed_operators = array( '=', '!=', '>', '>=', '<', '<=', 'IN', 'NOT IN' );
753
754
		foreach ( $rules as $key => $rule ) {
755
			// Check if we have a relation key
756
			if ( $key === 'relation' ) {
757
				if ( $rule === 'OR' ) {
758
					$parsed_rules['relation'] = $rule;
759
				}
760
				continue;
761
			}
762
763
			// Check if the rule is valid
764
			if ( ! is_array( $rule ) || empty( $rule['field'] ) ) {
765
				Incorrect_Syntax_Exception::raise( 'Invalid conditional logic rule format. The rule should be an array with the "field" key set.' );
766
			}
767
768
			// Check the compare oparator
769
			if ( empty( $rule['compare'] ) ) {
770
				$rule['compare'] = '=';
771
			}
772
			if ( ! in_array( $rule['compare'], $allowed_operators ) ) {
773
				Incorrect_Syntax_Exception::raise( 'Invalid conditional logic compare oparator: <code>' . $rule['compare'] . '</code><br>' . 
774
					'Allowed oparators are: <code>' . implode( ', ', $allowed_operators ) . '</code>' );
0 ignored issues
show
Coding Style introduced by
This line of the multi-line function call does not seem to be indented correctly. Expected 16 spaces, but found 20.
Loading history...
775
			}
776
			if ( $rule['compare'] === 'IN' || $rule['compare'] === 'NOT IN' ) {
777
				if ( ! is_array( $rule['value'] ) ) {
778
					Incorrect_Syntax_Exception::raise( 'Invalid conditional logic value format. An array is expected, when using the "' . $rule['compare'] . '" operator.' );
779
				}
780
			}
781
782
			// Check the value
783
			if ( ! isset( $rule['value'] ) ) {
784
				$rule['value'] = '';
785
			}
786
787
			$parsed_rules['rules'][] = $rule;
788
		}
789
790
		return $parsed_rules;
791
	}
792
793
	/**
794
	 * Set the field options
795
	 * Callbacks are supported
796
	 *
797
	 * @param array|callback $options
798
	 */
799
	protected function _set_options( $options ) {
800
		$this->options = (array) $options;
0 ignored issues
show
Documentation Bug introduced by
It seems like (array) $options of type array is incompatible with the declared type string of property $options.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
801
	}
802
803
	/**
804
	 * Add options to the field
805
	 * Callbacks are supported
806
	 *
807
	 * @param array|callback $options
808
	 */
809
	protected function _add_options( $options ) {
810
		$this->options[] = $options;
811
	}
812
813
	/**
814
	 * Check if there are callbacks and populate the options
815
	 */
816
	protected function load_options() {
817
		if ( empty( $this->options ) ) {
818
			return false;
819
		}
820
821
		$options = array();
822
		foreach ( $this->options as $key => $value ) {
0 ignored issues
show
Bug introduced by
The expression $this->options of type string is not traversable.
Loading history...
823
			if ( is_callable( $value ) ) {
824
				$options = $options + (array) call_user_func( $value );
825
			} else if ( is_array( $value ) ) {
826
				$options = $options + $value;
827
			} else {
828
				$options[ $key ] = $value;
829
			}
830
		}
831
832
		$this->options = $options;
0 ignored issues
show
Documentation Bug introduced by
It seems like $options of type array is incompatible with the declared type string of property $options.

Our type inference engine has found an assignment to a property that is incompatible with the declared type of that property.

Either this assignment is in error or the assigned type should be added to the documentation/type hint for that property..

Loading history...
833
	}
834
835
	/**
836
	 * Changes the options array structure. This is needed to keep the array items order when it is JSON encoded.
837
	 *
838
	 * @param array $options
839
	 * @return array
840
	 */
841
	public function parse_options( $options ) {
842
		$parsed = array();
843
844
		foreach ( $options as $key => $value ) {
845
			$parsed[] = array(
846
				'name' => $value,
847
				'value' => $key,
848
			);
849
		}
850
851
		return $parsed;
852
	}
853
854
	/**
855
	 * Hook administration scripts.
856
	 */
857
	public function admin_hook_scripts() {
858
		wp_enqueue_media();
859
		wp_enqueue_script( 'carbon-fields', \Carbon_Fields\URL . '/assets/js/fields.js', array( 'carbon-app', 'carbon-containers' ) );
860
		wp_localize_script( 'carbon-fields', 'crbl10n',
861
			array(
862
				'title' => __( 'Files', 'carbon_fields' ),
863
				'geocode_zero_results' => __( 'The address could not be found. ', 'carbon_fields' ),
864
				'geocode_not_successful' => __( 'Geocode was not successful for the following reason: ', 'carbon_fields' ),
865
				'max_num_items_reached' => __( 'Maximum number of items reached (%s items)', 'carbon_fields' ),
866
				'max_num_rows_reached' => __( 'Maximum number of rows reached (%s rows)', 'carbon_fields' ),
867
				'cannot_create_more_rows' => __( 'Cannot create more than %s rows', 'carbon_fields' ),
868
				'enter_name_of_new_sidebar' => __( 'Please enter the name of the new sidebar:', 'carbon_fields' ),
869
				'remove_sidebar_confirmation' => __( 'Are you sure you wish to remove this sidebar?', 'carbon_fields' ),
870
				'add_sidebar' => __( 'Add Sidebar', 'carbon_fields' ),
871
				'complex_no_rows' => __( 'There are no %s yet. Click <a href="#">here</a> to add one.', 'carbon_fields' ),
872
				'complex_add_button' => __( 'Add %s', 'carbon_fields' ),
873
				'complex_min_num_rows_not_reached' => __( 'Minimum number of rows not reached (%d %s)', 'carbon_fields' ),
874
				'message_form_validation_failed' => __( 'Please fill out all fields correctly. ', 'carbon_fields' ),
875
				'message_required_field' => __( 'This field is required. ', 'carbon_fields' ),
876
				'message_choose_option' => __( 'Please choose an option. ', 'carbon_fields' ),
877
			)
878
		);
879
	}
880
881
	/**
882
	 * Hook administration styles.
883
	 */
884
	public function admin_hook_styles() {
885
		wp_enqueue_style( 'thickbox' );
886
	}
887
} // END Field
888