Completed
Pull Request — master (#187)
by
unknown
02:17
created

Complex_Field::set_value_from_input()   C

Complexity

Conditions 12
Paths 18

Size

Total Lines 56
Code Lines 36

Duplication

Lines 3
Ratio 5.36 %

Importance

Changes 2
Bugs 0 Features 0
Metric Value
cc 12
eloc 36
c 2
b 0
f 0
nc 18
nop 1
dl 3
loc 56
rs 6.7092

How to fix   Long Method    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\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\Exception\Incorrect_Syntax_Exception;
10
11
/**
12
 * Complex field class.
13
 * Allows nested repeaters with multiple field groups to be created.
14
 */
15
class Complex_Field extends Field {
16
	const LAYOUT_GRID = 'grid'; // default
17
	const LAYOUT_LIST = 'list'; // deprecated
18
	const LAYOUT_TABBED = 'tabbed'; // deprecated
19
	const LAYOUT_TABBED_HORIZONTAL = 'tabbed-horizontal';
20
	const LAYOUT_TABBED_VERTICAL = 'tabbed-vertical';
21
22
	protected $fields = array();
23
	protected $values = array();
24
	protected $groups = array();
25
26
	protected $layout = self::LAYOUT_GRID;
27
	protected $values_min = -1;
28
	protected $values_max = -1;
29
	protected $collapsed = false;
30
31
	public $labels = array(
32
		'singular_name' => 'Entry',
33
		'plural_name' => 'Entries',
34
	);
35
36
	/**
37
	 * Initialization tasks.
38
	 */
39 View Code Duplication
	public function init() {
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...
40
		$this->labels = array(
41
			'singular_name' => __( 'Entry', 'carbon-fields' ),
42
			'plural_name' => __( 'Entries', 'carbon-fields' ),
43
		);
44
45
		// Include the complex group Underscore templates
46
		$this->add_template( 'Complex-Group', array( $this, 'template_group' ) );
47
		$this->add_template( 'Complex-Group-Tab-Item', array( $this, 'template_group_tab_item' ) );
48
49
		parent::init();
50
	}
51
52
	/**
53
	 * Add a set/group of fields.
54
	 *
55
	 * @return $this
56
	 */
57 View Code Duplication
	public function add_fields() {
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...
58
		$argv = func_get_args();
59
		$argc = count( $argv );
60
61
		if ( $argc == 1 ) {
62
			$fields = $argv[0];
63
			$name = '';
64
			$label = null;
65
		} else if ( $argc == 2 ) {
66
			if ( is_array( $argv[0] ) ) {
67
				list( $fields, $name ) = $argv;
68
			} else {
69
				list( $name, $fields ) = $argv;
70
			}
71
			$label = null;
72
		} else if ( $argc == 3 ) {
73
			if ( is_array( $argv[0] ) ) {
74
				list( $fields, $name, $label ) = $argv;
75
			} else {
76
				list( $name, $label, $fields ) = $argv;
77
			}
78
		}
79
80
		if ( array_key_exists( '_' . $name, $this->groups ) ) {
81
			Incorrect_Syntax_Exception::raise( 'Group with name "' . $name . '" in Complex Field "' . $this->get_label() . '" already exists.' );
0 ignored issues
show
Bug introduced by
The variable $name does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
82
		}
83
84
		$group = new Group_Field($name, $label, $fields);
0 ignored issues
show
Bug introduced by
The variable $label does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Bug introduced by
The variable $fields does not seem to be defined for all execution paths leading up to this point.

If you define a variable conditionally, it can happen that it is not defined for all execution paths.

Let’s take a look at an example:

function myFunction($a) {
    switch ($a) {
        case 'foo':
            $x = 1;
            break;

        case 'bar':
            $x = 2;
            break;
    }

    // $x is potentially undefined here.
    echo $x;
}

In the above example, the variable $x is defined if you pass “foo” or “bar” as argument for $a. However, since the switch statement has no default case statement, if you pass any other value, the variable $x would be undefined.

Available Fixes

  1. Check for existence of the variable explicitly:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        if (isset($x)) { // Make sure it's always set.
            echo $x;
        }
    }
    
  2. Define a default value for the variable:

    function myFunction($a) {
        $x = ''; // Set a default which gets overridden for certain paths.
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
        }
    
        echo $x;
    }
    
  3. Add a value for the missing path:

    function myFunction($a) {
        switch ($a) {
            case 'foo':
                $x = 1;
                break;
    
            case 'bar':
                $x = 2;
                break;
    
            // We add support for the missing case.
            default:
                $x = '';
                break;
        }
    
        echo $x;
    }
    
Loading history...
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
85
86
		$this->groups[ $group->get_name() ] = $group;
87
88
		return $this;
89
	}
