Completed
Push — milestone/2.0 ( 3b05d3...830ade )
by
unknown
08:32
created

Complex_Field::get_prefilled_groups()   A

Complexity

Conditions 4
Paths 4

Size

Total Lines 20
Code Lines 13

Duplication

Lines 0
Ratio 0 %

Code Coverage

Tests 0
CRAP Score 20

Importance

Changes 0
Metric Value
cc 4
eloc 13
nc 4
nop 1
dl 0
loc 20
ccs 0
cts 15
cp 0
crap 20
rs 9.2
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_group_fields( $group_fields, $group_values, $group_index ) {
315
		$fields = array();
316
317
		foreach ( $group_fields as $field ) {
318
			$clone = $this->get_clone_under_field_in_hierarchy( $field, $this, $group_index );
319
			if ( isset( $group_values[ $clone->get_base_name() ] ) ) {
320
				$group_value = $group_values[ $clone->get_base_name() ];
321
				
322
				if ( isset( $group_value['value_set'] ) ) {
323
					$clone->set_value( $group_value['value_set'] );
324
				}
325
326
				if ( is_a( $clone, get_class() ) ) {
327
					$clone->set_value_tree( $group_value );
328
				}
329
			}
330
			$fields[] = $clone;
331
		}
332
333
		return $fields;
334
	}
335
336
	protected function get_prefilled_groups( $value_tree ) {
337
		$fields = array();
338
339
		if ( empty( $value_tree ) ) {
340
			return $fields;
341
		}
342
343
		foreach ( $value_tree['value_set'] as $group_index => $value ) {
344
			$group_name = $value[ Value_Set::VALUE_PROPERTY ];
345
			$group = $this->get_group_by_name( $group_name );
346
			$group_fields = $group->get_fields();
347
			$group_values = array();
348
			if ( isset( $value_tree['groups'][ $group_index ] ) ) {
349
				$group_values = $value_tree['groups'][ $group_index ];
350
			}
351
			$fields[ $group_index ] = array( static::GROUP_TYPE_KEY => $group->get_name() ) + $this->get_prefilled_group_fields( $group_fields, $group_values, $group_index );
352
		}
353
354
		return $fields;
355
	}
356
357
	/**
358
	 * Load the field value from an input array based on it's name.
359
	 *
360
	 * @param array $input Array of field names and values.
361
	 */
362
	public function set_value_from_input( $input ) {
363
		if ( ! isset( $input[ $this->get_name() ] ) ) {
364
			return;
365
		}
366
367
		$value_tree = array(
368
			'value_set' => array(),
369
			'groups' => array(),
370
		);
371
		$input_groups = $input[ $this->get_name() ];
372
		$input_group_index = 0;
373
		foreach ( $input_groups as $values ) {
374
			if ( ! isset( $values[ static::GROUP_TYPE_KEY ] ) || ! isset( $this->groups[ $values[ static::GROUP_TYPE_KEY ] ] ) ) {
375
				continue;
376
			}
377
378
			$group = $this->get_group_by_name( $values[ static::GROUP_TYPE_KEY ] );
379
			$group_fields = $group->get_fields();
380
			$group_field_names = array_flip( $group->get_field_names() );
381
			
382
			$value_group = array( static::GROUP_TYPE_KEY => $values[ static::GROUP_TYPE_KEY ] );
383
			unset( $values[ static::GROUP_TYPE_KEY ] );
384
385
			// trim input values to those used by the field
386
			$values = array_intersect_key( $values, $group_field_names );
387
			
388
			foreach ( $group_fields as $field ) {
389
				$tmp_field = $this->get_clone_under_field_in_hierarchy( $field, $this, $input_group_index );
390
391
				$tmp_field->set_value_from_input( $values );
392
				if ( is_a( $tmp_field, get_class() ) ) {
393
					$value_group[ $tmp_field->get_base_name() ] = $tmp_field->get_value_tree();
394
				} else {
395
					$value_group[ $tmp_field->get_base_name() ] = array(
396
						'value_set' => $tmp_field->get_full_value(),
397
					);
398
				}
399
			}
400
401
			$value_tree['value_set'][] = array(
402
				Value_Set::VALUE_PROPERTY => $group->get_name(),
403
			);
404
			$value_tree['groups'][] = $value_group;
405
			$input_group_index++;
406
		}
407
408
		$this->set_value( $value_tree['value_set'] );
409
		$this->set_value_tree( $value_tree );
410
	}
