Completed
Pull Request — master (#10)
by Nicolas
02:35
created

Field::template()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 1
Code Lines 1

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 1
Bugs 0 Features 0
Metric Value
c 1
b 0
f 0
dl 0
loc 1
ccs 0
cts 0
cp 0
rs 10
cc 1
eloc 1
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 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
	 * Create a new field of type $type and name $name and label $label.
159
	 *
160
	 * @param string $type
161
	 * @param string $name lower case and underscore-delimited
162
	 * @param string $label (optional) Automatically generated from $name if not present
163
	 * @return object $field
164
	 **/
165 15
	public static function factory( $type, $name, $label = null ) {
166
		// backward compatibility: `file` type used to be called `attachment`
167 15
		if ( $type === 'attachment' ) {
168
			$type = 'file';
169
		}
170
171 15
		$type = str_replace( ' ', '_', ucwords( str_replace( '_', ' ', $type ) ) );
172
173 15
		$class = __NAMESPACE__ . '\\' . $type . '_Field';
174
175 15 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...
176 4
			Incorrect_Syntax_Exception::raise( 'Unknown field "' . $type . '".' );
177 1
			$class = __NAMESPACE__ . '\\Broken_Field';
178 1
		}
179
180 12
		if ( strpos( $name, '-' ) !== false ) {
181 1
			Incorrect_Syntax_Exception::raise( 'Forbidden character "-" in name "' . $name . '".' );
182
			$class = __NAMESPACE__ . '\\Broken_Field';
183
		}
184
185 11
		$field = new $class( $name, $label );
186 10
		$field->type = $type;
187 10
		$field->add_template( $field->get_type(), array( $field, 'template' ) );
188
189 10
		return $field;
190
	}
191
192
	/**
193
	 * An alias of factory().
194
	 *
195
	 * @see Field::factory()
196
	 **/
197 15
	public static function make( $type, $name, $label = null ) {
198 15
		return self::factory( $type, $name, $label );
199
	}
200
201
	/**
202
	 * Create a field from a certain type with the specified label.
203
	 * @param string $name  Field name
204
	 * @param string $label Field label
205
	 */
206 11
	protected function __construct( $name, $label ) {
207 11
		$this->set_name( $name );
208 10
		$this->set_label( $label );
209 10
		$this->set_base_name( $name );
210
211
		// Pick random ID
212 10
		$random_string = md5( mt_rand() . $this->get_name() . $this->get_label() );
213 10
		$random_string = substr( $random_string, 0, 5 ); // 5 chars should be enough
214 10
		$this->id = 'carbon-' . $random_string;
215
216 10
		$this->init();
217 10
		if ( is_admin() ) {
218
			$this->admin_init();
219
		}
220
221 10
		add_action( 'admin_print_scripts', array( $this, 'admin_hook_scripts' ) );
222 10
		add_action( 'admin_print_styles', array( $this, 'admin_hook_styles' ) );
223 10
	}
224
225
	/**
226
	 * Perform instance initialization after calling setup()
227
	 **/
228
	public function init() {}
229
230
	/**
231
	 * Instance initialization when in the admin area.
232
	 * Called during object construction.
233
	 **/
234
	public function admin_init() {}
235
236
	/**
237
	 * Enqueue admin scripts.
238
	 * Called once per field type.
239
	 **/
240
	public function admin_enqueue_scripts() {}
241
242
	/**
243
	 * Prints the main Underscore template
244
	 **/
245
	public function template() { }
246
247
	/**
248
	 * Returns all the Backbone templates
249
	 *
250
	 * @return array
251
	 **/
252
	public function get_templates() {
253
		return $this->templates;
254
	}
255
256
	/**
257
	 * Adds a new Backbone template
258
	 **/
259
	public function add_template( $name, $callback ) {
260
		$this->templates[ $name ] = $callback;
261
	}
262
263
	/**
264
	 * Delegate load to the field DataStore instance
265
	 **/
266
	public function load() {
267
		$this->store->load( $this );
268
269
		if ( $this->get_value() === false ) {
270
			$this->set_value( $this->default_value );
271
		}
272
	}
273
274
	/**
275
	 * Delegate save to the field DataStore instance
276
	 **/
277
	public function save() {
278
		return $this->store->save( $this );
279
	}