90
91
	/**
92
	 * Set the group label Underscore template.
93
	 *
94
	 * @param  string|callable $template
95
	 * @return $this
96
	 */
97 View Code Duplication
	public function set_header_template( $template ) {
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...
98
		if ( count($this->groups) === 0 ) {
0 ignored issues
show
Coding Style introduced by
Expected 1 spaces after opening bracket; 0 found
Loading history...
Coding Style introduced by
Expected 1 spaces before closing bracket; 0 found
Loading history...
99
			Incorrect_Syntax_Exception::raise( "Can't set group label template. There are no present groups for Complex Field " . $this->get_label() . "." );
0 ignored issues
show
Coding Style Comprehensibility introduced by
The string literal . does not require double quotes, as per coding-style, please use single quotes.

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

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

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

<?php

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

print $doubleQuoted;

will print an indented: Single is Value

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

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

Loading history...
100
		}
101
102
		$template = is_callable( $template ) ? call_user_func( $template ) : $template;
103
104
		// Assign the template to the group that was added last
105
		$values = array_values( $this->groups );
106
		$group = end( $values );
107
		$group->set_label_template( $template );
108
109
		// Include the group label Underscore template
110
		$this->add_template( $group->get_group_id(), array( $group, 'template_label' ) );
111
112
		$this->groups[ $group->get_name() ] = $group;
113
114
		return $this;
115
	}
116
117
	/**
118
	 * Retrieve all groups of fields.
119
	 *
120
	 * @return array $fields
121
	 */
122 View Code Duplication
	public function get_fields() {
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...
123
		$fields = array();
124
125
		foreach ( $this->groups as $group ) {
126
			$group_fields = $group->get_fields();
127
128
			$fields = array_merge( $fields, $group_fields );
129
		}
130
131
		return $fields;
132
	}
133
134
	/**
135
	 * Set the field labels.
136
	 * Currently supported values:
137
	 *  - singular_name - the singular entry label
138
	 *  - plural_name - the plural entries label
139
	 *
140
	 * @param  array $labels Labels
141
	 */
142
	public function setup_labels( $labels ) {
143
		$this->labels = array_merge( $this->labels, $labels );
144
		return $this;
145
	}
146
147
	/**
148
	 * Set the datastore of this field.
149
	 *
150
	 * @param Datastore_Interface $store
151
	 */
152
	public function set_datastore( Datastore_Interface $store ) {
153
		$this->store = $store;
154
155
		foreach ( $this->groups as $group ) {
156
			$group->set_datastore( $this->store );
157
		}
158
	}
159
160
	/**
161
	 * Load the field value from an input array based on it's name.
162
	 *
163
	 * @param array $input (optional) Array of field names and values. Defaults to $_POST
164
	 **/