411
412
	/**
413
	 * Load all groups of fields and their data.
414
	 */
415
	public function load() {
416
		$value_tree = $this->get_datastore()->load( $this );
417
		$value = array();
418
		if ( isset( $value_tree['value_set'] ) ) {
419
			$value = $value_tree['value_set'];
420
		}
421
		$this->set_value( $value );
422
423
		if ( $this->get_value() ) {
424
			$this->set_value_tree( $value_tree );
425
		}
426
	}
427
428
	/**
429
	 * Save all contained groups of fields.
430
	 */
431
	public function save() {
432
		// Only delete root field values as nested field values should be deleted in a cascading manner by the datastore
433
		$hierarchy = $this->get_hierarchy();
434
		if ( empty( $hierarchy ) ) {
435
			$this->delete();
436
		}
437
		
438
		$this->get_datastore()->save( $this );
439
440
		$field_groups = $this->get_prefilled_groups( $this->get_value_tree() );
441
442
		foreach ( $field_groups as $group_index => $fields ) {
443
			foreach ( $fields as $field ) {
444
				if ( ! is_a( $field, __NAMESPACE__ . '\\Field' ) ) {
445
					continue;
446
				}
447
				$field->save();
448
			}
449
		}
450
	}
451
452
	/**
453
	 * Return the full value tree of all groups and their fields
454
	 *
455
	 * @return mixed
456
	 */
457
	public function get_value_tree() {
458
		return (array) $this->value_tree;
459
	}
460
461
	/**
462
	 * Set the full value tree of all groups and their fields
463
	 *
464
	 * @see  Internal Glossary in DEVELOPMENT.MD
465
	 */
466
	public function set_value_tree( $value_tree ) {
467
		$this->value_tree = $value_tree;
468
	}
469
470
	/**
471
	 * Return a differently formatted value for end-users
472
	 *
473
	 * @return mixed
474
	 */
475
	public function get_formatted_value() {
476
		$field_groups = $this->get_prefilled_groups( $this->get_value_tree() );
477
		
478
		$value = array();
479
		foreach ( $field_groups as $group_index => $field_group ) {
480
			$value[ $group_index ] = array();
481
			foreach ( $field_group as $key => $field ) {
482
				if ( is_a( $field, __NAMESPACE__ . '\\Field' ) ) {
483
					$value[ $group_index ][ $field->get_base_name() ] = $field->get_formatted_value(); 
484
				} else {
485
					$value[ $group_index ][ $key ] = $field;
486
				}
487
			}
488
		}
489
		return $value;
490
	}
491
492
	/**
493
	 * Returns an array that holds the field data, suitable for JSON representation.
494
	 * This data will be available in the Underscore template and the Backbone Model.
495
	 *
496
	 * @param bool $load  Should the value be loaded from the database or use the value from the current instance.
497
	 * @return array
498
	 */
499
	public function to_json( $load ) {
500
		$complex_data = parent::to_json( $load );
501
502
		$groups_data = array();
503
		foreach ( $this->groups as $group ) {
504
			$groups_data[] = $group->to_json( false );
505
		}
506
507
		$field_groups = $this->get_prefilled_groups( $this->get_value_tree() );
508
		$value_data = array();
509
		foreach ( $field_groups as $group_index => $fields ) {
510
			$group = $this->get_group_by_name( $fields[ static::GROUP_TYPE_KEY ] );
511
512
			$data = array(
513
				'name' => $group->get_name(),
514
				'label' => $group->get_label(),
515
				'group_id' => $group->get_group_id(),
516
				'fields' => array(),
517
			);
518
519
			foreach ( $fields as $field ) {
520
				if ( ! is_a( $field, __NAMESPACE__ . '\\Field' ) ) {
521
					continue;
522
				}
523
				$data['fields'][] = $field->to_json( false );
524
			}
525
526
			$value_data[] = $data;
527
		}
528
529
		$complex_data = array_merge( $complex_data, array(
530
			'layout' => $this->layout,
531
			'labels' => $this->labels,
532
			'min' => $this->get_min(),
533
			'max' => $this->get_max(),
534
			'multiple_groups' => count( $groups_data ) > 1,
535
			'groups' => $groups_data,
536
			'value' => $value_data,
537
			'collapsed' => $this->get_collapsed(),
538
		) );
539
		return $complex_data;
540
	}
