Completed
Push — milestone/2_0/react-ui ( 1c376a...57d10c )
by
unknown
02:51
created

Container::get_field_by_name()   C

Complexity

Conditions 10
Paths 26

Size

Total Lines 47
Code Lines 34

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 110

Importance

Changes 0
Metric Value
cc 10
eloc 34
nc 26
nop 1
dl 0
loc 47
ccs 0
cts 36
cp 0
crap 110
rs 5.1578
c 0
b 0
f 0

How to fix   Complexity   

Long Method

Small methods make your code easier to understand, in particular if combined with a good name. Besides, if your method is small, finding a good name is usually much easier.

For example, if you find yourself adding comments to a method's body, this is usually a good sign to extract the commented part to a new method, and use the comment as a starting point when coming up with a good name for this new method.

Commonly applied refactorings include:

1
<?php
2
3
namespace Carbon_Fields\Container;
4
5
use Carbon_Fields\Helper\Helper;
6
use Carbon_Fields\Field\Field;
7
use Carbon_Fields\Field\Group_Field;
8
use Carbon_Fields\Container\Fulfillable\Fulfillable_Collection;
9
use Carbon_Fields\Datastore\Datastore_Interface;
10
use Carbon_Fields\Datastore\Datastore_Holder_Interface;
11
use Carbon_Fields\Exception\Incorrect_Syntax_Exception;
12
13
/**
14
 * Base container class.
15
 * Defines the key container methods and their default implementations.
16
 */