280
281
	/**
282
	 * Delegate delete to the field DataStore instance
283
	 **/
284
	public function delete() {
285
		return $this->store->delete( $this );
286
	}
287
288
	/**
289
	 * Load the field value from an input array based on it's name
290
	 *
291
	 * @param array $input (optional) Array of field names and values. Defaults to $_POST
292
	 **/
293
	public function set_value_from_input( $input = null ) {
294
		if ( is_null( $input ) ) {
295
			$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...
296
		}
297
298
		if ( ! isset( $input[ $this->name ] ) ) {
299
			$this->set_value( null );
300
		} else {
301
			$this->set_value( stripslashes_deep( $input[ $this->name ] ) );
302
		}
303
	}
304
305
	/**
306
	 * Assign DataStore instance for use during load, save and delete
307
	 *
308
	 * @param object $store
309
	 * @return object $this
310
	 **/
311
	public function set_datastore( Datastore_Interface $store ) {
312
		$this->store = $store;
313
		return $this;
314
	}
315
316
	/**
317
	 * Return the DataStore instance used by the field
318
	 *
319
	 * @return object $store
320
	 **/
321
	public function get_datastore() {
322
		return $this->store;
323
	}
324
325
	/**
326
	 * Assign the type of the container this field is in
327
	 *
328
	 * @param string
329
	 * @return object $this
330
	 **/
331
	public function set_context( $context ) {
332
		$this->context = $context;
333
		return $this;
334
	}
335
336
	/**
337
	 * Return the type of the container this field is in
338
	 *
339
	 * @return string
340
	 **/
341
	public function get_context() {
342
		return $this->context;
343
	}
344
345
	/**
346
	 * Directly modify the field value
347
	 *
348
	 * @param mixed $value
349
	 **/
350
	public function set_value( $value ) {
351
		$this->value = $value;
352
	}
353
354
	/**
355
	 * Set default field value
356
	 *
357
	 * @param mixed $default_value
358
	 **/
359
	public function set_default_value( $default_value ) {
360
		$this->default_value = $default_value;
361
		return $this;
362
	}
363
364
	/**
365
	 * Get default field value
366
	 *
367
	 * @return mixed
368
	 **/
369
	public function get_default_value() {
370
		return $this->default_value;
371
	}
372
373
	/**
374
	 * Return the field value
375
	 *
376
	 * @return mixed
377
	 **/
378
	public function get_value() {
379
		return $this->value;
380
	}
381
382
	/**
383
	 * Set field name.
384
	 * Use only if you are completely aware of what you are doing.
385
	 *
386
	 * @param string $name Field name, either sanitized or not
387
	 **/
388
	public function set_name( $name ) {
389
		$name = preg_replace( '~\s+~', '_', mb_strtolower( $name ) );
390
391
		if ( empty( $name ) ) {
392
			Incorrect_Syntax_Exception::raise( 'Field name can\'t be empty' );
393
		}
394
395
		if ( $this->name_prefix && strpos( $name, $this->name_prefix ) !== 0 ) {
396
			$name = $this->name_prefix . $name;
397
		}
398
399
		$this->name = $name;
400
	}
401
402
	/**
403
	 * Return the field name
404
	 *
405
	 * @return string
406
	 **/
407
	public function get_name() {
408
		return $this->name;
409
	}
410
411
	/**
412
	 * Set field base name as defined in the container.
413
	 **/
414
	public function set_base_name( $name ) {
415
		$this->base_name = $name;
416
	}
417
418
	/**
419
	 * Return the field base name.
420
	 *
421
	 * @return string
422
	 **/
423
	public function get_base_name() {
424
		return $this->base_name;
425
	}
426
427
	/**
428
	 * Set field name prefix. Calling this method will update the current field
429
	 * name and the conditional logic fields.
430
	 *
431
	 * @param string $prefix
432
	 * @return object $this
433
	 **/
434
	public function set_prefix( $prefix ) {
435
		$escaped_prefix = preg_quote( $this->name_prefix, '~' );
436
		$this->name = preg_replace( '~^' . $escaped_prefix . '~', '', $this->name );
437
		$this->name_prefix = $prefix;
438
		$this->name = $this->name_prefix . $this->name;
439
440
		return $this;
441
	}
