acf_field_repeater::render_field()   F
last analyzed

Complexity

Conditions 35
Paths > 20000

Size

Total Lines 285

Duplication

Lines 105
Ratio 36.84 %

Importance

Changes 0
Metric Value
cc 35
nc 1219200
nop 1
dl 105
loc 285
rs 0
c 0
b 0
f 0

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
/*
4
*  ACF Repeater Field Class
5
*
6
*  All the logic for this field type
7
*
8
*  @class 		acf_field_repeater
9
*  @extends		acf_field
10
*  @package		ACF
11
*  @subpackage	Fields
12
*/
13
14
if( ! class_exists('acf_field_repeater') ) :
15
16
class acf_field_repeater extends acf_field {
17
	
18
	
19
	/*
20
	*  __construct
21
	*
22
	*  This function will setup the field type data
23
	*
24
	*  @type	function
25
	*  @date	5/03/2014
26
	*  @since	5.0.0
27
	*
28
	*  @param	n/a
29
	*  @return	n/a
30
	*/
0 ignored issues
show
Documentation introduced by
The doc-type n/a could not be parsed: Unknown type name "n/a" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
31
	
32
	function __construct() {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
33
		
34
		// vars
35
		$this->name = 'repeater';
36
		$this->label = __("Repeater",'acf');
0 ignored issues
show
Bug introduced by
The property label does not exist. Did you maybe forget to declare it?

In PHP it is possible to write to properties without declaring them. For example, the following is perfectly valid PHP code:

class MyClass { }

$x = new MyClass();
$x->foo = true;

Generally, it is a good practice to explictly declare properties to avoid accidental typos and provide IDE auto-completion:

class MyClass {
    public $foo;
}

$x = new MyClass();
$x->foo = true;
Loading history...
37
		$this->category = 'layout';
38
		$this->defaults = array(
39
			'sub_fields'	=> array(),
40
			'min'			=> 0,
41
			'max'			=> 0,
42
			'layout' 		=> 'table',
43
			'button_label'	=> __("Add Row",'acf'),
44
			'collapsed'		=> ''
45
		);
46
		$this->l10n = array(
47
			'min'			=>	__("Minimum rows reached ({min} rows)",'acf'),
48
			'max'			=>	__("Maximum rows reached ({max} rows)",'acf'),
49
		);
50
		
51
		
52
		// do not delete!
53
    	parent::__construct();
54
	}
55
		
56
	
57
	/*
58
	*  load_field()
59
	*
60
	*  This filter is appied to the $field after it is loaded from the database
61
	*
62
	*  @type	filter
63
	*  @since	3.6
64
	*  @date	23/01/13
65
	*
66
	*  @param	$field - the field array holding all the field options
67
	*
68
	*  @return	$field - the field array holding all the field options
69
	*/
0 ignored issues
show
Documentation introduced by
The doc-type $field could not be parsed: Unknown type name "$field" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
70
	
71
	function load_field( $field ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
72
		
73
		$field['sub_fields'] = acf_get_fields( $field );
74
		
75
		
76
		// return
77
		return $field;
78
	}
79
80
	
81
	
82
	/*
83
	*  render_field()
84
	*
85
	*  Create the HTML interface for your field
86
	*
87
	*  @param	$field - an array holding all the field's data
88
	*
89
	*  @type	action
90
	*  @since	3.6
91
	*  @date	23/01/13
92
	*/
93
	
94
	function render_field( $field ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
95
		
96
		// vars
97
		$div = array(
98
			'class' 		=> 'acf-repeater',
99
			'data-min' 		=> $field['min'],
100
			'data-max'		=> $field['max']
101
		);
102
		
103
		
104
		// ensure value is an array
105
		if( empty($field['value']) ) {
106
		
107
			$field['value'] = array();
108
			
109
			$div['class'] .= ' -empty';
110
			
111
		}
112
		
113
		
114
		// rows
115
		$field['min'] = empty($field['min']) ? 0 : $field['min'];
116
		$field['max'] = empty($field['max']) ? 0 : $field['max'];
117
		
118
		
119
		// populate the empty row data (used for acfcloneindex and min setting)
120
		$empty_row = array();
121
		
122
		
123
		// If there are less values than min, populate the extra values
124 View Code Duplication
		if( $field['min'] ) {
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...
125
			
126
			for( $i = 0; $i < $field['min']; $i++ ) {
127
			
128
				// continue if already have a value
129
				if( array_key_exists($i, $field['value']) ) {
130
				
131
					continue;
132
					
133
				}
134
				
135
				
136
				// populate values
137
				$field['value'][ $i ] = $empty_row;
138
				
139
			}
140
			
141
		}
142
		
143
		
144
		// If there are more values than man, remove some values
145 View Code Duplication
		if( $field['max'] ) {
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...
146
		
147
			for( $i = 0; $i < count($field['value']); $i++ ) {
0 ignored issues
show
Performance Best Practice introduced by
It seems like you are calling the size function count() as part of the test condition. You might want to compute the size beforehand, and not on each iteration.

If the size of the collection does not change during the iteration, it is generally a good practice to compute it beforehand, and not on each iteration:

for ($i=0; $i<count($array); $i++) { // calls count() on each iteration
}

// Better
for ($i=0, $c=count($array); $i<$c; $i++) { // calls count() just once
}
Loading history...
148
			
149
				if( $i >= $field['max'] ) {
150
				
151
					unset( $field['value'][ $i ] );
152
					
153
				}
154
				
155
			}
156
			
157
		}
158
		
159
		
160
		// setup values for row clone
161
		$field['value']['acfcloneindex'] = $empty_row;
162
		
163
		
164
		// show columns
165
		$show_order = true;
166
		$show_add = true;
167
		$show_remove = true;
168
		
169
		
170
		if( $field['max'] ) {
171
		
172
			if( $field['max'] == 1 ) {
173
			
174
				$show_order = false;
175
				
176
			}
177
			
178
			if( $field['max'] <= $field['min'] ) {
179
			
180
				$show_remove = false;
181
				$show_add = false;
182
				
183
			}
184
			
185
		}
186
		
187
		
188
		// field wrap
189
		$el = 'td';
190
		$before_fields = '';
191
		$after_fields = '';
192
		
193
		if( $field['layout'] == 'row' ) {
194
		
195
			$el = 'div';
196
			$before_fields = '<td class="acf-fields -left">';
197
			$after_fields = '</td>';
198
			
199
		} elseif( $field['layout'] == 'block' ) {
200
		
201
			$el = 'div';
202
			
203
			$before_fields = '<td class="acf-fields">';
204
			$after_fields = '</td>';
205
			
206
		}
207
		
208
		
209
		// layout
210
		$div['class'] .= ' -' . $field['layout'];
211
		
212
		
213
		// hidden input
214
		acf_hidden_input(array(
215
			'type'	=> 'hidden',
216
			'name'	=> $field['name'],
217
		));
218
		
219
		
220
		// collapsed
221
		$collapsed = array();
222
		
223
		if( $field['collapsed'] ) {
224
			
225
			// get user setting
226
			$collapsed = acf_get_user_setting('collapsed_' . $field['key'], '');
0 ignored issues
show
Documentation introduced by
'' is of type string, but the function expects a boolean.

It seems like the type of the argument is not accepted by the function/method which you are calling.

In some cases, in particular if PHP’s automatic type-juggling kicks in this might be fine. In other cases, however this might be a bug.

We suggest to add an explicit type cast like in the following example:

function acceptsInteger($int) { }

$x = '123'; // string "123"

// Instead of
acceptsInteger($x);

// we recommend to use
acceptsInteger((integer) $x);
Loading history...
227
			$collapsed = explode(',', $collapsed);
228
			$collapsed = array_filter($collapsed, 'is_numeric');
229
			
230
			
231
			// add target class
232
			foreach( array_keys($field['sub_fields']) as $i ) {
233
				
234
				if( $field['sub_fields'][ $i ]['key'] === $field['collapsed'] ) {
235
					
236
					$field['sub_fields'][ $i ]['wrapper']['class'] .= ' -collapsed-target';
237
					
238
				}
239
								
240
			}
241
			
242
		}
243
		
244
?>
245
<div <?php acf_esc_attr_e($div); ?>>
246
<table class="acf-table">
247
	
248 View Code Duplication
	<?php if( $field['layout'] == 'table' ): ?>
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...
249
		<thead>
250
			<tr>
251
				<?php if( $show_order ): ?>
252
					<th class="acf-row-handle"><span></span></th>
253
				<?php endif; ?>
254
				
255
				<?php foreach( $field['sub_fields'] as $sub_field ): 
256
					
257
					$atts = array(
258
						'class'		=> 'acf-th',
259
						'data-key'	=> $sub_field['key'],
260
					);
261
					
262
					
263
					// add type
264
					$atts['class'] .= ' acf-th-' . $sub_field['type'];
265
					
266
					
267
					// Add custom width
268
					if( $sub_field['wrapper']['width'] ) {
269
					
270
						$atts['data-width'] = $sub_field['wrapper']['width'];
271
						
272
					}
273
						
274
					?>
275
					<th <?php acf_esc_attr_e( $atts ); ?>>
276
						<?php echo acf_get_field_label( $sub_field ); ?>
277
						<?php if( $sub_field['instructions'] ): ?>
278
							<p class="description"><?php echo $sub_field['instructions']; ?></p>
279
						<?php endif; ?>
280
					</th>
281
					
282
				<?php endforeach; ?>
283
284
				<?php if( $show_remove ): ?>
285
					<th class="acf-row-handle"><span></span></th>
286
				<?php endif; ?>
287
			</tr>
288
		</thead>
289
	<?php endif; ?>
290
	
291
	<tbody>
292
		<?php foreach( $field['value'] as $i => $row ): 
293
			
294
			$row_class = 'acf-row';
295
			
296
			if( $i === 'acfcloneindex' ) {
297
				
298
				$row_class .= ' acf-clone';
299
				
300
			} elseif( in_array($i, $collapsed) ) {
301
				
302
				$row_class .= ' -collapsed';
303
				
304
			}
305
			
306
			?>
307
			<tr class="<?php echo $row_class; ?>" data-id="<?php echo $i; ?>">
308
				
309
				<?php if( $show_order ): ?>
310
					<td class="acf-row-handle order" title="<?php _e('Drag to reorder','acf'); ?>">
311
						<?php if( $field['collapsed'] ): ?>
312
						<a class="acf-icon -collapse small" href="#" data-event="collapse-row" title="<?php _e('Click to toggle','acf'); ?>"></a>
313
						<?php endif; ?>
314
						<span><?php echo intval($i) + 1; ?></span>
315
					</td>
316
				<?php endif; ?>
317
				
318
				<?php echo $before_fields; ?>
319
				
320 View Code Duplication
				<?php foreach( $field['sub_fields'] as $sub_field ): 
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...
321
					
322
					// prevent repeater field from creating multiple conditional logic items for each row
323
					if( $i !== 'acfcloneindex' ) {
324
					
325
						$sub_field['conditional_logic'] = 0;
326
						
327
					}
328
					
329
					
330
					// add value
331
					if( isset($row[ $sub_field['key'] ]) ) {
332
						
333
						// this is a normal value
334
						$sub_field['value'] = $row[ $sub_field['key'] ];
335
						
336
					} elseif( isset($sub_field['default_value']) ) {
337
						
338
						// no value, but this sub field has a default value
339
						$sub_field['value'] = $sub_field['default_value'];
340
						
341
					}
342
					
343
					
344
					// update prefix to allow for nested values
345
					$sub_field['prefix'] = "{$field['name']}[{$i}]";
346
					
347
					
348
					// render input
349
					acf_render_field_wrap( $sub_field, $el ); ?>
350
					
351
				<?php endforeach; ?>
352
				
353
				<?php echo $after_fields; ?>
354
				
355
				<?php if( $show_remove ): ?>
356
					<td class="acf-row-handle remove">
357
						<a class="acf-icon -plus small" href="#" data-event="add-row" title="<?php _e('Add row','acf'); ?>"></a>
358
						<a class="acf-icon -minus small" href="#" data-event="remove-row" title="<?php _e('Remove row','acf'); ?>"></a>
359
					</td>
360
				<?php endif; ?>
361
				
362
			</tr>
363
		<?php endforeach; ?>
364
	</tbody>
365
</table>
366
<?php if( $show_add ): ?>
367
	
368
	<ul class="acf-hl">
369
		<li class="acf-fr">
370
			<a href="#" class="acf-button blue" data-event="add-row"><?php echo $field['button_label']; ?></a>
371
		</li>
372
	</ul>
373
			
374
<?php endif; ?>
375
</div>
376
<?php
377
		
378
	}
379
	
380
	
381
	/*
382
	*  render_field_settings()
383
	*
384
	*  Create extra options for your field. This is rendered when editing a field.
385
	*  The value of $field['name'] can be used (like bellow) to save extra data to the $field
386
	*
387
	*  @type	action
388
	*  @since	3.6
389
	*  @date	23/01/13
390
	*
391
	*  @param	$field	- an array holding all the field's data
392
	*/
393
	
394
	function render_field_settings( $field ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
395
		
396
		// vars
397
		$args = array(
398
			'fields'	=> $field['sub_fields'],
399
			'layout'	=> $field['layout'],
400
			'parent'	=> $field['ID']
401
		);
402
		
403
		
404
		?><tr class="acf-field" data-setting="repeater" data-name="sub_fields">
405
			<td class="acf-label">
406
				<label><?php _e("Sub Fields",'acf'); ?></label>
407
				<p class="description"></p>		
408
			</td>
409
			<td class="acf-input">
410
				<?php 
411
				
412
				acf_get_view('field-group-fields', $args);
413
				
414
				?>
415
			</td>
416
		</tr>
417
		<?php
418
		
419
		
420
		// rows
421
		$field['min'] = empty($field['min']) ? '' : $field['min'];
422
		$field['max'] = empty($field['max']) ? '' : $field['max'];
423
		
424
		
425
		// preview
426
		$choices = array();
427
		
428
		if( $field['collapsed'] ) {
429
			
430
			$choices[ $field['collapsed'] ] = $field['collapsed'];
431
			
432
		}
433
		
434
		
435
		acf_render_field_setting( $field, array(
436
			'label'			=> __('Collapsed','acf'),
437
			'instructions'	=> __('Select a sub field to show when row is collapsed','acf'),
438
			'type'			=> 'select',
439
			'name'			=> 'collapsed',
440
			'allow_null'	=> 1,
441
			'choices'		=> $choices
442
		));
443
		
444
		
445
		// min
446
		acf_render_field_setting( $field, array(
447
			'label'			=> __('Minimum Rows','acf'),
448
			'instructions'	=> '',
449
			'type'			=> 'number',
450
			'name'			=> 'min',
451
			'placeholder'	=> '0',
452
		));
453
		
454
		
455
		// max
456
		acf_render_field_setting( $field, array(
457
			'label'			=> __('Maximum Rows','acf'),
458
			'instructions'	=> '',
459
			'type'			=> 'number',
460
			'name'			=> 'max',
461
			'placeholder'	=> '0',
462
		));
463
		
464
		
465
		// layout
466
		acf_render_field_setting( $field, array(
467
			'label'			=> __('Layout','acf'),
468
			'instructions'	=> '',
469
			'class'			=> 'acf-repeater-layout',
470
			'type'			=> 'radio',
471
			'name'			=> 'layout',
472
			'layout'		=> 'horizontal',
473
			'choices'		=> array(
474
				'table'			=> __('Table','acf'),
475
				'block'			=> __('Block','acf'),
476
				'row'			=> __('Row','acf')
477
			)
478
		));
479
		
480
		
481
		// button_label
482
		acf_render_field_setting( $field, array(
483
			'label'			=> __('Button Label','acf'),
484
			'instructions'	=> '',
485
			'type'			=> 'text',
486
			'name'			=> 'button_label',
487
		));
488
		
489
	}
490
	
491
	
492
	/*
493
	*  load_value()
494
	*
495
	*  This filter is applied to the $value after it is loaded from the db
496
	*
497
	*  @type	filter
498
	*  @since	3.6
499
	*  @date	23/01/13
500
	*
501
	*  @param	$value (mixed) the value found in the database
502
	*  @param	$post_id (mixed) the $post_id from which the value was loaded
503
	*  @param	$field (array) the field array holding all the field options
504
	*  @return	$value
505
	*/
0 ignored issues
show
Documentation introduced by
The doc-type $value could not be parsed: Unknown type name "$value" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
506
	
507
	function load_value( $value, $post_id, $field ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
508
		
509
		// bail early if no value
510
		if( empty($value) || empty($field['sub_fields']) ) {
511
			
512
			return $value;
513
			
514
		}
515
		
516
		
517
		// convert to int
518
		$value = intval( $value );
519
		
520
		
521
		// vars
522
		$rows = array();
523
		
524
		
525
		// check number of rows
526
		if( $value > 0 ) {
527
			
528
			// loop through rows
529
			for( $i = 0; $i < $value; $i++ ) {
530
				
531
				// create empty array
532
				$rows[ $i ] = array();
533
				
534
				
535
				// loop through sub fields
536
				foreach( array_keys($field['sub_fields']) as $j ) {
537
					
538
					// get sub field
539
					$sub_field = $field['sub_fields'][ $j ];
540
					
541
					
542
					// update $sub_field name
543
					$sub_field['name'] = "{$field['name']}_{$i}_{$sub_field['name']}";
544
					
545
					
546
					// get value
547
					$sub_value = acf_get_value( $post_id, $sub_field );
548
				
549
				
550
					// add value
551
					$rows[ $i ][ $sub_field['key'] ] = $sub_value;
552
					
553
				}
554
				// foreach
555
				
556
			}
557
			// for
558
			
559
		}
560
		// if
561
		
562
		
563
		// return
564
		return $rows;
565
		
566
	}
567
	
568
	
569
	/*
570
	*  format_value()
571
	*
572
	*  This filter is appied to the $value after it is loaded from the db and before it is returned to the template
573
	*
574
	*  @type	filter
575
	*  @since	3.6
576
	*  @date	23/01/13
577
	*
578
	*  @param	$value (mixed) the value which was loaded from the database
579
	*  @param	$post_id (mixed) the $post_id from which the value was loaded
580
	*  @param	$field (array) the field array holding all the field options
581
	*
582
	*  @return	$value (mixed) the modified value
583
	*/
0 ignored issues
show
Documentation introduced by
The doc-type $value could not be parsed: Unknown type name "$value" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
584
	
585
	function format_value( $value, $post_id, $field ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
586
		
587
		// bail early if no value
588
		if( empty($value) || empty($field['sub_fields']) ) {
589
						
590
			return false;
591
			
592
		}
593
		
594
		
595
		// loop over rows
596
		foreach( array_keys($value) as $i ) {
597
			
598
			// loop through sub fields
599 View Code Duplication
			foreach( array_keys($field['sub_fields']) as $j ) {
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...
600
				
601
				// get sub field
602
				$sub_field = $field['sub_fields'][ $j ];
603
				
604
				
605
				// extract value
606
				$sub_value = acf_extract_var( $value[ $i ], $sub_field['key'] );
607
				
608
				
609
				// format value
610
				$sub_value = acf_format_value( $sub_value, $post_id, $sub_field );
611
				
612
				
613
				// append to $row
614
				$value[ $i ][ $sub_field['name'] ] = $sub_value;
615
				
616
			}
617
			
618
		}
619
		
620
		
621
		// return
622
		return $value;
623
		
624
	}
625
	
626
	
627
	/*
628
	*  validate_value
629
	*
630
	*  description
631
	*
632
	*  @type	function
633
	*  @date	11/02/2014
634
	*  @since	5.0.0
635
	*
636
	*  @param	$post_id (int)
637
	*  @return	$post_id (int)
638
	*/
0 ignored issues
show
Documentation introduced by
The doc-type $post_id could not be parsed: Unknown type name "$post_id" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
639
	
640
	function validate_value( $valid, $value, $field, $input ){
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
641
		
642
		// remove acfcloneindex
643
		if( isset($value['acfcloneindex']) ) {
644
		
645
			unset($value['acfcloneindex']);
646
			
647
		}
648
		
649
		
650
		// valid
651
		if( $field['required'] && empty($value) ) {
652
		
653
			$valid = false;
654
			
655
		}
656
		
657
		
658
		// check sub fields
659
		if( !empty($field['sub_fields']) && !empty($value) ) {
660
			
661
			$keys = array_keys($value);
662
			
663 View Code Duplication
			foreach( $keys as $i ) {
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...
664
				
665
				foreach( $field['sub_fields'] as $sub_field ) {
666
					
667
					// vars
668
					$k = $sub_field['key'];
669
					
670
					
671
					// test sub field exists
672
					if( !isset($value[ $i ][ $k ]) ) {
673
					
674
						continue;
675
						
676
					}
677
					
678
					
679
					// validate
680
					acf_validate_value( $value[ $i ][ $k ], $sub_field, "{$input}[{$i}][{$k}]" );
681
				}
682
				
683
			}
684
			
685
		}
686
		
687
		return $valid;
688
		
689
	}
690
	
691
	
692
	/*
693
	*  update_value()
694
	*
695
	*  This filter is appied to the $value before it is updated in the db
696
	*
697
	*  @type	filter
698
	*  @since	3.6
699
	*  @date	23/01/13
700
	*
701
	*  @param	$value - the value which will be saved in the database
702
	*  @param	$field - the field array holding all the field options
703
	*  @param	$post_id - the $post_id of which the value will be saved
704
	*
705
	*  @return	$value - the modified value
706
	*/
0 ignored issues
show
Documentation introduced by
The doc-type $value could not be parsed: Unknown type name "$value" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
707
	
708
	function update_value( $value, $post_id, $field ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
709
		
710
		// vars
711
		$total = 0;
712
		
713
		
714
		// remove acfcloneindex
715
		if( isset($value['acfcloneindex']) ) {
716
		
717
			unset($value['acfcloneindex']);
718
			
719
		}
720
		
721
		
722
		// update sub fields
723
		if( !empty($value) ) {
724
			
725
			// $i
726
			$i = -1;
727
			
728
			
729
			// loop through rows
730
			foreach( $value as $row ) {	
731
				
732
				// $i
733
				$i++;
734
				
735
				
736
				// increase total
737
				$total++;
738
				
739
				
740
				// continue if no sub fields
741
				if( !$field['sub_fields'] ) {
742
					
743
					continue;
744
					
745
				}
746
					
747
					
748
				// loop through sub fields
749 View Code Duplication
				foreach( $field['sub_fields'] as $sub_field ) {
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...
750
					
751
					// value
752
					$v = false;
0 ignored issues
show
Unused Code introduced by
$v is not used, you could remove the assignment.

This check looks for variable assignements that are either overwritten by other assignments or where the variable is not used subsequently.

$myVar = 'Value';
$higher = false;

if (rand(1, 6) > 3) {
    $higher = true;
} else {
    $higher = false;
}

Both the $myVar assignment in line 1 and the $higher assignment in line 2 are dead. The first because $myVar is never used and the second because $higher is always overwritten for every possible time line.

Loading history...
753
					
754
					
755
					// key (backend)
756
					if( isset($row[ $sub_field['key'] ]) ) {
757
						
758
						$v = $row[ $sub_field['key'] ];
759
						
760
					} elseif( isset($row[ $sub_field['name'] ]) ) {
761
						
762
						$v = $row[ $sub_field['name'] ];
763
						
764
					} else {
765
						
766
						// input is not set (hidden by conditioanl logic)
767
						continue;
768
						
769
					}
770
					
771
					
772
					// modify name for save
773
					$sub_field['name'] = "{$field['name']}_{$i}_{$sub_field['name']}";
774
					
775
					
776
					// update value
777
					acf_update_value( $v, $post_id, $sub_field );
778
					
779
				}
780
				// foreach
781
				
782
			}
783
			// foreach
784
			
785
		}
786
		// if
787
		
788
		
789
		// get old value (db only)
790
		$old_total = (int) acf_get_metadata( $post_id, $field['name'] );
791
		
792
		if( $old_total > $total ) {
793
			
794 View Code Duplication
			for( $i = $total; $i < $old_total; $i++ ) {
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...
795
				
796
				foreach( $field['sub_fields'] as $sub_field ) {
797
					
798
					// modify name for delete
799
					$sub_field['name'] = "{$field['name']}_{$i}_{$sub_field['name']}";
800
					
801
					
802
					// delete value
803
					acf_delete_value( $post_id, $sub_field );
804
				
805
				}
806
				// foreach
807
			
808
			}
809
			// for
810
			
811
		}
812
		// if
813
814
		
815
		// update $value and return to allow for the normal save function to run
816
		$value = $total;
817
		
818
		
819
		// return
820
		return $value;
821
	}
822
	
823
	
824
	/*
825
	*  delete_value
826
	*
827
	*  description
828
	*
829
	*  @type	function
830
	*  @date	1/07/2015
831
	*  @since	5.2.3
832
	*
833
	*  @param	$post_id (int)
834
	*  @return	$post_id (int)
835
	*/
0 ignored issues
show
Documentation introduced by
The doc-type $post_id could not be parsed: Unknown type name "$post_id" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
836
	
837
	function delete_value( $post_id, $key, $field ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
838
		
839
		// get old value (db only)
840
		$old_total = (int) acf_get_metadata( $post_id, $field['name'] );
841
		
842
		
843
		// bail early if no rows or no sub fields
844
		if( !$old_total || !$field['sub_fields'] ) {
845
			
846
			return;
847
			
848
		}
849
		
850
		
851 View Code Duplication
		for( $i = 0; $i < $old_total; $i++ ) {
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...
852
			
853
			foreach( $field['sub_fields'] as $sub_field ) {
854
				
855
				// modify name for delete
856
				$sub_field['name'] = "{$key}_{$i}_{$sub_field['name']}";
857
				
858
				
859
				// delete value
860
				acf_delete_value( $post_id, $sub_field );
861
			
862
			}
863
			// foreach
864
			
865
		}
866
			
867
	}
868
	
869
	
870
	/*
871
	*  delete_field
872
	*
873
	*  description
874
	*
875
	*  @type	function
876
	*  @date	4/04/2014
877
	*  @since	5.0.0
878
	*
879
	*  @param	$post_id (int)
880
	*  @return	$post_id (int)
881
	*/
0 ignored issues
show
Documentation introduced by
The doc-type $post_id could not be parsed: Unknown type name "$post_id" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
882
	
883
	function delete_field( $field ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
884
		
885
		// loop through sub fields
886 View Code Duplication
		if( !empty($field['sub_fields']) ) {
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...
887
		
888
			foreach( $field['sub_fields'] as $sub_field ) {
889
			
890
				acf_delete_field( $sub_field['ID'] );
891
				
892
			}
893
			
894
		}
895
		
896
	}
897
	
898
	
899
	/*
900
	*  update_field()
901
	*
902
	*  This filter is appied to the $field before it is saved to the database
903
	*
904
	*  @type	filter
905
	*  @since	3.6
906
	*  @date	23/01/13
907
	*
908
	*  @param	$field - the field array holding all the field options
909
	*  @param	$post_id - the field group ID (post_type = acf)
910
	*
911
	*  @return	$field - the modified field
912
	*/
0 ignored issues
show
Documentation introduced by
The doc-type $field could not be parsed: Unknown type name "$field" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
913
914
	function update_field( $field ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
915
		
916
		// remove sub fields
917
		unset($field['sub_fields']);
918
		
919
				
920
		// return		
921
		return $field;
922
	}
923
	
924
	
925
	/*
926
	*  duplicate_field()
927
	*
928
	*  This filter is appied to the $field before it is duplicated and saved to the database
929
	*
930
	*  @type	filter
931
	*  @since	3.6
932
	*  @date	23/01/13
933
	*
934
	*  @param	$field - the field array holding all the field options
935
	*
936
	*  @return	$field - the modified field
937
	*/
0 ignored issues
show
Documentation introduced by
The doc-type $field could not be parsed: Unknown type name "$field" at position 0. (view supported doc-types)

This check marks PHPDoc comments that could not be parsed by our parser. To see which comment annotations we can parse, please refer to our documentation on supported doc-types.

Loading history...
938
939
	function duplicate_field( $field ) {
0 ignored issues
show
Best Practice introduced by
It is generally recommended to explicitly declare the visibility for methods.

Adding explicit visibility (private, protected, or public) is generally recommend to communicate to other developers how, and from where this method is intended to be used.

Loading history...
940
		
941
		// get sub fields
942
		$sub_fields = acf_extract_var( $field, 'sub_fields' );
943
		
944
		
945
		// save field to get ID
946
		$field = acf_update_field( $field );
947
		
948
		
949
		// duplicate sub fields
950
		acf_duplicate_fields( $sub_fields, $field['ID'] );
951
		
952
						
953
		// return		
954
		return $field;
955
	}
956
957
}
958
959
new acf_field_repeater();
960
961
endif;
962
963
?>
964