17
abstract class Container implements Datastore_Holder_Interface {
18
	/**
19
	 * Where to put a particular tab -- at the head or the tail. Tail by default
20
	 */
21
	const TABS_TAIL = 1;
22
	const TABS_HEAD = 2;
23
24
	/**
25
	 * Separator signifying field hierarchy relation
26
	 * Used when searching for fields in a specific complex field
27
	 */
28
	const HIERARCHY_FIELD_SEPARATOR = '/';
29
30
	/**
31
	 * Separator signifying complex_field->group relation
32
	 * Used when searching for fields in a specific complex field group
33
	 */
34
	const HIERARCHY_GROUP_SEPARATOR = ':';
35
36
	/**
37
	 * Stores if the container is active on the current page
38
	 *
39
	 * @see activate()
40
	 * @var bool
41
	 */
42
	protected $active = false;
43
44
	/**
45
	 * List of registered unique field names for this container instance
46
	 *
47
	 * @see register_field_name()
48
	 * @var array
49
	 */
50
	protected $registered_field_names = array();
51
52
	/**
53
	 * Tabs available
54
	 */
55
	protected $tabs = array();
56
57
	/**
58
	 * List of default container settings
59
	 *
60
	 * @see init()
61
	 * @var array
62
	 */
63
	public $settings = array();
64
65
	/**
66
	 * Title of the container
67
	 *
68
	 * @var string
69
	 */
70
	public $title = '';
71
72
	/**
73
	 * List of notification messages to be displayed on the front-end
74
	 *
75
	 * @var array
76
	 */
77
	protected $notifications = array();
78
79
	/**
80
	 * List of error messages to be displayed on the front-end
81
	 *
82
	 * @var array
83
	 */
84
	protected $errors = array();
85
86
	/**
87
	 * List of container fields
88
	 *
89
	 * @see add_fields()
90
	 * @var array
91
	 */
92
	protected $fields = array();
93
94
	/**
95
	 * Array of custom CSS classes.
96
	 *
97
	 * @see add_class()
98
	 * @see get_classes()
99
	 * @var array<string>
100
	 */
101
	protected $classes = array();
102
103
	/**
104
	 * Container datastores. Propagated to all container fields
105
	 *
106
	 * @see set_datastore()
107
	 * @see get_datastore()
108
	 * @var object
109
	 */
110
	protected $datastore;
111
112
	/**
113
	 * Flag whether the datastore is the default one or replaced with a custom one
114
	 *
115
	 * @see set_datastore()
116
	 * @see get_datastore()
117
	 * @var boolean
118
	 */
119
	protected $has_default_datastore = true;
120
121
	/**
122
	 * Fulfillable_Collection to use when checking attachment/saving conditions
123
	 *
124
	 * @var Fulfillable_Collection
125
	 */
126
	protected $condition_collection;
127
128
	/**
129
	 * Get array of all static condition types
130
	 *
131
	 * @param  boolean       $static
132
	 * @return array<string>
133
	 */
134
	protected function get_condition_types( $static ) {
135
		$group = $static ? 'static' : 'dynamic';
136
		$container_type = Helper::class_to_type( get_class( $this ), '_Container' );
137
138
		$condition_types = array();
139
		$condition_types = apply_filters( 'carbon_fields_' . $container_type . '_container_' . $group . '_condition_types', $condition_types, $container_type, $this );
140
		$condition_types = apply_filters( 'carbon_fields_container_' . $group . '_condition_types', $condition_types, $container_type, $this );
141
142
		return $condition_types;
143
	}
144
145
	/**
146
	 * Create a new container of type $type and name $name.
147
	 *
148
	 * @param string $type
149
	 * @param string $name Human-readable name of the container
150
	 * @return object $container
151
	 */
152 8
	public static function factory( $type, $name ) {
153 8
		$normalized_type = Helper::normalize_type( $type );
154 8
		$class = Helper::type_to_class( $normalized_type, __NAMESPACE__, '_Container' );
155
156 8 View Code Duplication
		if ( ! class_exists( $class ) ) {
157 3
			Incorrect_Syntax_Exception::raise( 'Unknown container "' . $type . '".' );
158 1
			$class = __NAMESPACE__ . '\\Broken_Container';
159 1
		}
160
161 6
		$repository = \Carbon_Fields\Carbon_Fields::resolve( 'container_repository' );
162 6
		$unique_id = $repository->get_unique_panel_id( $name );
163 6
		$container = new $class( $unique_id, $name, $normalized_type );
164 6
		$repository->register_container( $container );
165
166 6
		return $container;
167
	}
168
169
	/**
170
	 * An alias of factory().
171
	 *
172
	 * @see Container::factory()
173
	 */
174
	public static function make( $type, $name ) {
175
		return static::factory( $type, $name );
176
	}
177
178
	/**
179
	 * Create a new container
180
	 *
181
	 * @param string $unique_id Unique id of the container
182
	 * @param string $title title of the container
183
	 * @param string $type Type of the container
184
	 */
185 2
	public function __construct( $unique_id, $title, $type ) {
186 2
		\Carbon_Fields\Carbon_Fields::verify_boot();
187
188 2
		if ( empty( $title ) ) {
189 1
			Incorrect_Syntax_Exception::raise( 'Empty container title is not supported' );
190
		}
191
192 1
		$this->id = $unique_id;
193 1
		$this->title = $title;
194 1
		$this->type = $type;
195 1
		$this->condition_collection = \Carbon_Fields\Carbon_Fields::resolve( 'container_condition_fulfillable_collection' );
196 1
		$this->condition_collection->set_condition_type_list(
197 1
			array_merge( $this->get_condition_types( true ), $this->get_condition_types( false ) ),
198
			true
199 1
		);
200 1
	}
201
202
	/**
203
	 * Return whether the container is active
204
	 */
205
	public function active() {
206
		return $this->active;
207
	}
208
209
	/**
210
	 * Activate the container and trigger an action
211
	 */
212
	protected function activate() {
213
		$this->active = true;
214
		$this->boot();
215
		do_action( 'crb_container_activated', $this );
216
217
		$fields = $this->get_fields();
218
		foreach ( $fields as $field ) {
219
			$field->activate();
220
		}
221
	}
222
223
	/**
224
	 * Perform instance initialization
225
	 */
226
	abstract public function init();
227
228
	/**
229
	 * Boot the container once it's attached.
230
	 */
231
	protected function boot() {
232
		add_action( 'admin_print_footer_scripts', array( get_class(), 'admin_hook_styles' ), 5 );
233
	}
234
235
	/**
236
	 * Load the value for each field in the container.
237
	 * Could be used internally during container rendering
238
	 */
239
	public function load() {
240
		foreach ( $this->fields as $field ) {
241
			$field->load();
242
		}
243
	}
244
245
	/**
246
	 * Called first as part of the container save procedure.
247
	 * Responsible for checking the request validity and
248
	 * calling the container-specific save() method
249
	 *
250
	 * @see save()
251
	 * @see is_valid_save()
252
	 */
253
	public function _save() {
254
		$param = func_get_args();
255
		if ( call_user_func_array( array( $this, '_is_valid_save' ), $param ) ) {
256
			call_user_func_array( array( $this, 'save' ), $param );
257
		}
258
	}
259
260
	/**
261
	 * Load submitted data and save each field in the container
262
	 *
263
	 * @see is_valid_save()
264
	 */
265
	public function save( $data = null ) {
266
		foreach ( $this->fields as $field ) {
267
			$field->set_value_from_input( stripslashes_deep( $_POST ) );
268
			$field->save();
269
		}
270
	}
271
272
	/**
273
	 * Checks whether the current save request is valid
274
	 *
275
	 * @return bool
276
	 **/
277
	final protected function _is_valid_save() {
278
		$params = func_get_args();
279
		$is_valid_save = call_user_func_array( array( $this, 'is_valid_save' ), $params );
280
		return apply_filters( 'carbon_fields_container_is_valid_save', $is_valid_save, $this );
281
	}
282
283
	/**
284
	 * Checks whether the current save request is valid
285
	 *
286
	 * @return bool
287
	 **/
288
	abstract protected function is_valid_save();
289
290
	/**
291
	 * Called first as part of the container attachment procedure.
292
	 * Responsible for checking it's OK to attach the container
293
	 * and if it is, calling the container-specific attach() method
294
	 *
295
	 * @see attach()
296
	 * @see is_valid_attach()
297
	 */
298
	public function _attach() {
299
		$param = func_get_args();
300
		if ( $this->is_valid_attach() ) {
301
			call_user_func_array( array( $this, 'attach' ), $param );
302
303
			// Allow containers to activate but not load (useful in cases such as theme options)
304
			if ( $this->should_activate() ) {
305
				$this->activate();
306
			}
307
		}
308
	}
309
310
	/**
311
	 * Attach the container rendering and helping methods
312
	 * to concrete WordPress Action hooks
313
	 */
314
	public function attach() {}
315
316
	/**
317
	 * Perform checks whether the container should be attached during the current request
318
	 *
319
	 * @return bool True if the container is allowed to be attached
320
	 */
321
	final public function is_valid_attach() {
322
		$is_valid_attach = $this->is_valid_attach_for_request();
323
		return apply_filters( 'carbon_fields_container_is_valid_attach', $is_valid_attach, $this );
324
	}
325
326
	/**
327
	 * Get environment array for page request (in admin)
328
	 *
329
	 * @return array
330
	 */
331
	abstract protected function get_environment_for_request();
332
333
	/**
334
	 * Check container attachment rules against current page request (in admin)
335
	 *
336
	 * @return bool
337
	 */
338
	abstract protected function is_valid_attach_for_request();
339
340
	/**
341
	 * Check if conditions pass for request
342
	 *
343
	 * @return bool
344
	 */
345
	protected function static_conditions_pass() {
346
		$environment = $this->get_environment_for_request();
347
		$static_condition_collection = $this->condition_collection->evaluate(
348
			$this->get_condition_types( false ),
349
			true
350
		);
351
		return $static_condition_collection->is_fulfilled( $environment );
352
	}
353
354
	/**
355
	 * Get environment array for object id
356
	 *
357
	 * @param integer $object_id
358
	 * @return array
359
	 */
360
	abstract protected function get_environment_for_object( $object_id );
361
362
	/**
363
	 * Check container attachment rules against object id
364
	 *
365
	 * @param int $object_id
366
	 * @return bool
367
	 */
368
	abstract public function is_valid_attach_for_object( $object_id );
369
370
	/**
371
	 * Check if all conditions pass for object
372
	 *
373
	 * @return bool
374
	 */
375
	protected function all_conditions_pass( $object_id ) {
376
		$environment = $this->get_environment_for_object( $object_id );
377
		return $this->condition_collection->is_fulfilled( $environment );
378
	}
379
380
	/**
381
	 * Whether this container is currently viewed.
382
	 */
383
	public function should_activate() {
384
		return $this->is_valid_attach();
385
	}
386
387
	/**
388
	 * Perform a check whether the current container has fields
389
	 *
390
	 * @return bool
391
	 */
392
	public function has_fields() {
393
		return (bool) $this->fields;
394
	}
395
396
	/**
397
	 * Returns the private container array of fields.
398
	 * Use only if you are completely aware of what you are doing.
399
	 *
400
	 * @return array
401
	 */
402
	public function get_fields() {
403
		return $this->fields;
404
	}
405
406
	/**
407
	 * Return root field from container with specified name
408
	 *
409
	 * @example crb_complex
410
	 *
411
	 * @param string $field_name
412
	 * @return Field
413
	 */
414
	public function get_root_field_by_name( $field_name ) {
415
		$fields = $this->get_fields();
416
		foreach ( $fields as $field ) {
417
			if ( $field->get_base_name() === $field_name ) {
418
				return $field;
419
			}
420
		}
421
		return null;
422
	}
423
424
	/**
425
	 * Get a regex to match field name patterns used to fetch specific fields
426
	 *
427
	 * @return string
428
	 */
429
	protected function get_field_pattern_regex() {
430
		// matches:
431
		// field_name
432
		// field_name[0]
433
		// field_name[0]:group_name
434
		// field_name:group_name
435
		$regex = '/
436
			\A
437
			(?P<field_name>[a-z0-9_]+)
438
			(?:\[(?P<group_index>\d+)\])?
439
			(?:' .  preg_quote( static::HIERARCHY_GROUP_SEPARATOR, '/' ). '(?P<group_name>[a-z0-9_]+))?
440
			\z
441
		/x';
442
		return $regex;
443
	}
444
445
	/**
446
	 * Return field from container with specified name
447
	 *
448
	 * @example crb_complex/text_field
449
	 * @example crb_complex/complex_2
450
	 * @example crb_complex/complex_2:text_group/text_field
451
	 *
452
	 * @param string $field_name Can specify a field inside a complex with a / (slash) separator
453
	 * @return Field
454
	 */
455
	public function get_field_by_name( $field_name ) {
456
		$hierarchy = array_filter( explode( static::HIERARCHY_FIELD_SEPARATOR, $field_name ) );
457
		$field = null;
458
459
		$field_group = $this->get_fields();
460
		$hierarchy_left = $hierarchy;
461
		$field_pattern_regex = $this->get_field_pattern_regex();
462
		$hierarchy_index = array();
463
464
		while ( ! empty( $hierarchy_left ) ) {
465
			$segment = array_shift( $hierarchy_left );
466
			$segment_pieces = array();
467
			if ( ! preg_match( $field_pattern_regex, $segment, $segment_pieces ) ) {
468
				Incorrect_Syntax_Exception::raise( 'Invalid field name pattern used: ' . $field_name );
469
				return null;
470
			}
471
472
			$segment_field_name = $segment_pieces['field_name'];
473
			$segment_group_index = isset( $segment_pieces['group_index'] ) ? $segment_pieces['group_index'] : 0;
474
			$segment_group_name = isset( $segment_pieces['group_name'] ) ? $segment_pieces['group_name'] : Group_Field::DEFAULT_GROUP_NAME;
475
476
			foreach ( $field_group as $f ) {
477
				if ( $f->get_base_name() === $segment_field_name ) {
478
					if ( empty( $hierarchy_left ) ) {
479
						$field = clone $f;
480
						$field->set_hierarchy_index( $hierarchy_index );
481
					} else {
482
						if ( is_a( $f, 'Carbon_Fields\\Field\\Complex_Field' ) ) {
483
							$group = $f->get_group_by_name( $segment_group_name );
484
							if ( ! $group ) {
485
								Incorrect_Syntax_Exception::raise( 'Unknown group name specified when fetching a value inside a complex field: "' . $segment_group_name . '".' );
486
								return null;
487
							}
488
							$field_group = $group->get_fields();
489
							$hierarchy_index[] = $segment_group_index;
490
						} else {
491
							Incorrect_Syntax_Exception::raise( 'Attempted to look for a nested field inside a non-complex field.' );
492
							return null;
493
						}
494
					}
495
					break;
496
				}
497
			}
498
		}
499
500
		return $field;
501
	}
502
503
	/**
504
	 * Perform checks whether there is a field registered with the name $name.
505
	 * If not, the field name is recorded.
506
	 *
507
	 * @param string $name
508
	 * @return boolean
509
	 */
510 View Code Duplication
	public function register_field_name( $name ) {
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...
511
		if ( in_array( $name, $this->registered_field_names ) ) {
512
			Incorrect_Syntax_Exception::raise( 'Field name "' . $name . '" already registered' );
513
			return false;
514
		}
515
516
		$this->registered_field_names[] = $name;
517
		return true;
518
	}
519
520
	/**
521
	 * Remove field name $name from the list of unique field names
522
	 *
523
	 * @param string $name
524
	 */
525
	public function drop_unique_field_name( $name ) {
526
		$index = array_search( $name, $this->registered_field_names );
527
528
		if ( $index !== false ) {
529
			unset( $this->registered_field_names[ $index ] );
530
		}
531
	}
532
533
	/**
534
	 * Return whether the datastore instance is the default one or has been overriden
535
	 *
536
	 * @return boolean
537
	 */
538 6
	public function has_default_datastore() {
539 6
		return $this->has_default_datastore;
540
	}
541
542
	/**
543
	 * Set datastore instance
544
	 *
545
	 * @param Datastore_Interface $datastore
546
	 * @return object $this
547
	 */
548 6 View Code Duplication
	public function set_datastore( Datastore_Interface $datastore, $set_as_default = false ) {
549 6
		if ( $set_as_default && ! $this->has_default_datastore() ) {
550 1
			return $this; // datastore has been overriden with a custom one - abort changing to a default one
551
		}
552 6
		$this->datastore = $datastore;
553 6
		$this->has_default_datastore = $set_as_default;
554
555 6
		foreach ( $this->fields as $field ) {
556
			$field->set_datastore( $this->get_datastore(), true );
557 6
		}
558 6
		return $this;
559
	}
560
561
	/**
562
	 * Get the DataStore instance
563
	 *
564
	 * @return Datastore_Interface $datastore
565
	 */
566 6
	public function get_datastore() {
567 6
		return $this->datastore;
568
	}
569
570
	/**
571
	 * Return WordPress nonce name used to identify the current container instance
572
	 *
573
	 * @return string
574
	 */
575
	public function get_nonce_name() {
576
		return 'carbon_panel_' . $this->id . '_nonce';
577
	}
578
579
	/**
580
	 * Return WordPress nonce name used to identify the current container instance
581
	 *
582
	 * @return string
583
	 */
584
	public function get_nonce_value() {
585
		return wp_create_nonce( $this->get_nonce_name() );
586
	}
587
588
	/**
589
	 * Check if the nonce is present in the request and that it is verified
590
	 *
591
	 * @return bool
592
	 */
593
	protected function verified_nonce_in_request() {
594
		$input = stripslashes_deep( $_REQUEST );
595
		$nonce_name = $this->get_nonce_name();
596
		$nonce_value = isset( $input[ $nonce_name ] ) ? $input[ $nonce_name ] : '';
597
		return wp_verify_nonce( $nonce_value, $nonce_name );
598
	}
599
600
	/**
601
	 * Internal function that creates the tab and associates it with particular field set
602
	 *
603
	 * @param string $tab_name
604
	 * @param array $fields
605
	 * @param int $queue_end
606
	 * @return object $this
607
	 */
608
	private function create_tab( $tab_name, $fields, $queue_end = self::TABS_TAIL ) {
609
		if ( isset( $this->tabs[ $tab_name ] ) ) {
610
			Incorrect_Syntax_Exception::raise( "Tab name duplication for $tab_name" );
611
		}
612
613
		if ( $queue_end === static::TABS_TAIL ) {
614
			$this->tabs[ $tab_name ] = array();
615
		} else if ( $queue_end === static::TABS_HEAD ) {
616
			$this->tabs = array_merge(
617
				array( $tab_name => array() ),
618
				$this->tabs
619
			);
620
		}
621
622
		foreach ( $fields as $field ) {
623
			$field_name = $field->get_name();
624
			$this->tabs[ $tab_name ][ $field_name ] = $field;
625
		}
626
627
		$this->settings['tabs'] = $this->get_tabs_json();
628
	}
629
630
	/**
631
	 * Whether the container is tabbed or not
632
	 *
633
	 * @return bool
634
	 */
635
	public function is_tabbed() {
636
		return (bool) $this->tabs;
637
	}
638
639
	/**
640
	 * Retrieve all fields that are not defined under a specific tab
641
	 *
642
	 * @return array
643
	 */
644
	protected function get_untabbed_fields() {
645
		$tabbed_fields_names = array();
646
		foreach ( $this->tabs as $tab_fields ) {
647
			$tabbed_fields_names = array_merge( $tabbed_fields_names, array_keys( $tab_fields ) );
648
		}
649
650
		$all_fields_names = array();
651
		foreach ( $this->fields as $field ) {
652
			$all_fields_names[] = $field->get_name();
653
		}
654
655
		$fields_not_in_tabs = array_diff( $all_fields_names, $tabbed_fields_names );
656
657
		$untabbed_fields = array();
658
		foreach ( $this->fields as $field ) {
659
			if ( in_array( $field->get_name(), $fields_not_in_tabs ) ) {
660
				$untabbed_fields[] = $field;
661
			}
662
		}
663
664
		return $untabbed_fields;
665
	}
666
667
	/**
668
	 * Retrieve all tabs.
669
	 * Create a default tab if there are any untabbed fields.
670
	 *
671
	 * @return array
672
	 */
673
	protected function get_tabs() {
674
		$untabbed_fields = $this->get_untabbed_fields();
675
676
		if ( ! empty( $untabbed_fields ) ) {
677
			$this->create_tab( __( 'General', 'carbon-fields' ), $untabbed_fields, static::TABS_HEAD );
678
		}
679
680
		return $this->tabs;
681
	}
682
683
	/**
684
	 * Build the tabs JSON
685
	 *
686
	 * @return array
687
	 */
688
	protected function get_tabs_json() {
689
		$tabs_json = array();
690
		$tabs = $this->get_tabs();
691
692
		foreach ( $tabs as $tab_name => $fields ) {
693
			foreach ( $fields as $field_name => $field ) {
694
				$tabs_json[ $tab_name ][] = $field_name;
695
			}
696
		}
697
698
		return $tabs_json;
699
	}
700
701
	/**
702
	 * Get custom CSS classes.
703
	 *
704
	 * @return array<string>
705
	 */
706
	public function get_classes() {
707
		return $this->classes;
708
	}
709
710
	/**
711
	 * Set CSS classes that the container should use.
712
	 *
713
	 * @param string|array<string> $classes
714
	 * @return object $this
715
	 */
716
	public function set_classes( $classes ) {
717
		$this->classes = Helper::sanitize_classes( $classes );
718
		return $this;
719
	}
720
721
	/**
722
	 * Returns an array that holds the container data, suitable for JSON representation.
723
	 *
724
	 * @param bool $load  Should the value be loaded from the database or use the value from the current instance.
725
	 * @return array
726
	 */
727
	public function to_json( $load ) {
728
		$array_translator = \Carbon_Fields\Carbon_Fields::resolve( 'container_condition_translator_array' );
729
		$conditions = $this->condition_collection->evaluate( $this->get_condition_types( true ), $this->get_environment_for_request(), array( 'CUSTOM' ) );
730
		$conditions = $array_translator->fulfillable_to_foreign( $conditions );
731
		$conditions = $array_translator->foreign_to_json( $conditions );
732
733
		$container_data = array(
734
			'id' => $this->id,
735
			'type' => $this->type,
736
			'title' => $this->title,
737
			'classes' => $this->get_classes(),
738
			'settings' => $this->settings,
739
			'conditions' => $conditions,
740
			'fields' => array(),
741
			'nonce' => array(
742
				'name' => $this->get_nonce_name(),
743
				'value' => $this->get_nonce_value(),
744
			),
745
		);
746
747
		$fields = $this->get_fields();
748
		foreach ( $fields as $field ) {
749
			$field_data = $field->to_json( $load );
750
			$container_data['fields'][] = $field_data;
751
		}
752
753
		return $container_data;
754
	}
755
756
	/**
757
	 * Enqueue admin styles
758
	 */
759
	public static function admin_hook_styles() {
760
		wp_enqueue_style( 'carbon-main', \Carbon_Fields\URL . '/assets/dist/carbon.css', array(), \Carbon_Fields\VERSION );
761
	}
762
763
	/**
764
	 * COMMON USAGE METHODS
765
	 */
766
767
	/**
768
	 * Append array of fields to the current fields set. All items of the array
769
	 * must be instances of Field and their names should be unique for all
770
	 * Carbon containers.
771
	 * If a field does not have DataStore already, the container datastore is
772
	 * assigned to them instead.
773
	 *
774
	 * @param array $fields
775
	 * @return object $this
776
	 */
777
	public function add_fields( $fields ) {
778
		foreach ( $fields as $field ) {
779
			if ( ! is_a( $field, 'Carbon_Fields\\Field\\Field' ) ) {
780
				Incorrect_Syntax_Exception::raise( 'Object must be of type Carbon_Fields\\Field\\Field' );
781
				return $this;
782
			}
783
784
			$unique = $this->register_field_name( $field->get_name() );
785
			if ( ! $unique ) {
786
				return $this;
787
			}
788
789
			$field->set_context( $this->type );
790
			if ( ! $field->get_datastore() ) {
791
				$field->set_datastore( $this->get_datastore(), $this->has_default_datastore() );
792
			}
793
		}
794
795
		$this->fields = array_merge( $this->fields, $fields );
796
797
		return $this;
798
	}
799
800
	/**
801
	 * Configuration function for adding tab with fields
802
	 *
803
	 * @param string $tab_name
804
	 * @param array $fields
805
	 * @return object $this
806
	 */
807
	public function add_tab( $tab_name, $fields ) {
808
		$this->add_fields( $fields );
809
		$this->create_tab( $tab_name, $fields );
810
		return $this;
811
	}
812
813
	/**
814
	 * Proxy function to set attachment conditions
815
	 *
816
	 * @see    Fulfillable_Collection::when()
817
	 * @return Container $this
818
	 */
819
	public function when() {
820
		call_user_func_array( array( $this->condition_collection, 'when' ), func_get_args() );
821
		return $this;
822
	}
823
824
	/**
825
	 * Proxy function to set attachment conditions
826
	 *
827
	 * @see    Fulfillable_Collection::and_when()
828
	 * @return Container $this
829
	 */
830
	public function and_when() {
831
		call_user_func_array( array( $this->condition_collection, 'and_when' ), func_get_args() );
832
		return $this;
833
	}
834
835
	/**
836
	 * Proxy function to set attachment conditions
837
	 *
838
	 * @see    Fulfillable_Collection::or_when()
839
	 * @return Container $this
840
	 */
841
	public function or_when() {
842
		call_user_func_array( array( $this->condition_collection, 'or_when' ), func_get_args() );
843
		return $this;
844
	}
845
}
846