442
443
	/**
444
	 * Set field label.
445
	 *
446
	 * @param string $label If null, the label will be generated from the field name
447
	 **/
448
	public function set_label( $label ) {
449
		// Try to guess field label from it's name
450 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...
451
			// remove the leading underscore(if it's there)
452
			$label = preg_replace( '~^_~', '', $this->name );
453
454
			// remove the leading "crb_"(if it's there)
455
			$label = preg_replace( '~^crb_~', '', $label );
456
457
			// split the name into words and make them capitalized
458
			$label = mb_convert_case( str_replace( '_', ' ', $label ), MB_CASE_TITLE );
459
		}
460
461
		$this->label = $label;
462
	}
463
464
	/**
465
	 * Return field label.
466
	 *
467
	 * @return string
468
	 **/
469
	public function get_label() {
470
		return $this->label;
471
	}
472
473
	/**
474
	 * Set additional text to be displayed during field render,
475
	 * containing information and guidance for the user
476
	 *
477
	 * @return object $this
478
	 **/
479
	public function set_help_text( $help_text ) {
480
		$this->help_text = $help_text;
481
		return $this;
482
	}
483
484
	/**
485
	 * Alias for set_help_text()
486
	 *
487
	 * @see set_help_text()
488
	 * @return object $this
489
	 **/
490
	public function help_text( $help_text ) {
491
		return $this->set_help_text( $help_text );
492
	}
493
494
	/**
495
	 * Return the field help text
496
	 *
497
	 * @return object $this
498
	 **/
499
	public function get_help_text() {
500
		return $this->help_text;
501
	}
502
503
	/**
504
	 * Whether or not this value should be auto loaded. Applicable to theme options only.
505
	 *
506
	 * @param bool $autoload
507
	 * @return object $this
508
	 **/
509
	public function set_autoload( $autoload ) {
510
		$this->autoload = $autoload;
511
		return $this;
512
	}
513
514
	/**
515
	 * Return whether or not this value should be auto loaded.
516
	 *
517
	 * @return bool
518
	 **/
519
	public function get_autoload() {
520
		return $this->autoload;
521
	}
522
523
	/**
524
	 * Whether or not this field will be initialized when the field is in the viewport (visible).
525
	 *
526
	 * @param bool $lazyload
527
	 * @return object $this
528
	 **/
529
	public function set_lazyload( $lazyload ) {
530
		$this->lazyload = $lazyload;
531
		return $this;
532
	}
533
534
	/**
535
	 * Return whether or not this field should be lazyloaded.
536
	 *
537
	 * @return bool
538
	 **/
539
	public function get_lazyload() {
540
		return $this->lazyload;
541
	}
542
543
	/**
544
	 * Set the field width.
545
	 *
546
	 * @param int $width
547
	 * @return object $this
548
	 **/
549
	public function set_width( $width ) {
550
		$this->width = (int) $width;
551
		return $this;
552
	}
553
554
	/**
555
	 * Get the field width.
556
	 *
557
	 * @return int $width
558
	 **/
559
	public function get_width() {
560
		return $this->width;
561
	}
562
563
	/**
564
	 *  Add custom CSS class to the field html container.
565
	 *
566
	 * @param string|array $classes
567
	 * @return object $this
568
	 **/
569
	public function add_class( $classes ) {
570
		if ( ! is_array( $classes ) ) {
571
			$classes = array_values( array_filter( explode( ' ', $classes ) ) );
572
		}
573
574
		$this->classes = array_map( 'sanitize_html_class', $classes );
575
		return $this;
576
	}
577
578
	/**
579
	 * Get the field custom CSS classes.
580
	 *
581
	 * @return array
582
	 **/
583
	public function get_classes() {
584
		return $this->classes;
585
	}
586
587
	/**
588
	 * Whether this field is mandatory for the user
589
	 *
590
	 * @param bool $required
591
	 * @return object $this
592
	 **/
593
	public function set_required( $required ) {
594
		$this->required = $required;
595
		return $this;
596
	}
597
598
	/**
599
	 * HTML id attribute getter.
600
	 * @return string
601
	 */
602 1
	public function get_id() {
603 1
		return $this->id;
604
	}
605
606
	/**
607
	 * HTML id attribute setter
608
	 * @param string $id
609
	 */