165
	public function set_value_from_input( $input = null ) {
166
		$this->values = array();
167
168
		if ( is_null( $input ) ) {
169
			$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...
170
		}
171
172
		if ( ! isset( $input[ $this->get_name() ] ) ) {
173
			return;
174
		}
175
176
		$input_groups = $input[ $this->get_name() ];
177
		$index = 0;
178
0 ignored issues
show
Coding Style introduced by
Functions must not contain multiple empty lines in a row; found 2 empty lines
Loading history...
179
180
		foreach ( $input_groups as $values ) {
181
			$value_group = array();
182 View Code Duplication
			if ( ! isset( $values['group'] ) || ! isset( $this->groups[ $values['group'] ] ) ) {
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...
183
				continue;
184
			}
185
186
			$group = $this->groups[ $values['group'] ];
187
			unset( $values['group'] );
188
189
			$group_fields = $group->get_fields();
190
191
			// trim input values to those used by the field
192
			$group_field_names = array_flip( $group->get_field_names() );
193
			$values = array_intersect_key( $values, $group_field_names );
194
195
			foreach ( $group_fields as $field ) {
196
				// set value from the group
197
				$tmp_field = clone $field;
198
				if ( is_a( $tmp_field, __NAMESPACE__ . '\\Complex_Field' ) ) {
199
					if ( ! isset( $values[ $tmp_field->get_name() ] ) ) {
200
						continue; // bail if the complex field is empty
201
					}
202
203
					$new_name = $this->get_name() . $group->get_name() . '-' . $field->get_name() . '_' . $index;
204
					$new_values = array( $new_name => $values[ $tmp_field->get_name() ] );
205
206
					$tmp_field->set_name( $new_name );
207
					$tmp_field->set_value_from_input( $new_values );
208
				} else {
209
					$tmp_field->set_value_from_input( $values );
210
				}
211
212
				// update name to group name
213
				$tmp_field->set_name( $this->get_name() . $group->get_name() . '-' . $field->get_name() . '_' . $index );
214
				$value_group[] = $tmp_field;
215
			}
216
217
			$this->values[] = $value_group;
218
			$index++;
219
		}
220
	}
221
222
	/**
223
	 * Load all groups of fields and their data.
224
	 */
225
	public function load() {
226
		// load existing groups
227
		$this->load_values();
228
	}
229
230
	/**
231
	 * Save all contained groups of fields.
232
	 */
233
	public function save() {
234
		$this->delete();
235
236
		foreach ( $this->values as $value ) {
237
			foreach ( $value as $field ) {
238
				$field->save();
239
			}
240
		}
241
	}
242
243
	/**
244
	 * Delete the values of all contained fields.
245
	 */
246
	public function delete() {
247
		return $this->store->delete_values( $this );
248
	}
249
250
	/**
251
	 * Load and parse the field data.
252
	 */
253
	public function load_values() {
254
		return $this->load_values_from_db();
255
	}
256
257
	/**
258
	 * Load and parse the field data from the database.
259
	 */
260
	public function load_values_from_db() {
261
		$this->values = array();
262
263
		$group_rows = $this->store->load_values( $this );
264
265
		return $this->process_loaded_values( $group_rows );
266
	}
267
268
	/**
269
	 * Load and parse a raw set of field data.
270
	 *
271
	 * @param  array $values Raw data entries
272
	 * @return array 		 Processed data entries
273
	 */
274 View Code Duplication
	public function load_values_from_array( $values ) {
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...
275
		$this->values = array();
276
277
		$group_rows = array();
278
279
		$meta_key = $this->get_name();
280
281
		foreach ( $values as $key => $value ) {
282
			if ( strpos( $key, $meta_key ) !== 0 ) {
283
				continue;
284
			}
285
286
			$group_rows[] = array(
287
				'field_key' => preg_replace( '~^(' . preg_quote( $this->name, '~' ) . ')_\d+_~', '$1_', $key ),
288
				'field_value' => $value,
289
			);
290
		}
291
292
		return $this->process_loaded_values( $group_rows );
293
	}
294
295
	/**
296
	 * Parse groups of raw field data into the actual field hierarchy.
297
	 *
298
	 * @param  array $group_rows Group rows
299
	 */