541
542
	/**
543
	 * The main Underscore template.
544
	 */
545
	public function template() {
546
		?>
547
		<div class="carbon-subcontainer carbon-grid {{ multiple_groups ? 'multiple-groups' : '' }}">
548
			<div class="carbon-empty-row carbon-empty-row-visible">
549
				{{{ crbl10n.complex_no_rows.replace('%s', labels.plural_name) }}}
550
			</div>
551
552
			<div class="groups-wrapper layout-{{ layout }}">
553
				<# if (layout === '<?php echo static::LAYOUT_TABBED_HORIZONTAL ?>' || layout === '<?php echo static::LAYOUT_TABBED_VERTICAL ?>' ) { #>
554
					<div class="group-tabs-nav-holder">
555
						<ul class="group-tabs-nav"></ul>
556
557
						<div class="carbon-actions">
558
							<div class="carbon-button">
559
								<a href="#" class="button" data-group="{{{ multiple_groups ? '' : groups[0].name }}}">
560
									+
561
								</a>
562
563
								<# if (multiple_groups) { #>
564
									<ul>
565
										<# _.each(groups, function(group) { #>
566
											<li><a href="#" data-group="{{{ group.name }}}">{{{ group.label }}}</a></li>
567
										<# }); #>
568
									</ul>
569
								<# } #>
570
							</div>
571
						</div>
572
					</div><!-- /.group-tabs-nav-holder -->
573
				<# } #>
574
575
				<div class="carbon-groups-holder"></div>
576
				<div class="clear"></div>
577
			</div>
578
579
			<div class="carbon-actions">
580
				<div class="carbon-button">
581
					<a href="#" class="button" data-group="{{{ multiple_groups ? '' : groups[0].name }}}">
582
						{{{ crbl10n.complex_add_button.replace('%s', labels.singular_name) }}}
583
					</a>
584
585
					<# if (multiple_groups) { #>
586
						<ul>
587
							<# _.each(groups, function(group) { #>
588
								<li><a href="#" data-group="{{{ group.name }}}">{{{ group.label }}}</a></li>
589
							<# }); #>
590
						</ul>
591
					<# } #>
592
				</div>
593
			</div>
594
		</div>
595
		<?php
596
	}
597
598
	/**
599
	 * The Underscore template for the complex field group.
600
	 */
