acf_field_flexible_content::__construct()   A
last analyzed

Complexity

Conditions 1
Paths 1

Size

Total Lines 29

Duplication

Lines 0
Ratio 0 %

Importance

Changes 0
Metric Value
cc 1
nc 1
nop 0
dl 0
loc 29
rs 9.456
c 0
b 0
f 0
1
<?php
2
3
/*
4
*  ACF Flexible Content Field Class
5
*
6
*  All the logic for this field type
7
*
8
*  @class 		acf_field_flexible_content
9
*  @extends		acf_field
10
*  @package		ACF
11
*  @subpackage	Fields
12
*/
13
14
if( ! class_exists('acf_field_flexible_content') ) :
15
16
class acf_field_flexible_content 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 = 'flexible_content';
36
		$this->label = __("Flexible Content",'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
			'layouts'		=> array(),
40
			'min'			=> '',
41
			'max'			=> '',
42
			'button_label'	=> __("Add Row",'acf'),
43
		);
44
		$this->l10n = array(
45
			'layout' 		=> __("layout", 'acf'),
46
			'layouts'		=> __("layouts", 'acf'),
47
			'remove'		=> __("remove {layout}?", 'acf'),
48
			'min'			=> __("This field requires at least {min} {identifier}",'acf'),
49
			'max'			=> __("This field has a limit of {max} {identifier}",'acf'),
50
			'min_layout'	=> __("This field requires at least {min} {label} {identifier}",'acf'),
51
			'max_layout'	=> __("Maximum {label} limit reached ({max} {identifier})",'acf'),
52
			'available'		=> __("{available} {label} {identifier} available (max {max})",'acf'),
53
			'required'		=> __("{required} {label} {identifier} required (min {min})",'acf'),
54
		);		
55
		
56
		
57
		// do not delete!
58
    	parent::__construct();
59
		
60
	}
61
	
62
	
63
	/*
64
	*  get_valid_layout
65
	*
66
	*  This function will fill in the missing keys to create a valid layout
67
	*
68
	*  @type	function
69
	*  @date	3/10/13
70
	*  @since	1.1.0
71
	*
72
	*  @param	$layout (array)
73
	*  @return	$layout (array)
74
	*/
0 ignored issues
show
Documentation introduced by
The doc-type $layout could not be parsed: Unknown type name "$layout" 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...
75
	
76
	function get_valid_layout( $layout = array() ) {
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...
77
		
78
		// parse
79
		$layout = wp_parse_args($layout, array(
80
			'key'			=> uniqid(),
81
			'name'			=> '',
82
			'label'			=> '',
83
			'display'		=> 'block',
84
			'sub_fields'	=> array(),
85
			'min'			=> '',
86
			'max'			=> '',
87
		));
88
		
89
		
90
		// return
91
		return $layout;
92
	}
93
	
94
95
	/*
96
	*  load_field()
97
	*
98
	*  This filter is appied to the $field after it is loaded from the database
99
	*
100
	*  @type	filter
101
	*  @since	3.6
102
	*  @date	23/01/13
103
	*
104
	*  @param	$field - the field array holding all the field options
105
	*
106
	*  @return	$field - the field array holding all the field options
107
	*/
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...
108
	
109
	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...
110
		
111
		// bail early if no field layouts
112
		if( empty($field['layouts']) ) {
113
			
114
			return $field;
115
			
116
		}
117
		
118
		
119
		// vars
120
		$sub_fields = acf_get_fields($field);
121
		
122
		
123
		// loop through layouts, sub fields and swap out the field key with the real field
124
		foreach( array_keys($field['layouts']) as $i ) {
125
			
126
			// extract layout
127
			$layout = acf_extract_var( $field['layouts'], $i );
128
			
129
			
130
			// validate layout
131
			$layout = $this->get_valid_layout( $layout );
132
			
133
			
134
			// append sub fields
135
			if( !empty($sub_fields) ) {
136
				
137
				foreach( array_keys($sub_fields) as $k ) {
138
					
139
					// check if 'parent_layout' is empty
140 View Code Duplication
					if( empty($sub_fields[ $k ]['parent_layout']) ) {
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...
141
					
142
						// parent_layout did not save for this field, default it to first layout
143
						$sub_fields[ $k ]['parent_layout'] = $layout['key'];
144
						
145
					}
146
					
147
					
148
					// append sub field to layout, 
149 View Code Duplication
					if( $sub_fields[ $k ]['parent_layout'] == $layout['key'] ) {
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...
150
					
151
						$layout['sub_fields'][] = acf_extract_var( $sub_fields, $k );
152
						
153
					}
154
					
155
				}
156
				
157
			}
158
			
159
			
160
			// append back to layouts
161
			$field['layouts'][ $i ] = $layout;
162
			
163
		}
