Completed
Push — milestone/2.0 ( 1de7af...3b05d3 )
by
unknown
08:25
created

Complex_Field::set_collapsed()   A

Complexity

Conditions 1
Paths 1

Size

Total Lines 4
Code Lines 3

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 2

Importance

Changes 0
Metric Value
cc 1
eloc 3
nc 1
nop 1
dl 0
loc 4
ccs 0
cts 3
cp 0
crap 2
rs 10
c 0
b 0
f 0
1
<?php
2
3
namespace Carbon_Fields\Field;
4
5
use Carbon_Fields\Datastore\Datastore_Interface;
6
use Carbon_Fields\Helper\Helper;
7
use Carbon_Fields\Field\Field;
8
use Carbon_Fields\Field\Group_Field;
9
use Carbon_Fields\Value_Set\Value_Set;
10
use Carbon_Fields\Exception\Incorrect_Syntax_Exception;
11
12
/**
13
 * Complex field class.
14
 * Allows nested repeaters with multiple field groups to be created.
15
 */
16
class Complex_Field extends Field {
17
18
	/**
19
	 * Visual layout type constants
20
	 */
21
	const LAYOUT_GRID = 'grid'; // default
22
23
	const LAYOUT_TABBED_HORIZONTAL = 'tabbed-horizontal';
24
25
	const LAYOUT_TABBED_VERTICAL = 'tabbed-vertical';
26
27
	/**
28
	 * Key which defines what a group's type/name is
29
	 */
30
	const GROUP_TYPE_KEY = '_type';
31
32
	/**
33
	 * Default field value
34
	 *
35
	 * @var array
36
	 */
37
	protected $default_value = array();
38
39
	/**
40
	 * Complex field layout
41
	 * 
42
	 * @var string static::LAYOUT_* constant
43
	 */
44
	protected $layout = self::LAYOUT_GRID;
45
46
	/**
47
	 * Value tree describing the complex values ( ['value_set'] ) and all groups with their child fields ( ['groups'] )
48
	 * 
49
	 * @var array
50
	 */
51
	protected $value_tree = array(
52
		'value_set' => array(),
53
		'groups' => array(),
54
	);
55
56
	/**
57
	 * Array of groups registered for this complex field
58
	 * 
59
	 * @var array
60
	 */
61
	protected $groups = array();
62
63
	/**
64
	 * Minimum number of entries. -1 for no limit
65
	 * 
66
	 * @var integer
67
	 */
68
	protected $values_min = -1;
69
70
	/**
71
	 * Maximum number of entries. -1 for no limit
72
	 * 
73
	 * @var integer
74
	 */
75
	protected $values_max = -1;
76
77
	/**
78
	 * Default entry state - collapsed or not
79
	 * 
80
	 * @var boolean
81
	 */
82
	protected $collapsed = false;
83
84
	/**
85
	 * Entry labels
86
	 * These are translated in init()
87
	 * 
88
	 * @var array
89
	 */
90
	public $labels = array(
91
		'singular_name' => 'Entry',
92
		'plural_name' => 'Entries',
93
	);
94
95
	/**
96
	 * Create a field from a certain type with the specified label.
97
	 * 
98
	 * @param string $type  Field type
99
	 * @param string $name  Field name
100
	 * @param string $label Field label
101
	 */
102
	protected function __construct( $type, $name, $label ) {
103
		$this->set_value_set( new Value_Set( Value_Set::TYPE_MULTIPLE_VALUES ) );
104
		parent::__construct( $type, $name, $label );
105
	}
106
107
	/**
108
	 * Initialization tasks.
109
	 */
110
	public function init() {
111
		$this->labels = array(
112
			'singular_name' => __( $this->labels['singular_name'], \Carbon_Fields\TEXT_DOMAIN ),
1 ignored issue
show
introduced by
Expected next thing to be a escaping function, not '$this'
Loading history...
113
			'plural_name' => __( $this->labels['plural_name'], \Carbon_Fields\TEXT_DOMAIN ),
1 ignored issue
show
introduced by
Expected next thing to be a escaping function, not '$this'
Loading history...
114
		);
115
116
		// Include the complex group Underscore templates
117
		$this->add_template( 'Complex-Group', array( $this, 'template_group' ) );
118
		$this->add_template( 'Complex-Group-Tab-Item', array( $this, 'template_group_tab_item' ) );
119
120
		parent::init();
121
	}
122
123
	/**
124
	 * Set array of hierarchy field names
125
	 */
126
	public function set_hierarchy( $hierarchy ) {
127
		parent::set_hierarchy( $hierarchy );
128
		$this->update_child_hierarchy();
129
	}
130
	
131
	/**
132
	 * Propagate hierarchy to child fields
133
	 */
134
	public function update_child_hierarchy() {
135
		$hierarchy = array_merge( $this->get_hierarchy(), array( $this->get_base_name() ) );
136
		$fields = $this->get_fields();
137
		foreach ( $fields as $field ) {
138
			$field->set_hierarchy( $hierarchy );
139
		}
140
	}
141
142
	/**
143
	 * Activate the field once the container is attached.
144
	 */
145
	public function activate() {
146
		parent::activate();
147
		$fields = $this->get_fields();
148
		foreach ( $fields as $field ) {
149
			$field->activate();
150
		}
151
	}
152
153
	/**
154
	 * Set the datastore of this field and propagate it to children
155
	 *
156
	 * @param Datastore_Interface $datastore
157
	 */
158 View Code Duplication
	public function set_datastore( Datastore_Interface $datastore, $set_as_default = false ) {
159
		if ( $set_as_default && ! $this->has_default_datastore() ) {
160
			return $this; // datastore has been overriden with a custom one - abort changing to a default one
161
		}
162
		$this->datastore = $datastore;
163
		$this->has_default_datastore = $set_as_default;
164
165
		foreach ( $this->groups as $group ) {
166
			$group->set_datastore( $this->get_datastore(), true );
167
		}
168
		return $this;
169
	}
170
171
	/**
172
	 * Retrieve all groups of fields.
173
	 *
174
	 * @return array $fields
175
	 */
176
	public function get_fields() {
177
		$fields = array();
178
179
		foreach ( $this->groups as $group ) {
180
			$group_fields = $group->get_fields();
181
182
			$fields = array_merge( $fields, $group_fields );
183
		}
184
185
		return $fields;
186
	}
187
188
	/**
189
	 * Add a set/group of fields.
190
	 *
191
	 * Accepted param variations:
192
	 *   - array<Field> $fields
193
	 *   - string $group_name, array<Field> $fields
194
	 *   - string $group_name, string $group_label, array<Field> $fields
195
	 * 
196
	 * @return $this
197
	 */
198
	public function add_fields() {
199
		$argv = func_get_args();
200
		$argc = count( $argv );
201
		$fields = $argv[ $argc - 1 ];
202
		$name = '';
203
		$label = null;
204
205
		if ( $argc >= 2 ) {
206
			$name = $argv[0];
207
		}
208
		
209
		if ( $argc >= 3 ) {
210
			$label = $argv[1];
211
		}
212
213
		$name = ! empty( $name ) ? $name : Group_Field::DEFAULT_GROUP_NAME;
214
215
		if ( array_key_exists( $name, $this->groups ) ) {
216
			Incorrect_Syntax_Exception::raise( 'Group with name "' . $name . '" in Complex Field "' . $this->get_label() . '" already exists.' );
217
		}
218
219
		foreach ( $fields as $field ) {
220
			if ( $field->get_base_name() === static::GROUP_TYPE_KEY ) {
221
				Incorrect_Syntax_Exception::raise( '"' . static::GROUP_TYPE_KEY . '" is a reserved keyword for Complex fields and cannot be used for a field name.' );
222
			}
223
		}
224
225
		$group = new Group_Field( $name, $label, $fields );
226
227
		$this->groups[ $group->get_name() ] = $group;
228
		$this->update_child_hierarchy();
229
230
		return $this;
231
	}
232
233
	/**
234
	 * Retrieve the groups of this field.
235
	 *
236
	 * @return array
237
	 */
238
	public function get_group_names() {
239
		return array_keys( $this->groups );
240
	}
241
242
	/**
243
	 * Retrieve a group by its name.
244
	 *
245
	 * @param  string $group_name        Group name
246
	 * @return Group_Field $group_object Group object
247
	 */
248
	public function get_group_by_name( $group_name ) {
249
		$group_object = null;
250
251
		foreach ( $this->groups as $group ) {
252
			if ( $group->get_name() == $group_name ) {
253
				$group_object = $group;
254
			}
255
		}
256
257
		return $group_object;
258
	}
259
260
	/**
261
	 * Set the group label Underscore template.
262
	 *
263
	 * @param  string|callable $template
264
	 * @return $this
265
	 */
266
	public function set_header_template( $template ) {
267
		if ( count( $this->groups ) === 0 ) {
268
			Incorrect_Syntax_Exception::raise( "Can't set group label template. There are no present groups for Complex Field " . $this->get_label() . '.' );
269
		}
270
271
		$template = is_callable( $template ) ? call_user_func( $template ) : $template;
272
273
		// Assign the template to the group that was added last
274
		$values = array_values( $this->groups );
275
		$group = end( $values );
276
		$group->set_label_template( $template );
277
278
		// Include the group label Underscore template
279
		$this->add_template( $group->get_group_id(), array( $group, 'template_label' ) );
280
281
		$this->groups[ $group->get_name() ] = $group;
282
283
		return $this;
284
	}
285
286
	/**
287
	 * Set the field labels.
288
	 * Currently supported values:
289
	 *  - singular_name - the singular entry label
290
	 *  - plural_name - the plural entries label
291
	 *
292
	 * @param  array $labels Labels
293
	 */
294
	public function setup_labels( $labels ) {
295
		$this->labels = array_merge( $this->labels, $labels );
296
		return $this;
297
	}
298
299
	/**
300
	 * Return a clone of a field with hierarchy settings applied
301
	 *
302
	 * @param Field $field
303
	 * @param Field $parent_field
304
	 * @param int $group_index
305
	 * @return Field
306
	 */
307
	public function get_clone_under_field_in_hierarchy( $field, $parent_field, $group_index = 0 ) {
308
		$clone = clone $field;
309
		$clone->set_hierarchy( array_merge( $parent_field->get_hierarchy(), array( $parent_field->get_base_name() ) ) );
310
		$clone->set_hierarchy_index( array_merge( $parent_field->get_hierarchy_index(), array( $group_index ) ) );
311
		return $clone;
312
	}
313
314
	protected function get_prefilled_field_groups( $value_tree ) {
315
		$fields = array();
316
317
		if ( empty( $value_tree ) ) {
318
			return $fields;
319
		}
320
321
		foreach ( $value_tree['value_set'] as $group_index => $value ) {
322
			$group_name = $value[ Value_Set::VALUE_PROPERTY ];
323
			$group = $this->get_group_by_name( $group_name );
324
			$group_fields = $group->get_fields();
325
			$fields[ $group_index ] = array(
326
				static::GROUP_TYPE_KEY => $group->get_name(),
327
			);
328
			$group_values = array();
329
			if ( isset( $value_tree['groups'][ $group_index ] ) ) {
330
				$group_values = $value_tree['groups'][ $group_index ];
331
			}
332
333
			foreach ( $group_fields as $field ) {
334
				$clone = $this->get_clone_under_field_in_hierarchy( $field, $this, $group_index );
335
				if ( isset( $group_values[ $clone->get_base_name() ] ) ) {
336
					$group_value = $group_values[ $clone->get_base_name() ];
337
					
338
					if ( isset( $group_value['value_set'] ) ) {
339
						$clone->set_value( $group_value['value_set'] );
340
					}
341
342
					if ( is_a( $clone, get_class() ) ) {
343
						$clone->set_value_tree( $group_value );
344
					}
345
				}
346
				$fields[ $group_index ][] = $clone;
347
			}
348
		}
349
350
		return $fields;
351
	}
352
353
	/**
354
	 * Load the field value from an input array based on it's name.
355
	 *
356
	 * @param array $input Array of field names and values.
357
	 */
358
	public function set_value_from_input( $input ) {
359
		if ( ! isset( $input[ $this->get_name() ] ) ) {
360
			return;
361
		}
362
363
		$value_tree = array(
364
			'value_set' => array(),
365
			'groups' => array(),
366
		);
367
		$input_groups = $input[ $this->get_name() ];
368
		$input_group_index = 0;
369
		foreach ( $input_groups as $values ) {
370
			if ( ! isset( $values[ static::GROUP_TYPE_KEY ] ) || ! isset( $this->groups[ $values[ static::GROUP_TYPE_KEY ] ] ) ) {
371
				continue;
372
			}
373
374
			$group = $this->get_group_by_name( $values[ static::GROUP_TYPE_KEY ] );
375
			$value_group = array( static::GROUP_TYPE_KEY => $values[ static::GROUP_TYPE_KEY ] );
376
			unset( $values[ static::GROUP_TYPE_KEY ] );
377
378
			$group_fields = $group->get_fields();
379
380
			// trim input values to those used by the field
381
			$group_field_names = array_flip( $group->get_field_names() );
382
			$values = array_intersect_key( $values, $group_field_names );
383
			
384
			foreach ( $group_fields as $field ) {
385
				$tmp_field = $this->get_clone_under_field_in_hierarchy( $field, $this, $input_group_index );
386
387
				$tmp_field->set_value_from_input( $values );
388
				if ( is_a( $tmp_field, get_class() ) ) {
389
					$value_group[ $tmp_field->get_base_name() ] = $tmp_field->get_value_tree();
390
				} else {
391
					$value_group[ $tmp_field->get_base_name() ] = array(
392
						'value_set' => $tmp_field->get_value_set()->get_set(),
393
					);
394
				}
395
			}
396
397
			$value_tree['value_set'][] = array(
398
				Value_Set::VALUE_PROPERTY => $group->get_name(),
399
			);
400
			$value_tree['groups'][] = $value_group;
401
			$input_group_index++;
402
		}
403
404
		$this->set_value( $value_tree['value_set'] );
405
		$this->set_value_tree( $value_tree );
406
	}
407
408
	/**
409
	 * Load all groups of fields and their data.
410
	 */
411
	public function load() {
412
		$value_tree = $this->get_datastore()->load( $this );
413
		$value = array();
414
		if ( isset( $value_tree['value_set'] ) ) {
415
			$value = $value_tree['value_set'];
416
		}
417
		$this->set_value( $value );
418
419
		if ( $this->get_value() ) {
420
			$this->set_value_tree( $value_tree );
421
		}
422
	}
423
424
	/**
425
	 * Save all contained groups of fields.
426
	 */
427
	public function save() {
428
		// Only delete root field values as nested field values should be deleted in a cascading manner by the datastore
429
		$hierarchy = $this->get_hierarchy();
430
		if ( empty( $hierarchy ) ) {
431
			$this->delete();
432
		}
433
		
434
		$this->get_datastore()->save( $this );
435
436
		$field_groups = $this->get_prefilled_field_groups( $this->get_value_tree() );
437
438
		foreach ( $field_groups as $group_index => $fields ) {
439
			foreach ( $fields as $field ) {
440
				if ( ! is_a( $field, __NAMESPACE__ . '\\Field' ) ) {
441
					continue;
442
				}
443
				$field->save();
444
			}
445
		}
446
	}
447
448
	/**
449
	 * Return the full value tree of all groups and their fields
450
	 *
451
	 * @return mixed
452
	 */
453
	public function get_value_tree() {
454
		return (array) $this->value_tree;
455
	}
456
457
	/**
458
	 * Set the full value tree of all groups and their fields
459
	 *
460
	 * @see  Internal Glossary in DEVELOPMENT.MD
461
	 */
462
	public function set_value_tree( $value_tree ) {
463
		$this->value_tree = $value_tree;
464
	}
465
466
	/**
467
	 * Return a differently formatted value for end-users
468
	 *
469
	 * @return mixed
470
	 */
471
	public function get_formatted_value() {
472
		$field_groups = $this->get_prefilled_field_groups( $this->get_value_tree() );
473
		
474
		$value = array();
475
		foreach ( $field_groups as $group_index => $field_group ) {
476
			$value[ $group_index ] = array();
477
			foreach ( $field_group as $key => $field ) {
478
				if ( is_a( $field, __NAMESPACE__ . '\\Field' ) ) {
479
					$value[ $group_index ][ $field->get_base_name() ] = $field->get_formatted_value(); 
480
				} else {
481
					$value[ $group_index ][ $key ] = $field;
482
				}
483
			}
484
		}
485
		return $value;
486
	}
487
488
	/**
489
	 * Returns an array that holds the field data, suitable for JSON representation.
490
	 * This data will be available in the Underscore template and the Backbone Model.
491
	 *
492
	 * @param bool $load  Should the value be loaded from the database or use the value from the current instance.
493
	 * @return array
494
	 */
495
	public function to_json( $load ) {
496
		$complex_data = parent::to_json( $load );
497
498
		$groups_data = array();
499
		foreach ( $this->groups as $group ) {
500
			$groups_data[] = $group->to_json( false );
501
		}
502
503
		$field_groups = $this->get_prefilled_field_groups( $this->get_value_tree() );
504
		$value_data = array();
505
		foreach ( $field_groups as $group_index => $fields ) {
506
			$group = $this->get_group_by_name( $fields[ static::GROUP_TYPE_KEY ] );
507
508
			$data = array(
509
				'name' => $group->get_name(),
510
				'label' => $group->get_label(),
511
				'group_id' => $group->get_group_id(),
512
				'fields' => array(),
513
			);
514
515
			foreach ( $fields as $field ) {
516
				if ( ! is_a( $field, __NAMESPACE__ . '\\Field' ) ) {
517
					continue;
518
				}
519
				$data['fields'][] = $field->to_json( false );
520
			}
521
522
			$value_data[] = $data;
523
		}
524
525
		$complex_data = array_merge( $complex_data, array(
526
			'layout' => $this->layout,
527
			'labels' => $this->labels,
528
			'min' => $this->get_min(),
529
			'max' => $this->get_max(),
530
			'multiple_groups' => count( $groups_data ) > 1,
531
			'groups' => $groups_data,
532
			'value' => $value_data,
533
			'collapsed' => $this->get_collapsed(),
534
		) );
535
		return $complex_data;
536
	}
537
538
	/**
539
	 * The main Underscore template.
540
	 */
541
	public function template() {
542
		?>
543
		<div class="carbon-subcontainer carbon-grid {{ multiple_groups ? 'multiple-groups' : '' }}">
544
			<div class="carbon-empty-row carbon-empty-row-visible">
545
				{{{ crbl10n.complex_no_rows.replace('%s', labels.plural_name) }}}
546
			</div>
547
548
			<div class="groups-wrapper layout-{{ layout }}">
549
				<# if (layout === '<?php echo static::LAYOUT_TABBED_HORIZONTAL ?>' || layout === '<?php echo static::LAYOUT_TABBED_VERTICAL ?>' ) { #>
550
					<div class="group-tabs-nav-holder">
551
						<ul class="group-tabs-nav"></ul>
552
553
						<div class="carbon-actions">
554
							<div class="carbon-button">
555
								<a href="#" class="button" data-group="{{{ multiple_groups ? '' : groups[0].name }}}">
556
									+
557
								</a>
558
559
								<# if (multiple_groups) { #>
560
									<ul>
561
										<# _.each(groups, function(group) { #>
562
											<li><a href="#" data-group="{{{ group.name }}}">{{{ group.label }}}</a></li>
563
										<# }); #>
564
									</ul>
565
								<# } #>
566
							</div>
567
						</div>
568
					</div><!-- /.group-tabs-nav-holder -->
569
				<# } #>
570
571
				<div class="carbon-groups-holder"></div>
572
				<div class="clear"></div>
573
			</div>
574
575
			<div class="carbon-actions">
576
				<div class="carbon-button">
577
					<a href="#" class="button" data-group="{{{ multiple_groups ? '' : groups[0].name }}}">
578
						{{{ crbl10n.complex_add_button.replace('%s', labels.singular_name) }}}
579
					</a>
580
581
					<# if (multiple_groups) { #>
582
						<ul>
583
							<# _.each(groups, function(group) { #>
584
								<li><a href="#" data-group="{{{ group.name }}}">{{{ group.label }}}</a></li>
585
							<# }); #>
586
						</ul>
587
					<# } #>
588
				</div>
589
			</div>
590
		</div>
591
		<?php
592
	}
593
594
	/**
595
	 * The Underscore template for the complex field group.
596
	 */
597
	public function template_group() {
598
		?>
599
		<div id="carbon-{{{ complex_name }}}-complex-container" class="carbon-row carbon-group-row" data-group-id="{{ id }}">
600
			<input type="hidden" name="{{{ complex_name + '[' + index + ']' }}}[_type]" value="{{ name }}" />
601
602
			<div class="carbon-drag-handle">
603
				<span class="group-number">{{{ order + 1 }}}</span><span class="group-name">{{{ label_template || label }}}</span>
604
			</div>
605
606
			<div class="carbon-group-actions carbon-group-actions-{{ layout }}">
607
				<a class="carbon-btn-duplicate dashicons-before dashicons-admin-page" href="#" title="<?php esc_attr_e( 'Clone', \Carbon_Fields\TEXT_DOMAIN ); ?>">
608
					<?php _e( 'Clone', \Carbon_Fields\TEXT_DOMAIN ); ?>
609
				</a>
610
611
				<a class="carbon-btn-remove dashicons-before dashicons-trash" href="#" title="<?php esc_attr_e( 'Remove', \Carbon_Fields\TEXT_DOMAIN ); ?>">
612
					<?php _e( 'Remove', \Carbon_Fields\TEXT_DOMAIN ); ?>
613
				</a>
614
615
				<a class="carbon-btn-collapse dashicons-before dashicons-arrow-up" href="#" title="<?php esc_attr_e( 'Collapse/Expand', \Carbon_Fields\TEXT_DOMAIN ); ?>">
616
					<?php _e( 'Collapse/Expand', \Carbon_Fields\TEXT_DOMAIN ); ?>
617
				</a>
618
			</div>
619
620
			<div class="fields-container">
621
				<# _.each(fields, function(field) { #>
622
					<div class="carbon-row carbon-subrow subrow-{{{ field.type }}} {{{ field.classes.join(' ') }}}">
623
						<label for="{{{ complex_id + '-' + field.id + '-' + index }}}">
624
							{{ field.label }}
625
626
							<# if (field.required) { #>
627
								 <span class="carbon-required">*</span>
628
							<# } #>
629
						</label>
630
631
						<div class="field-holder {{{ complex_id + '-' + field.id + '-' + index }}}"></div>
632
633
						<# if (field.help_text) { #>
634
							<em class="help-text">
635
								{{{ field.help_text }}}
636
							</em>
637
						<# } #>
638
639
						<em class="carbon-error"></em>
640
					</div>
641
				<# }) #>
642
			</div>
643
		</div>
644
		<?php
645
	}
646
647
	 /**
648
	 * The Underscore template for the group item tab.
649
	 */
650
	public function template_group_tab_item() {
651
		?>
652
		<li class="group-tab-item" data-group-id="{{ id }}">
653
			<a href="#">
654
				<span class="group-handle"></span>
655
656
				<# if (label_template || label) { #>
657
					<span class="group-name">{{{ label_template || label }}}</span>
658
				<# } #>
659
				<span class="group-number">{{{ order + 1 }}}</span>
660
				<span class="dashicons dashicons-warning carbon-complex-group-error-badge" ></span>
661
			</a>
662
		</li>
663
		<?php
664
	}
665
666
	/**
667
	 * Modify the layout of this field.
668
	 *
669
	 * @param string $layout
670
	 */
671
	public function set_layout( $layout ) {
672
		$available_layouts = array(
673
			static::LAYOUT_GRID,
674
			static::LAYOUT_TABBED_HORIZONTAL,
675
			static::LAYOUT_TABBED_VERTICAL,
676
		);
677
678
		if ( ! in_array( $layout,  $available_layouts ) ) {
679
			$error_message = 'Incorrect layout ``' . $layout . '" specified. ' .
680
				'Available layouts: ' . implode( ', ', $available_layouts );
681
682
			Incorrect_Syntax_Exception::raise( $error_message );
683
		}
684
685
		$this->layout = $layout;
686
687
		return $this;
688
	}
689
690
	/**
691
	 * Get the minimum number of entries.
692
	 *
693
	 * @return int $min
694
	 */
695
	public function get_min() {
696
		return $this->values_min;
697
	}
698
699
	/**
700
	 * Set the minimum number of entries.
701
	 *
702
	 * @param int $min
703
	 */
704
	public function set_min( $min ) {
705
		$this->values_min = intval( $min );
706
		return $this;
707
	}
708
709
	/**
710
	 * Get the maximum number of entries.
711
	 *
712
	 * @return int $max
713
	 */
714
	public function get_max() {
715
		return $this->values_max;
716
	}
717
718
	/**
719
	 * Set the maximum number of entries.
720
	 *
721
	 * @param int $max
722
	 */
723
	public function set_max( $max ) {
724
		$this->values_max = intval( $max );
725
		return $this;
726
	}
727
728
	/**
729
	 * Get collapsed state
730
	 *
731
	 * @return bool
732
	 */
733
	public function get_collapsed() {
734
		return $this->collapsed;
735
	}
736
737
	/**
738
	 * Change the groups initial collapse state.
739
	 * This state relates to the state of which the groups are rendered.
740
	 *
741
	 * @param bool $collapsed
742
	 */
743
	public function set_collapsed( $collapsed = true ) {
744
		$this->collapsed = $collapsed;
745
		return $this;
746
	}
747
}
748