300 View Code Duplication
	public function process_loaded_values( $group_rows ) {
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...
301
		$input_groups = array();
302
303
		// Set default values
304
		$field_names = array();
305
		foreach ( $this->groups as $group ) {
306
			$group_fields = $group->get_fields();
307
			foreach ( $group_fields as $field ) {
308
				$field_names[] = $field->get_name();
309
				$field->set_value( $field->get_default_value() );
310
			}
311
		}
312
313
		if ( empty( $group_rows ) ) {
314
			return;
315
		}
316
317
		// load and parse values and group type
318
		foreach ( $group_rows as $row ) {
319
			if ( ! preg_match( Helper::get_complex_field_regex( $this->name, array_keys( $this->groups ), $field_names ), $row['field_key'], $field_name ) ) {
320
				continue;
321
			}
322
323
			$row['field_value'] = maybe_unserialize( $row['field_value'] );
324
			$input_groups[ $field_name['index'] ]['type'] = $field_name['group'];
325
326
			if ( ! empty( $field_name['trailing'] ) ) {
327
				$input_groups[ $field_name['index'] ][ $field_name['key'] . '_' . $field_name['sub'] . '-' . $field_name['trailing'] ] = $row['field_value'];
328
			} else if ( ! empty( $field_name['sub'] ) ) {
329
				$input_groups[ $field_name['index'] ][ $field_name['key'] ][ $field_name['sub'] ] = $row['field_value'];
330
			} else {
331
				$input_groups[ $field_name['index'] ][ $field_name['key'] ] = $row['field_value'];
332
			}
333
		}
334
335
		// create groups list with loaded fields
336
		ksort( $input_groups );
337
338
		foreach ( $input_groups as $index => $values ) {
339
			$value_group = array( 'type' => $values['type'] );
340
			$group_fields = $this->groups[ $values['type'] ]->get_fields();
341
			unset( $values['type'] );
342
343
			foreach ( $group_fields as $field ) {
344
				// set value from the group
345
				$tmp_field = clone $field;
346
347
				if ( is_a( $field, __NAMESPACE__ . '\\Complex_Field' ) ) {
348
					$tmp_field->load_values_from_array( $values );
349
				} else {
350
					$tmp_field->set_value_from_input( $values );
351
				}
352
353
				$value_group[] = $tmp_field;
354
			}
355
356
			$this->values[] = $value_group;
357
		}
358
	}
359
360
	/**
361
	 * Retrieve the field values.
362
	 * @return array
363
	 */
364
	public function get_values() {
365
		return $this->values;
366
	}
367
368
	/**
369
	 * Generate and set the field prefix.
370
	 * @param string $prefix
371
	 */
372
	public function set_prefix( $prefix ) {
373
		parent::set_prefix( $prefix );
374
375
		foreach ( $this->groups as $group ) {
376
			$group->set_prefix( $prefix );
377
		}
378
	}
379
380
	/**
381
	 * Returns an array that holds the field data, suitable for JSON representation.
382
	 * This data will be available in the Underscore template and the Backbone Model.
383
	 *
384
	 * @param bool $load  Should the value be loaded from the database or use the value from the current instance.
385
	 * @return array
386
	 */
387 View Code Duplication
	public function to_json( $load ) {
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...
388
		$complex_data = parent::to_json( $load );
389
390
		$groups_data = array();
391
		$values_data = array();
392
393
		foreach ( $this->groups as $group ) {
394
			$groups_data[] = $group->to_json( false );
395
		}
396
397
		foreach ( $this->values as $fields ) {
398
			$group = $this->get_group_by_name( $fields['type'] );
399
			unset( $fields['type'] );
400
401
			$data = array(
402
				'name' => $group->get_name(),
403
				'label' => $group->get_label(),
404
				'group_id' => $group->get_group_id(),
405
				'fields' => array(),
406
			);
407
408
			foreach ( $fields as $index => $field ) {
409
				$data['fields'][] = $field->to_json( false );
410
			}
411
412
			$values_data[] = $data;
413
		}
414
415
		$complex_data = array_merge( $complex_data, array(
416
			'layout' => $this->layout,
417
			'labels' => $this->labels,
418
			'min' => $this->get_min(),
419
			'max' => $this->get_max(),
420
			'multiple_groups' => count( $groups_data ) > 1,
421
			'groups' => $groups_data,
422
			'value' => $values_data,
423
			'collapsed' => $this->collapsed,
424
		) );
425
426
		return $complex_data;
427
	}
428
429
	/**
430
	 * The main Underscore template.
431
	 */