164
		
165
		
166
		// return
167
		return $field;
168
	}
169
	
170
	
171
	/*
172
	*  render_field()
173
	*
174
	*  Create the HTML interface for your field
175
	*
176
	*  @param	$field - an array holding all the field's data
177
	*
178
	*  @type	action
179
	*  @since	3.6
180
	*  @date	23/01/13
181
	*/
182
	
183
	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...
184
	
185
		// defaults
186
		if( empty($field['button_label']) ) {
187
		
188
			$field['button_label'] = $this->defaults['button_label'];
189
			
190
		}
191
		
192
		
193
		// sort layouts into names
194
		$layouts = array();
195
		
196
		foreach( $field['layouts'] as $k => $layout ) {
197
		
198
			$layouts[ $layout['name'] ] = acf_extract_var( $field['layouts'], $k );
199
			
200
		}
201
		
202
		
203
		// hidden input
204
		acf_hidden_input(array(
205
			'type'	=> 'hidden',
206
			'name'	=> $field['name'],
207
		));
208
		
209
		
210
		// no value message
211
		$no_value_message = __('Click the "%s" button below to start creating your layout','acf');
212
		$no_value_message = apply_filters('acf/fields/flexible_content/no_value_message', $no_value_message, $field);
213
214
?>
215
<div <?php acf_esc_attr_e(array( 'class' => 'acf-flexible-content', 'data-min' => $field['min'], 'data-max'	=> $field['max'] )); ?>>
216
	
217
	<div class="no-value-message" <?php if( $field['value'] ){ echo 'style="display:none;"'; } ?>>
218
		<?php printf( $no_value_message, $field['button_label'] ); ?>
219
	</div>
220
	
221
	<div class="clones">
222
		<?php foreach( $layouts as $layout ): ?>
223
			<?php $this->render_layout( $field, $layout, 'acfcloneindex', array() ); ?>
224
		<?php endforeach; ?>
225
	</div>
226
	<div class="values">
227
		<?php if( !empty($field['value']) ): ?>
228
			<?php foreach( $field['value'] as $i => $value ): ?>
229
				<?php 
230
				
231
				// validate
232
				if( empty($layouts[ $value['acf_fc_layout'] ]) ) {
233
				
234
					continue;
235
					
236
				}
237
238
				$this->render_layout( $field, $layouts[ $value['acf_fc_layout'] ], $i, $value );
239
				
240
				?>
241
			<?php endforeach; ?>
242
		<?php endif; ?>
243
	</div>
244
	
245
	<ul class="acf-hl">
246
		<li class="acf-fr">
247
			<a href="#" class="acf-button blue" data-event="add-layout"><?php echo $field['button_label']; ?></a>
248
		</li>
249
	</ul>
250
	
251
	<script type="text-html" class="tmpl-popup"><?php 
252
		?><div class="acf-fc-popup">
253
			<ul>
254
				<?php foreach( $layouts as $layout ): 
255
					
256
					$atts = array(
257
						'data-layout'	=> $layout['name'],
258
						'data-min' 		=> $layout['min'],
259
						'data-max' 		=> $layout['max'],
260
					);
261
					
262
					?>
263
					<li>
264
						<a href="#" <?php acf_esc_attr_e( $atts ); ?>><?php echo $layout['label']; ?><span class="status"></span></a>
265
					</li>
266
				<?php endforeach; ?>
267
			</ul>
268
			<a href="#" class="focus"></a>
269
		</div>
270
	</script>
271
	
272
</div>
273
<?php
274
		
275
	}
276
	
277
	
278
	/*
279
	*  render_layout
280
	*
281
	*  description
282
	*
283
	*  @type	function
284
	*  @date	19/11/2013
285
	*  @since	5.0.0
286
	*
287
	*  @param	$post_id (int)
288
	*  @return	$post_id (int)
289
	*/
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...
290
	