610 1
	public function set_id( $id ) {
611 1
		$this->id = $id;
612 1
	}
613
614
	/**
615
	 * Return whether this field is mandatory for the user
616
	 *
617
	 * @return bool
618
	 **/
619
	public function is_required() {
620
		return $this->required;
621
	}
622
623
	/**
624
	 * Returns the type of the field based on the class.
625
	 * The class is stripped by the "CarbonFields" prefix.
626
	 * Also the "Field" suffix is removed.
627
	 * Then underscores and backslashes are removed.
628
	 *
629
	 * @return string
630
	 */
631
	public function get_type() {
632
		$class = get_class( $this );
633
634
		return $this->clean_type( $class );
635
	}
636
637
	/**
638
	 * Cleans up an object class for usage as HTML class
639
	 *
640
	 * @return string
641
	 */
642
	protected function clean_type( $type ) {
643
		$remove = array(
644
			'_',
645
			'\\',
646
			'CarbonFields',
647
			'Field',
648
		);
649
		$clean_class = str_replace( $remove, '', $type );
650
651
		return $clean_class;
652
	}
653
654
	/**
655
	 * Return an array of html classes to be used for the field container
656
	 *
657
	 * @return array
658
	 */
659
	public function get_html_class() {
660
		$html_classes = array();
661
662
		$object_class = get_class( $this );
663
		$html_classes[] = $this->get_type();
664
665
		$parent_class = $object_class;
666
		while ( $parent_class = get_parent_class( $parent_class ) ) {
667
			$clean_class = $this->clean_type( $parent_class );
668
669
			if ( $clean_class ) {
670
				$html_classes[] = $clean_class;
671
			}
672
		}
673
674
		return $html_classes;
675
	}
676
677
	/**
678
	 * Allows the value of a field to be processed after loading.
679
	 * Can be implemented by the extending class if necessary.
680
	 *
681
	 * @return array
682
	 */
683
	public function process_value() {
684
685
	}
686
687
	/**
688
	 * Returns an array that holds the field data, suitable for JSON representation.
689
	 * This data will be available in the Underscore template and the Backbone Model.
690
	 *
691
	 * @param bool $load  Should the value be loaded from the database or use the value from the current instance.
692
	 * @return array
693
	 */
694
	public function to_json( $load ) {
695
		if ( $load ) {
696
			$this->load();
697
		}
698
699
		$this->process_value();
700
701
		$field_data = array(
702
			'id' => $this->get_id(),
703
			'type' => $this->get_type(),
704
			'label' => $this->get_label(),
705
			'name' => $this->get_name(),
706
			'base_name' => $this->get_base_name(),
707
			'value' => $this->get_value(),
708
			'default_value' => $this->get_default_value(),
709
			'help_text' => $this->get_help_text(),
710
			'context' => $this->get_context(),
711
			'required' => $this->is_required(),
712
			'lazyload' => $this->get_lazyload(),
713
			'width' => $this->get_width(),
714
			'classes' => $this->get_classes(),
715
			'conditional_logic' => $this->get_conditional_logic(),
716
		);
717
718
		return $field_data;
719
	}
720
721
	/**
722
	 * Set the field visibility conditional logic.
723
	 *
724
	 * @param array
725
	 */
726 8
	public function set_conditional_logic( $rules ) {
727 8
		$this->conditional_logic = $this->parse_conditional_rules( $rules );
728
729 3
		return $this;
730
	}
731
732
	/**
733
	 * Get the conditional logic rules
734
	 *
735
	 * @return array
736
	 */
737 3
	public function get_conditional_logic() {
738 3
		return $this->conditional_logic;
739
	}
740
741
	/**
742
	 * Validate and parse the conditional logic rules.
743
	 *
744
	 * @param array $rules
745
	 * @return array
746
	 */