432
	public function template() {
433
		?>
434
		<div class="carbon-subcontainer carbon-grid {{ multiple_groups ? 'multiple-groups' : '' }}">
435
			<div class="carbon-empty-row carbon-empty-row-visible">
436
				{{{ crbl10n.complex_no_rows.replace('%s', labels.plural_name) }}}
437
			</div>
438
439
			<div class="groups-wrapper layout-{{ layout }}">
440
				<# if (layout === '<?php echo self::LAYOUT_TABBED_HORIZONTAL ?>' || layout === '<?php echo self::LAYOUT_TABBED_VERTICAL ?>' ) { #>
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not 'self'
Loading history...
441
					<div class="group-tabs-nav-holder">
442
						<ul class="group-tabs-nav"></ul>
443
444
						<div class="carbon-actions">
445
							<div class="carbon-button">
446
								<a href="#" class="button" data-group="{{{ multiple_groups ? '' : groups[0].name }}}">
447
									+
448
								</a>
449
450
								<# if (multiple_groups) { #>
451
									<ul>
452
										<# _.each(groups, function(group) { #>
453
											<li><a href="#" data-group="{{{ group.name }}}">{{{ group.label }}}</a></li>
454
										<# }); #>
455
									</ul>
456
								<# } #>
457
							</div>
458
						</div>
459
					</div><!-- /.group-tabs-nav-holder -->
460
				<# } #>
461
462
				<div class="carbon-groups-holder"></div>
463
				<div class="clear"></div>
464
			</div>
465
466
			<div class="carbon-actions">
467
				<div class="carbon-button">
468
					<a href="#" class="button" data-group="{{{ multiple_groups ? '' : groups[0].name }}}">
469
						{{{ crbl10n.complex_add_button.replace('%s', labels.singular_name) }}}
470
					</a>
471
472
					<# if (multiple_groups) { #>
473
						<ul>
474
							<# _.each(groups, function(group) { #>
475
								<li><a href="#" data-group="{{{ group.name }}}">{{{ group.label }}}</a></li>
476
							<# }); #>
477
						</ul>
478
					<# } #>
479
				</div>
480
			</div>
481
		</div>
482
		<?php
483
	}
484
485
	/**
486
	 * The Underscore template for the complex field group.
487
	 */
488 View Code Duplication
	public function template_group() {
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...
489
		?>
490
		<div id="carbon-{{{ complex_name }}}-complex-container" class="carbon-row carbon-group-row" data-group-id="{{ id }}">
491
			<input type="hidden" name="{{{ complex_name + '[' + index + ']' }}}[group]" value="{{ name }}" />
492
493
			<div class="carbon-drag-handle">
494
				<span class="group-number">{{{ order + 1 }}}</span><span class="group-name">{{{ label_template || label }}}</span>
495
			</div>
496
497
			<div class="carbon-group-actions carbon-group-actions-{{ layout }}">
498
				<a class="carbon-btn-duplicate dashicons-before dashicons-admin-page" href="#" title="<?php esc_attr_e( 'Clone', 'carbon_fields' ); ?>">
499
					<?php _e( 'Clone', 'carbon_fields' ); ?>
500
				</a>
501
502
				<a class="carbon-btn-remove dashicons-before dashicons-trash" href="#" title="<?php esc_attr_e( 'Remove', 'carbon_fields' ); ?>">
503
					<?php _e( 'Remove', 'carbon_fields' ); ?>
504
				</a>
505
506
				<a class="carbon-btn-collapse dashicons-before dashicons-arrow-up" href="#" title="<?php esc_attr_e( 'Collapse/Expand', 'carbon_fields' ); ?>">
507
					<?php _e( 'Collapse/Expand', 'carbon_fields' ); ?>
508
				</a>
509
			</div>
510
511
			<div class="fields-container">
512
				<# _.each(fields, function(field) { #>
513
					<div class="carbon-row carbon-subrow subrow-{{{ field.type }}} {{{ field.classes.join(' ') }}}">
514
						<label for="{{{ complex_id + '-' + field.id + '-' + index }}}">
515
							{{ field.label }}
516
517
							<# if (field.required) { #>
518
								 <span class="carbon-required">*</span>
519
							<# } #>
520
						</label>
521
522
						<div class="field-holder {{{ complex_id + '-' + field.id + '-' + index }}}"></div>
523
524
						<# if (field.help_text) { #>
525
							<em class="help-text">
526
								{{{ field.help_text }}}
527
							</em>
528
						<# } #>
529
530
						<em class="carbon-error"></em>
531
					</div>
532
				<# }) #>
533
			</div>
534
		</div>
535
		<?php
536
	}
537
538
	 /**
539
	 * The Underscore template for the group item tab.
540
	 */