291
	function render_layout( $field, $layout, $i, $value ) {
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...
292
		
293
		// vars
294
		$order = 0;
295
		$el = 'div';
296
		$div = array(
297
			'class'			=> 'layout',
298
			'data-id'		=> $i,
299
			'data-layout'	=> $layout['name']
300
		);
301
		
302
	
303
		// collapsed
304
		$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...
305
		
306
		
307
		// cookie fallback ( version < 5.3.2 )
308
		if( $collapsed === '' ) {
309
			
310
			$collapsed = acf_extract_var($_COOKIE, "acf_collapsed_{$field['key']}", '');
311
			$collapsed = str_replace('|', ',', $collapsed);
312
			
313
			acf_update_user_setting( 'collapsed_' . $field['key'], $collapsed );
314
				
315
		}
316
		
317
		
318
		// explode
319
		$collapsed = explode(',', $collapsed);
320
		$collapsed = array_filter($collapsed, 'is_numeric');
321
			
322
		
323
		// collapsed class
324
		if( in_array($i, $collapsed) ) {
325
			
326
			$div['class'] .= ' -collapsed';
327
			
328
		}
329
		
330
		
331
		// clone
332
		if( is_numeric($i) ) {
333
			
334
			$order = $i + 1;
335
			
336
		} else {
337
			
338
			$div['class'] .= ' acf-clone';
339
			
340
		}
341
		
342
		
343
?>
344
<div <?php acf_esc_attr_e($div); ?>>
345
			
346
	<div class="acf-hidden">
347
		<?php acf_hidden_input(array( 'name' => "{$field['name']}[{$i}][acf_fc_layout]", 'value' => $layout['name'] )); ?>
348
	</div>
349
	
350
	<div class="acf-fc-layout-handle">
351
		<span class="fc-layout-order"><?php echo $order; ?></span> <?php echo $layout['label']; ?>
352
	</div>
353
	
354
	<ul class="acf-fc-layout-controlls acf-hl">
355
		<li class="acf-fc-show-on-hover">
356
			<a class="acf-icon -plus small" href="#" data-event="add-layout" title="<?php _e('Add layout','acf'); ?>"></a>
357
		</li>
358
		<li class="acf-fc-show-on-hover">
359
			<a class="acf-icon -minus small" href="#" data-event="remove-layout" title="<?php _e('Remove layout','acf'); ?>"></a>
360
		</li>
361
		<li>
362
			<a class="acf-icon -collapse small" href="#" data-event="collapse-layout" title="<?php _e('Click to toggle','acf'); ?>"></a>
363
		</li>
364
	</ul>
365
	
366
<?php if( !empty($layout['sub_fields']) ): ?>
367
	
368 View Code Duplication
	<?php if( $layout['display'] == '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...
369
		
370
		// update vars
371
		$el = 'td';
372
		
373
		?>
374
	<table class="acf-table">
375
		
376
		<thead>
377
			<tr>
378
				<?php foreach( $layout['sub_fields'] as $sub_field ): 
379
					
380
					$atts = array(
381
						'class'		=> "acf-th acf-th-{$sub_field['name']}",
382
						'data-key'	=> $sub_field['key'],
383
					);
384
					
385
					
386
					// Add custom width
387
					if( $sub_field['wrapper']['width'] ) {
388
					
389
						$atts['data-width'] = $sub_field['wrapper']['width'];
390
						
391
					}
392
						
393
					?>
394
					<th <?php acf_esc_attr_e( $atts ); ?>>
395
						<?php echo acf_get_field_label( $sub_field ); ?>
396
						<?php if( $sub_field['instructions'] ): ?>
397
							<p class="description"><?php echo $sub_field['instructions']; ?></p>
398
						<?php endif; ?>
399
					</th>
400
					
401
				<?php endforeach; ?> 
402
			</tr>
403
		</thead>
404
		
405
		<tbody>
406
	<?php else: ?>
407
	<div class="acf-fields <?php if($layout['display'] == 'row'): ?>-left<?php endif; ?>">
408
	<?php endif; ?>
409
	
410
		<?php
411
			
412
		// loop though sub fields
413 View Code Duplication
		foreach( $layout['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...
414
			
415
			// prevent repeater field from creating multiple conditional logic items for each row
416
			if( $i !== 'acfcloneindex' ) {
417
				
418
				$sub_field['conditional_logic'] = 0;
419
				
420
			}
421
			
422
			
423
			// add value
424
			if( isset($value[ $sub_field['key'] ]) ) {
425
				
426
				// this is a normal value
427
				$sub_field['value'] = $value[ $sub_field['key'] ];
428
				
429
			} elseif( isset($sub_field['default_value']) ) {
430
				
431
				// no value, but this sub field has a default value
432
				$sub_field['value'] = $sub_field['default_value'];
433
				
434
			}
435
			
436
			
437
			// update prefix to allow for nested values
438
			$sub_field['prefix'] = "{$field['name']}[{$i}]";
439
			
440
			
441
			// render input
442
			acf_render_field_wrap( $sub_field, $el );
443
		
444
		}
445
		
446
		?>
447
			
448
	<?php if( $layout['display'] == 'table' ): ?>
449
		</tbody>
450
	</table>
451
	<?php else: ?>
452
	</div>
453
	<?php endif; ?>
454
455
<?php endif; ?>
456
457
</div>
458
<?php
459
		
460
	}
461
	
462
	
463
	/*
464
	*  render_field_settings()
465
	*
466
	*  Create extra options for your field. This is rendered when editing a field.
467
	*  The value of $field['name'] can be used (like bellow) to save extra data to the $field
468
	*
469
	*  @type	action
470
	*  @since	3.6
471
	*  @date	23/01/13
472
	*
473
	*  @param	$field	- an array holding all the field's data
474
	*/
475
	
476
	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...
477
		
478
		// load default layout
479
		if( empty($field['layouts']) ) {
480
		
481
			$field['layouts'] = array();
482
			$field['layouts'][] = $this->get_valid_layout();
483
			
484
		}
485
		
486
		
487
		// loop through layouts
488
		foreach( $field['layouts'] as $layout ) {
489
			
490
			// get valid layout
491
			$layout = $this->get_valid_layout( $layout );
492
			
493
			
494
			// vars
495
			$layout_prefix = "{$field['prefix']}[layouts][{$layout['key']}]";
496
			
497
			
498
?><tr class="acf-field" data-name="fc_layout" data-setting="flexible_content" data-id="<?php echo $layout['key']; ?>">
499
	<td class="acf-label">
500
		<label><?php _e("Layout",'acf'); ?></label>
501
		<p class="description acf-fl-actions">
502
			<a data-name="acf-fc-reorder" title="<?php _e("Reorder Layout",'acf'); ?>" ><?php _e("Reorder",'acf'); ?></a>
503
			<a data-name="acf-fc-delete" title="<?php _e("Delete Layout",'acf'); ?>" href="#"><?php _e("Delete",'acf'); ?></a>
504
			<a data-name="acf-fc-duplicate" title="<?php _e("Duplicate Layout",'acf'); ?>" href="#"><?php _e("Duplicate",'acf'); ?></a>
505
			<a data-name="acf-fc-add" title="<?php _e("Add New Layout",'acf'); ?>" href="#"><?php _e("Add New",'acf'); ?></a>
506
		</p>
507
	</td>
508
	<td class="acf-input">
509
		
510
		<ul class="acf-fc-meta acf-bl">
511
			<li class="acf-fc-meta-key">
512
				<?php 
513
				
514
				acf_hidden_input(array(
515
					'name'		=> "{$layout_prefix}[key]",
516
					'data-name'	=> 'layout-key',
517
					'value'		=> $layout['key']
518
				));
519
				
520
				?>
521
			</li>
522
			<li class="acf-fc-meta-label">
523
				<?php 
524
				
525
				acf_render_field(array(
0 ignored issues
show
Documentation introduced by
array('type' => 'text', ... => __('Label', 'acf')) is of type array<string,?,{"type":"...ue":"?","prepend":"?"}>, 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...
526
					'type'		=> 'text',
527
					'name'		=> 'label',
528
					'prefix'	=> $layout_prefix,
529
					'value'		=> $layout['label'],
530
					'prepend'	=> __('Label','acf')
531
				));
532
				
533
				?>
534
			</li>
535
			<li class="acf-fc-meta-name">
536
				<?php 
537
						
538
				acf_render_field(array(
0 ignored issues
show
Documentation introduced by
array('type' => 'text', ...' => __('Name', 'acf')) is of type array<string,?,{"type":"...ue":"?","prepend":"?"}>, 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...
539
					'type'		=> 'text',
540
					'name'		=> 'name',
541
					'prefix'	=> $layout_prefix,
542
					'value'		=> $layout['name'],
543
					'prepend'	=> __('Name','acf')
544
				));
545
				
546
				?>
547
			</li>
548
			<li class="acf-fc-meta-display">
549
				<div class="acf-input-prepend"><?php _e('Layout','acf'); ?></div>
550
				<div class="acf-input-wrap select">
551
					<?php 
552
					
553
					acf_render_field(array(
0 ignored issues
show
Documentation introduced by
array('type' => 'select'...' => __('Row', 'acf'))) is of type array<string,?,{"type":"..."?\",\"row\":\"?\"}>"}>, 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...
554
						'type'		=> 'select',
555
						'name'		=> 'display',
556
						'prefix'	=> $layout_prefix,
557
						'value'		=> $layout['display'],
558
						'choices'	=> array(
559
							'table'			=> __('Table','acf'),
560
							'block'			=> __('Block','acf'),
561
							'row'			=> __('Row','acf')
562
						),
563
					));
564
					
565
					?>
566
				</div>
567
			</li>
568
			<li class="acf-fc-meta-min">
569
				<?php
570
						
571
				acf_render_field(array(
0 ignored issues
show
Documentation introduced by
array('type' => 'text', ...d' => __('Min', 'acf')) is of type array<string,?,{"type":"...ue":"?","prepend":"?"}>, 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...
572
					'type'		=> 'text',
573
					'name'		=> 'min',
574
					'prefix'	=> $layout_prefix,
575
					'value'		=> $layout['min'],
576
					'prepend'	=> __('Min','acf')
577
				));
578
				
579
				?>
580
			</li>
581
			<li class="acf-fc-meta-max">
582
				<?php 
583
				
584
				acf_render_field(array(
0 ignored issues
show
Documentation introduced by
array('type' => 'text', ...d' => __('Max', 'acf')) is of type array<string,?,{"type":"...ue":"?","prepend":"?"}>, 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...
585
					'type'		=> 'text',
586
					'name'		=> 'max',
587
					'prefix'	=> $layout_prefix,
588
					'value'		=> $layout['max'],
589
					'prepend'	=> __('Max','acf')
590
				));
591
				
592
				?>
593
			</li>
594
		</ul>
595
		<?php 
596
		
597
		// vars
598
		$args = array(
599
			'fields'	=> $layout['sub_fields'],
600
			'layout'	=> $layout['display'],
601
			'parent'	=> $field['ID']
602
		);
603
		
604
		acf_get_view('field-group-fields', $args);
605
		
606
		?>
607
	</td>
608
</tr>
609
<?php
610
	
611
		}
612
		// endforeach
613
		
614
		
615
		// min
616
		acf_render_field_setting( $field, array(
617
			'label'			=> __('Button Label','acf'),
618
			'instructions'	=> '',
619
			'type'			=> 'text',
620
			'name'			=> 'button_label',
621
		));
622
		
623
		
624
		// min
625
		acf_render_field_setting( $field, array(
626
			'label'			=> __('Minimum Layouts','acf'),
627
			'instructions'	=> '',
628
			'type'			=> 'number',
629
			'name'			=> 'min',
630
		));
631
		
632
		
633
		// max
634
		acf_render_field_setting( $field, array(
635
			'label'			=> __('Maximum Layouts','acf'),
636
			'instructions'	=> '',
637
			'type'			=> 'number',
638
			'name'			=> 'max',
639
		));
640
				
641
	}
642
	
643
	
644
	/*
645
	*  load_value()
646
	*
647
	*  This filter is applied to the $value after it is loaded from the db
648
	*
649
	*  @type	filter
650
	*  @since	3.6
651
	*  @date	23/01/13
652
	*
653
	*  @param	$value (mixed) the value found in the database
654
	*  @param	$post_id (mixed) the $post_id from which the value was loaded
655
	*  @param	$field (array) the field array holding all the field options
656
	*  @return	$value
657
	*/
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...
658
	
659
	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...
660
		
661
		// bail early if no value
662
		if( empty($value) || empty($field['layouts']) ) {
663
			
664
			return $value;
665
			
666
		}
667
		
668
		
669
		// value must be an array
670
		$value = acf_get_array( $value );
671
		
672
		
673
		// vars
674
		$rows = array();
675
		
676
		
677
		// populate $layouts
678
		$layouts = array();
679
		
680 View Code Duplication
		foreach( array_keys($field['layouts']) 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...
681
			
682
			// get layout
683
			$layout = $field['layouts'][ $i ];
684
			
685
			
686
			// append to $layouts
687
			$layouts[ $layout['name'] ] = $layout['sub_fields'];
688
			
689
		}
690
	
691
		
692
		// loop through rows
693
		foreach( $value as $i => $l ) {
694
			
695
			// append to $values
696
			$rows[ $i ] = array();
697
			$rows[ $i ]['acf_fc_layout'] = $l;
698
			
699
			
700
			// bail early if layout deosnt contain sub fields
701
			if( empty($layouts[ $l ]) ) {
702
				
703
				continue;
704
				
705
			}
706
			
707
			
708
			// get layout
709
			$layout = $layouts[ $l ];
710
			
711
			
712
			// loop through sub fields
713
			foreach( array_keys($layout) as $j ) {
714
				
715
				// get sub field
716
				$sub_field = $layout[ $j ];
717
				
718
				
719
				// update full name
720
				$sub_field['name'] = "{$field['name']}_{$i}_{$sub_field['name']}";
721
				
722
				
723
				// get value
724
				$sub_value = acf_get_value( $post_id, $sub_field );
725
				
726
				
727
				// add value
728
				$rows[ $i ][ $sub_field['key'] ] = $sub_value;
729
				
730
			}
731
			// foreach
732
			
733
		}
734
		// foreach
735
		
736
		
737
		
738
		// return
739
		return $rows;
740
		
741
	}
742
	
743
	
744
	/*
745
	*  format_value()
746
	*
747
	*  This filter is appied to the $value after it is loaded from the db and before it is returned to the template
748
	*
749
	*  @type	filter
750
	*  @since	3.6
751
	*  @date	23/01/13
752
	*
753
	*  @param	$value (mixed) the value which was loaded from the database
754
	*  @param	$post_id (mixed) the $post_id from which the value was loaded
755
	*  @param	$field (array) the field array holding all the field options
756
	*
757
	*  @return	$value (mixed) the modified value
758
	*/
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...
759
	
760
	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...
761
		
762
		// bail early if no value
763
		if( empty($value) || empty($field['layouts']) ) {
764
			
765
			return false;
766
			
767
		}
768
		
769
		
770
		// populate $layouts
771
		$layouts = array();
772
		
773 View Code Duplication
		foreach( array_keys($field['layouts']) 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...
774
			
775
			// get layout
776
			$layout = $field['layouts'][ $i ];
777
			
778
			
779
			// append to $layouts
780
			$layouts[ $layout['name'] ] = $layout['sub_fields'];
781
			
782
		}
783
		
784
		
785
		// loop over rows
786
		foreach( array_keys($value) as $i ) {
787
			
788
			// get layout name
789
			$l = $value[ $i ]['acf_fc_layout'];
790
			
791
			
792
			// bail early if layout deosnt exist
793
			if( empty($layouts[ $l ]) ) {
794
				
795
				continue;
796
				
797
			}
798
			
799
			
800
			// get layout
801
			$layout = $layouts[ $l ];
802
			
803
			
804
			// loop through sub fields
805 View Code Duplication
			foreach( array_keys($layout) 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...
806
				
807
				// get sub field
808
				$sub_field = $layout[ $j ];
809
				
810
				
811
				// extract value
812
				$sub_value = acf_extract_var( $value[ $i ], $sub_field['key'] );
813
				
814
				
815
				// format value
816
				$sub_value = acf_format_value( $sub_value, $post_id, $sub_field );
817
				
818
				
819
				// append to $row
820
				$value[ $i ][ $sub_field['name'] ] = $sub_value;
821
				
822
			}
823
			
824
		}
825
		
826
		
827
		// return
828
		return $value;
829
	}
830
	
831
	
832
	/*
833
	*  validate_value
834
	*
835
	*  description
836
	*
837
	*  @type	function
838
	*  @date	11/02/2014
839
	*  @since	5.0.0
840
	*
841
	*  @param	$post_id (int)
842
	*  @return	$post_id (int)
843
	*/
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...
844
	
845
	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...
846
		
847
		// remove acfcloneindex
848
		if( isset($value['acfcloneindex']) ) {
849
		
850
			unset($value['acfcloneindex']);
851
			
852
		}
853
		
854
		
855
		// valid
856
		if( $field['required'] && empty($value) ) {
857
		
858
			$valid = false;
859
			
860
		}
861
		
862
		
863
		// populate $layouts
864
		$layouts = array();
865
		
866 View Code Duplication
		foreach( array_keys($field['layouts']) 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...
867
			
868
			$layout = acf_extract_var($field['layouts'], $i);
869
			
870
			// append to $layouts
871
			$layouts[ $layout['name'] ] = $layout['sub_fields'];
872
			
873
		}	
874
		
875
		
876
		// check sub fields
877
		if( !empty($value) ) {
878
			
879
			// loop through rows
880
			foreach( $value as $i => $row ) {	
881
				
882
				// get layout
883
				$l = $row['acf_fc_layout'];
884
				
885
				
886
				// loop through sub fields
887
				if( !empty($layouts[ $l ]) ) {
888
					
889 View Code Duplication
					foreach( $layouts[ $l ] 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...
890
						
891
						// get sub field key
892
						$k = $sub_field['key'];
893
						
894
						
895
						// exists?
896
						if( ! isset($value[ $i ][ $k ]) ) {
897
							
898
							continue;
899
							
900
						}
901
						
902
						
903
						// validate
904
						acf_validate_value( $value[ $i ][ $k ], $sub_field, "{$input}[{$i}][{$k}]" );
905
					
906
					}
907
					// foreach
908
					
909
				}
910
				// if
911
				
912
			}
913
			// foreach
914
			
915
		}
916
		// if
917
		
918
		
919
		// return
920
		return $valid;
921
		
922
	}
923
	
924
	
925
	/*
926
	*  update_value()
927
	*
928
	*  This filter is appied to the $value before it is updated in the db
929
	*
930
	*  @type	filter
931
	*  @since	3.6
932
	*  @date	23/01/13
933
	*
934
	*  @param	$value - the value which will be saved in the database
935
	*  @param	$field - the field array holding all the field options
936
	*  @param	$post_id - the $post_id of which the value will be saved
937
	*
938
	*  @return	$value - the modified value
939
	*/
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...
940
	
941
	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...
942
		
943
		// remove acfcloneindex
944
		if( isset($value['acfcloneindex']) ) {
945
		
946
			unset($value['acfcloneindex']);
947
			
948
		}
949
		
950
		
951
		// vars
952
		$order = array();
953
		$layouts = array();
954
		
955
		
956
		// populate $layouts
957
		foreach( $field['layouts'] as $layout ) {
958
			
959
			$layouts[ $layout['name'] ] = $layout['sub_fields'];
960
			
961
		}
962
		
963
		
964
		// update sub fields
965
		if( !empty($value) ) {
966
			
967
			// $i
968
			$i = -1;
969
			
970
			
971
			// loop through rows
972
			foreach( $value as $row ) {	
973
				
974
				// $i
975
				$i++;
976
				
977
				
978
				// get layout
979
				$l = $row['acf_fc_layout'];
980
				
981
				
982
				// append to order
983
				$order[] = $l;
984
				
985
				
986
				// loop through sub fields
987
				if( !empty($layouts[ $l ]) ) {
988
					
989 View Code Duplication
					foreach( $layouts[ $l ] 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...
990
						
991
						// value
992
						$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...
993
						
994
						
995
						// key (backend)
996
						if( isset($row[ $sub_field['key'] ]) ) {
997
							
998
							$v = $row[ $sub_field['key'] ];
999
							
1000
						} elseif( isset($row[ $sub_field['name'] ]) ) {
1001
							
1002
							$v = $row[ $sub_field['name'] ];
1003
							
1004
						} else {
1005
							
1006
							// input is not set (hidden by conditioanl logic)
1007
							continue;
1008
							
1009
						}
1010
						
1011
						
1012
						// modify name for save
1013
						$sub_field['name'] = "{$field['name']}_{$i}_{$sub_field['name']}";
1014
						
1015
						
1016
						// update field
1017
						acf_update_value( $v, $post_id, $sub_field );
1018
						
1019
					}
1020
					// foreach
1021
					
1022
				}
1023
				// if
1024
				
1025
			}
1026
			// foreach
1027
			
1028
		}
1029
		// if
1030
		
1031
		
1032
		// remove old data
1033
		$old_order = acf_get_metadata( $post_id, $field['name'] );
1034
		$old_count = empty($old_order) ? 0 : count($old_order);
1035
		$new_count = empty($order) ? 0 : count($order);
1036
		
1037
		
1038
		if( $old_count > $new_count ) {
1039
			
1040
			for( $i = $new_count; $i < $old_count; $i++ ) {
1041
				
1042
				// get layout
1043
				$l = $old_order[ $i ];
1044
				
1045
				
1046
				// loop through sub fields
1047
				if( !empty($layouts[ $l ]) ) {
1048
					
1049
					foreach( $layouts[ $l ] as $sub_field ) {
1050
						
1051
						// modify name for delete
1052
						$sub_field['name'] = "{$field['name']}_{$i}_{$sub_field['name']}";
1053
						
1054
						
1055
						// delete value
1056
						acf_delete_value( $post_id, $sub_field );
1057
						
1058
					}
1059
					
1060
				}
1061
				
1062
			}
1063
			
1064
		}
1065
1066
		
1067
		// save false for empty value
1068
		if( empty($order) ) {
1069
			
1070
			$order = false;
1071
		
1072
		}
1073
		
1074
		
1075
		// return
1076
		return $order;
1077
	}
1078
	
1079
	
1080
	/*
1081
	*  update_field()
1082
	*
1083
	*  This filter is appied to the $field before it is saved to the database
1084
	*
1085
	*  @type	filter
1086
	*  @since	3.6
1087
	*  @date	23/01/13
1088
	*
1089
	*  @param	$field - the field array holding all the field options
1090
	*  @param	$post_id - the field group ID (post_type = acf)
1091
	*
1092
	*  @return	$field - the modified field
1093
	*/
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...
1094
1095
	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...
1096
		
1097
		// vars
1098
		$layouts = acf_extract_var($field, 'layouts');
1099
		
1100
		
1101
		// update layouts
1102
		$field['layouts'] = array();
1103
		
1104
		
1105
		// loop through sub fields
1106
		if( !empty($layouts) ) {
1107
			
1108
			foreach( $layouts as $layout ) {
1109
				
1110
				// remove sub fields
1111
				unset($layout['sub_fields']);
1112
				
1113
				
1114
				// append to layouts
1115
				$field['layouts'][] = $layout;	
1116
				
1117
			}
1118
			
1119
		}
1120
		
1121
		
1122
		// return		
1123
		return $field;
1124
	}