747
	protected function parse_conditional_rules( $rules ) {
748
		if ( ! is_array( $rules ) ) {
749
			Incorrect_Syntax_Exception::raise( 'Conditional logic rules argument should be an array.' );
750
		}
751
752
		$allowed_operators = array( '=', '!=', '>', '>=', '<', '<=', 'IN', 'NOT IN' );
753
		$allowed_relations = array( 'AND', 'OR' );
754
755
		$parsed_rules = array(
756
			'relation' => 'AND',
757
			'rules' => array(),
758
		);
759
760
		foreach ( $rules as $key => $rule ) {
761
			// Check if we have a relation key
762
			if ( $key === 'relation' ) {
763
				$relation = strtoupper( $rule );
764
765 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...
766
					Incorrect_Syntax_Exception::raise( 'Invalid relation type ' . $rule . '. ' .
767
					'The rule should be one of the following: "' . implode( '", "', $allowed_relations ) . '"' );
768
				}
769
770
				$parsed_rules['relation'] = $relation;
771
				continue;
772
			}
773
774
			// Check if the rule is valid
775
			if ( ! is_array( $rule ) || empty( $rule['field'] ) ) {
776
				Incorrect_Syntax_Exception::raise( 'Invalid conditional logic rule format. ' .
777
				'The rule should be an array with the "field" key set.' );
778
			}
779
780
			// Check the compare operator
781
			if ( empty( $rule['compare'] ) ) {
782
				$rule['compare'] = '=';
783
			}
784 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...
785
				Incorrect_Syntax_Exception::raise( 'Invalid conditional logic compare operator: <code>' .
786
					$rule['compare'] . '</code><br>Allowed operators are: <code>' .
787
				implode( ', ', $allowed_operators ) . '</code>' );
788
			}
789
			if ( $rule['compare'] === 'IN' || $rule['compare'] === 'NOT IN' ) {
790
				if ( ! is_array( $rule['value'] ) ) {
791
					Incorrect_Syntax_Exception::raise( 'Invalid conditional logic value format. ' .
792
					'An array is expected, when using the "' . $rule['compare'] . '" operator.' );
793
				}
794
			}
795
796
			// Check the value
797
			if ( ! isset( $rule['value'] ) ) {
798
				$rule['value'] = '';
799
			}
800
801
			$parsed_rules['rules'][] = $rule;
802
		}
803
804
		return $parsed_rules;
805
	}
806
807
808
	/**
809
	 * Hook administration scripts.
810
	 */
811
	public function admin_hook_scripts() {
812
		wp_enqueue_media();
813
		wp_enqueue_script( 'carbon-fields', \Carbon_Fields\URL . '/assets/js/fields.js', array( 'carbon-app', 'carbon-containers' ) );
814
		wp_localize_script( 'carbon-fields', 'crbl10n',
815
			array(
816
				'title' => __( 'Files', 'carbon_fields' ),
817
				'geocode_zero_results' => __( 'The address could not be found. ', 'carbon_fields' ),
818
				'geocode_not_successful' => __( 'Geocode was not successful for the following reason: ', 'carbon_fields' ),
819
				'max_num_items_reached' => __( 'Maximum number of items reached (%s items)', 'carbon_fields' ),
820
				'max_num_rows_reached' => __( 'Maximum number of rows reached (%s rows)', 'carbon_fields' ),
821
				'cannot_create_more_rows' => __( 'Cannot create more than %s rows', 'carbon_fields' ),
822
				'enter_name_of_new_sidebar' => __( 'Please enter the name of the new sidebar:', 'carbon_fields' ),
823
				'remove_sidebar_confirmation' => __( 'Are you sure you wish to remove this sidebar?', 'carbon_fields' ),
824
				'add_sidebar' => __( 'Add Sidebar', 'carbon_fields' ),
825
				'complex_no_rows' => __( 'There are no %s yet. Click <a href="#">here</a> to add one.', 'carbon_fields' ),
826
				'complex_add_button' => __( 'Add %s', 'carbon_fields' ),
827
				'complex_min_num_rows_not_reached' => __( 'Minimum number of rows not reached (%d %s)', 'carbon_fields' ),
828
				'message_form_validation_failed' => __( 'Please fill out all fields correctly. ', 'carbon_fields' ),
829
				'message_required_field' => __( 'This field is required. ', 'carbon_fields' ),
830
				'message_choose_option' => __( 'Please choose an option. ', 'carbon_fields' ),
831
			)
832
		);
833
	}
834
835
	/**
836
	 * Hook administration styles.
837
	 */
838
	public function admin_hook_styles() {
839
		wp_enqueue_style( 'thickbox' );
840
	}
841
} // END Field
842