541
	public function template_group_tab_item() {
542
		?>
543
		<li class="group-tab-item" data-group-id="{{ id }}">
544
			<a href="#">
545
				<span class="group-handle"></span>
546
547
				<# if (label_template || label) { #>
548
					<span class="group-name">{{{ label_template || label }}}</span>
549
				<# } #>
550
				<span class="group-number">{{{ order + 1 }}}</span>
551
				<span class="dashicons dashicons-warning carbon-complex-group-error-badge" ></span>
552
			</a>
553
		</li>
554
		<?php
555
	}
556
557
	/**
558
	 * Modify the layout of this field.
559
	 *
560
	 * @param string $layout
561
	 */
562 View Code Duplication
	public function set_layout( $layout ) {
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...
563
		$available_layouts = array(
564
			self::LAYOUT_GRID,
565
			self::LAYOUT_TABBED_HORIZONTAL,
566
			self::LAYOUT_TABBED_VERTICAL,
567
			self::LAYOUT_LIST,
568
		);
569
570
		if ( $layout === self::LAYOUT_TABBED ) {
571
			// The library used to provide just one kind of tabs -- horizontal ones. Later vertical tabs were added.
572
			// So the "tabbed" name was renamed to "tabbed-horizontal" and "tabbed-vertical" layout was introduced.
573
			_doing_it_wrong( __METHOD__, sprintf( __( 'Complex field "%1$s" layout is deprecated, please use "%2$s" or "%3$s" instead.', 'carbon_fields' ), self::LAYOUT_TABBED, self::LAYOUT_TABBED_HORIZONTAL, self::LAYOUT_TABBED_VERTICAL ), null );
574
575
			$layout = self::LAYOUT_TABBED_HORIZONTAL;
576
		}
577
578
		if ( ! in_array( $layout,  $available_layouts ) ) {
579
			$error_message = 'Incorrect layout ``' . $layout . '" specified. ' .
580
				'Available layouts: ' . implode( ', ', $available_layouts );
581
582
			Incorrect_Syntax_Exception::raise( $error_message );
583
		}
584
585
		if ( $layout === self::LAYOUT_LIST ) {
586
			_doing_it_wrong( __METHOD__, __( 'Complex field <code>' . self::LAYOUT_LIST . '</code> layout is deprecated, please use <code>set_width()</code> instead.', 'carbon_fields' ), null );
0 ignored issues
show
introduced by
Expected next thing to be a escaping function, not 'self'
Loading history...
587
		}
588
589
		$this->layout = $layout;
590
591
		return $this;
592
	}
593
594
	/**
595
	 * Set the minimum number of entries.
596
	 *
597
	 * @param int $min
598
	 */
599
	public function set_min( $min ) {
600
		$this->values_min = intval( $min );
601
		return $this;
602
	}
603
604
	/**
605
	 * Get the minimum number of entries.
606
	 *
607
	 * @return int $min
608
	 */
609
	public function get_min() {
610
		return $this->values_min;
611
	}
612
613
	/**
614
	 * Set the maximum number of entries.
615
	 *
616
	 * @param int $max
617
	 */
618
	public function set_max( $max ) {
619
		$this->values_max = intval( $max );
620
		return $this;
621
	}
622
623
	/**
624
	 * Get the maximum number of entries.
625
	 *
626
	 * @return int $max
627
	 */
628
	public function get_max() {
629
		return $this->values_max;
630
	}
631
632
	/**
633
	 * Change the groups initial collapse state.
634
	 * This state relates to the state of which the groups are rendered.
635
	 *
636
	 * @param bool $collapsed
637
	 */
638
	public function set_collapsed( $collapsed = true ) {
639
		$this->collapsed = $collapsed;
640
641
		return $this;
642
	}
643
644
	/**
645
	 * Retrieve the groups of this field.
646
	 *
647
	 * @return array
648
	 */
649
	public function get_group_names() {
650
		return array_keys( $this->groups );
651
	}
652
653
	/**
654
	 * Retrieve a group by its name.
655
	 *
656
	 * @param  string $group_name        Group name
657
	 * @return Group_Field $group_object Group object
658
	 */
659 View Code Duplication
	public function get_group_by_name( $group_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...
660
		$group_object = null;
661
662
		foreach ( $this->groups as $group ) {
663
			if ( $group->get_name() == $group_name ) {
664
				$group_object = $group;
665
			}
666
		}
667
668
		return $group_object;
669
	}
670
}
671