601
	public function template_group() {
602
		?>
603
		<div id="carbon-{{{ complex_name }}}-complex-container" class="carbon-row carbon-group-row" data-group-id="{{ id }}">
604
			<input type="hidden" name="{{{ complex_name + '[' + index + ']' }}}[_type]" value="{{ name }}" />
605
606
			<div class="carbon-drag-handle">
607
				<span class="group-number">{{{ order + 1 }}}</span><span class="group-name">{{{ label_template || label }}}</span>
608
			</div>
609
610
			<div class="carbon-group-actions carbon-group-actions-{{ layout }}">
611
				<a class="carbon-btn-duplicate dashicons-before dashicons-admin-page" href="#" title="<?php esc_attr_e( 'Clone', \Carbon_Fields\TEXT_DOMAIN ); ?>">
612
					<?php _e( 'Clone', \Carbon_Fields\TEXT_DOMAIN ); ?>
613
				</a>
614
615
				<a class="carbon-btn-remove dashicons-before dashicons-trash" href="#" title="<?php esc_attr_e( 'Remove', \Carbon_Fields\TEXT_DOMAIN ); ?>">
616
					<?php _e( 'Remove', \Carbon_Fields\TEXT_DOMAIN ); ?>
617
				</a>
618
619
				<a class="carbon-btn-collapse dashicons-before dashicons-arrow-up" href="#" title="<?php esc_attr_e( 'Collapse/Expand', \Carbon_Fields\TEXT_DOMAIN ); ?>">
620
					<?php _e( 'Collapse/Expand', \Carbon_Fields\TEXT_DOMAIN ); ?>
621
				</a>
622
			</div>
623
624
			<div class="fields-container">
625
				<# _.each(fields, function(field) { #>
626
					<div class="carbon-row carbon-subrow subrow-{{{ field.type }}} {{{ field.classes.join(' ') }}}">
627
						<label for="{{{ complex_id + '-' + field.id + '-' + index }}}">
628
							{{ field.label }}
629
630
							<# if (field.required) { #>
631
								 <span class="carbon-required">*</span>
632
							<# } #>
633
						</label>
634
635
						<div class="field-holder {{{ complex_id + '-' + field.id + '-' + index }}}"></div>
636
637
						<# if (field.help_text) { #>
638
							<em class="help-text">
639
								{{{ field.help_text }}}
640
							</em>
641
						<# } #>
642
643
						<em class="carbon-error"></em>
644
					</div>
645
				<# }) #>
646
			</div>
647
		</div>
648
		<?php
649
	}
650
651
	 /**
652
	 * The Underscore template for the group item tab.
653
	 */
654
	public function template_group_tab_item() {
655
		?>
656
		<li class="group-tab-item" data-group-id="{{ id }}">
657
			<a href="#">
658
				<span class="group-handle"></span>
659
660
				<# if (label_template || label) { #>
661
					<span class="group-name">{{{ label_template || label }}}</span>
662
				<# } #>
663
				<span class="group-number">{{{ order + 1 }}}</span>
664
				<span class="dashicons dashicons-warning carbon-complex-group-error-badge" ></span>
665
			</a>
666
		</li>
667
		<?php
668
	}
669
670
	/**
671
	 * Modify the layout of this field.
672
	 *
673
	 * @param string $layout
674
	 */
675
	public function set_layout( $layout ) {
676
		$available_layouts = array(
677
			static::LAYOUT_GRID,
678
			static::LAYOUT_TABBED_HORIZONTAL,
679
			static::LAYOUT_TABBED_VERTICAL,
680
		);
681
682
		if ( ! in_array( $layout,  $available_layouts ) ) {
683
			$error_message = 'Incorrect layout ``' . $layout . '" specified. ' .
684
				'Available layouts: ' . implode( ', ', $available_layouts );
685
686
			Incorrect_Syntax_Exception::raise( $error_message );
687
		}
688
689
		$this->layout = $layout;
690
691
		return $this;
692
	}
693
694
	/**
695
	 * Get the minimum number of entries.
696
	 *
697
	 * @return int $min
698
	 */
699
	public function get_min() {
700
		return $this->values_min;
701
	}
702
703
	/**
704
	 * Set the minimum number of entries.
705
	 *
706
	 * @param int $min
707
	 */
708
	public function set_min( $min ) {
709
		$this->values_min = intval( $min );
710
		return $this;
711
	}
712
713
	/**
714
	 * Get the maximum number of entries.
715
	 *
716
	 * @return int $max
717
	 */
718
	public function get_max() {
719
		return $this->values_max;
720
	}
721
722
	/**
723
	 * Set the maximum number of entries.
724
	 *
725
	 * @param int $max
726
	 */
727
	public function set_max( $max ) {
728
		$this->values_max = intval( $max );
729
		return $this;
730
	}
731
732
	/**
733
	 * Get collapsed state
734
	 *
735
	 * @return bool
736
	 */
737
	public function get_collapsed() {
738
		return $this->collapsed;
739
	}
740
741
	/**
742
	 * Change the groups initial collapse state.
743
	 * This state relates to the state of which the groups are rendered.
744
	 *
745
	 * @param bool $collapsed
746
	 */
747
	public function set_collapsed( $collapsed = true ) {
748
		$this->collapsed = $collapsed;
749
		return $this;
750
	}
751
}
752