1125
	
1126
	
1127
	/*
1128
	*  delete_field
1129
	*
1130
	*  description
1131
	*
1132
	*  @type	function
1133
	*  @date	4/04/2014
1134
	*  @since	5.0.0
1135
	*
1136
	*  @param	$post_id (int)
1137
	*  @return	$post_id (int)
1138
	*/
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...
1139
	
1140
	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...
1141
		
1142
		if( !empty($field['layouts']) ) {
1143
			
1144
			// loop through layouts
1145
			foreach( $field['layouts'] as $layout ) {
1146
				
1147
				// loop through sub fields
1148 View Code Duplication
				if( !empty($layout['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...
1149
				
1150
					foreach( $layout['sub_fields'] as $sub_field ) {
1151
					
1152
						acf_delete_field( $sub_field['ID'] );
1153
						
1154
					}
1155
					// foreach
1156
					
1157
				}
1158
				// if
1159
				
1160
			}
1161
			// foreach
1162
			
1163
		}
1164
		// if
1165
		
1166
	}
1167
	
1168
	
1169
	/*
1170
	*  duplicate_field()
1171
	*
1172
	*  This filter is appied to the $field before it is duplicated and saved to the database
1173
	*
1174
	*  @type	filter
1175
	*  @since	3.6
1176
	*  @date	23/01/13
1177
	*
1178
	*  @param	$field - the field array holding all the field options
1179
	*
1180
	*  @return	$field - the modified field
1181
	*/
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...
1182
	
1183
	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...
1184
		
1185
		// vars
1186
		$sub_fields = array();
1187
		
1188
		
1189
		if( !empty($field['layouts']) ) {
1190
			
1191
			// loop through layouts
1192
			foreach( $field['layouts'] as $layout ) {
1193
				
1194
				// extract sub fields
1195
				$extra = acf_extract_var( $layout, 'sub_fields' );
1196
				
1197
				
1198
				// merge
1199
				if( !empty($extra) ) {
1200
					
1201
					$sub_fields = array_merge($sub_fields, $extra);
1202
					
1203
				}
1204
				
1205
			}
1206
			// foreach
1207
			
1208
		}
1209
		// if
1210
		
1211
		
1212
		// save field to get ID
1213
		$field = acf_update_field( $field );
1214
		
1215
		
1216
		// duplicate sub fields
1217
		acf_duplicate_fields( $sub_fields, $field['ID'] );
1218
		
1219
		
1220
		// return		
1221
		return $field;
1222
		
1223
	}
1224
	
1225
}
1226
1227
new acf_field_flexible_content();
1228
1229
endif;
1230
1231
?>
1232