api-template.php ➔ have_rows()   F
last analyzed

Complexity

Conditions 20
Paths 384

Size

Total Lines 167

Duplication

Lines 49
Ratio 29.34 %

Importance

Changes 0
Metric Value
cc 20
nc 384
nop 2
dl 49
loc 167
rs 0.8266
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_get_field_reference()
5
*
6
*  This function will find the $field_key that is related to the $field_name.
7
*  This is know as the field value reference
8
*
9
*  @type	function
10
*  @since	3.6
11
*  @date	29/01/13
12
*
13
*  @param	$field_name (mixed) the name of the field. eg 'sub_heading'
14
*  @param	$post_id (int) the post_id of which the value is saved against
15
*  @return	$reference (string)	a string containing the field_key
16
*/
0 ignored issues
show
Documentation introduced by
The doc-type $reference could not be parsed: Unknown type name "$reference" 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...
17
18
function acf_get_field_reference( $field_name, $post_id ) {
19
	
20
	// try cache
21
	$found = false;
22
	$cache = wp_cache_get( "field_reference/post_id={$post_id}/name={$field_name}", 'acf', false, $found );
23
	
24
	if( $found ) {
25
		
26
		return $cache;
27
		
28
	}
29
			
30
	
31
	// get reference
32
	$reference = acf_get_metadata( $post_id, $field_name, true );
33
	
34
	
35
	//update cache
36
	wp_cache_set( "field_reference/post_id={$post_id}/name={$field_name}", $reference, 'acf' );
37
	
38
	
39
	// return
40
	return $reference;
41
	
42
}
43
44
45
/*
46
*  the_field()
47
*
48
*  This function is the same as echo get_field().
49
*
50
*  @type	function
51
*  @since	1.0.3
52
*  @date	29/01/13
53
*
54
*  @param	$selector (string) the field name or key
55
*  @param	$post_id (mixed) the post_id of which the value is saved against
56
*  @return	n/a
57
*/
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...
58
59
function the_field( $selector, $post_id = false, $format_value = true ) {
60
	
61
	$value = get_field($selector, $post_id, $format_value);
62
	
63
	if( is_array($value) ) {
64
		
65
		$value = @implode( ', ', $value );
66
		
67
	}
68
	
69
	echo $value;
70
	
71
}
72
73
74
/*
75
*  get_field()
76
*
77
*  This function will return a custom field value for a specific field name/key + post_id.
78
*  There is a 3rd parameter to turn on/off formating. This means that an image field will not use 
79
*  its 'return option' to format the value but return only what was saved in the database
80
*
81
*  @type	function
82
*  @since	3.6
83
*  @date	29/01/13
84
*
85
*  @param	$selector (string) the field name or key
86
*  @param	$post_id (mixed) the post_id of which the value is saved against
87
*  @param	$format_value (boolean) whether or not to format the value as described above
88
*  @return	(mixed)
89
*/
90
 
91
function get_field( $selector, $post_id = false, $format_value = true ) {
92
	
93
	// filter post_id
94
	$post_id = acf_get_valid_post_id( $post_id );
0 ignored issues
show
Documentation introduced by
$post_id is of type boolean, but the function expects a integer.

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...
95
	
96
	
97
	// get field
98
	$field = acf_maybe_get_field( $selector, $post_id );
99
	
100
	
101
	// create dummy field
102 View Code Duplication
	if( !$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...
103
		
104
		$field = acf_get_valid_field(array(
0 ignored issues
show
Documentation introduced by
array('name' => $selecto...y' => '', 'type' => '') is of type array<string,?,{"name":"...ring","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...
105
			'name'	=> $selector,
106
			'key'	=> '',
107
			'type'	=> '',
108
		));
109
		
110
		
111
		// prevent formatting
112
		$format_value = false;
113
		
114
	}
115
	
116
	
117
	// get value for field
118
	$value = acf_get_value( $post_id, $field );
119
	
120
	
121
	// format value
122
	if( $format_value ) {
123
		
124
		// get value for field
125
		$value = acf_format_value( $value, $post_id, $field );
126
		
127
	}
128
	
129
	
130
	// return
131
	return $value;
132
	 
133
}
134
135
136
/*
137
*  get_field_object()
138
*
139
*  This function will return an array containing all the field data for a given field_name
140
*
141
*  @type	function
142
*  @since	3.6
143
*  @date	3/02/13
144
*
145
*  @param	$selector (string) the field name or key
146
*  @param	$post_id (mixed) the post_id of which the value is saved against
147
*  @param	$format_value (boolean) whether or not to format the field value
148
*  @param	$load_value (boolean) whether or not to load the field value
149
*  @return	$field (array)
150
*/
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...
151
152
function get_field_object( $selector, $post_id = false, $format_value = true, $load_value = true ) {
153
	
154
	// compatibilty
155
	if( is_array($format_value) ) {
156
		
157
		extract( $format_value );
158
		
159
	}
160
	
161
	
162
	// get valid post_id
163
	$post_id = acf_get_valid_post_id( $post_id );
0 ignored issues
show
Documentation introduced by
$post_id is of type boolean, but the function expects a integer.

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...
164
	
165
	
166
	// get field key
167
	$field = acf_maybe_get_field( $selector, $post_id );
168
	
169
	
170
	// bail early if no field found
171
	if( !$field ) {
172
		
173
		return false;
174
		
175
	}
176
	
177
	
178
	// load value
179
	if( $load_value ) {
180
	
181
		$field['value'] = acf_get_value( $post_id, $field );
182
		
183
	}
184
	
185
	
186
	// format value
187
	if( $format_value ) {
188
		
189
		// get value for field
190
		$field['value'] = acf_format_value( $field['value'], $post_id, $field );
191
		
192
	}
193
	
194
	
195
	// return
196
	return $field;
197
	
198
}
199
200
201
/*
202
*  get_fields()
203
*
204
*  This function will return an array containing all the custom field values for a specific post_id.
205
*  The function is not very elegant and wastes a lot of PHP memory / SQL queries if you are not using all the values.
206
*
207
*  @type	function
208
*  @since	3.6
209
*  @date	29/01/13
210
*
211
*  @param	$post_id (mixed) the post_id of which the value is saved against
212
*  @param	$format_value (boolean) whether or not to format the field value
213
*  @return	(array)	associative array where field name => field value
214
*/
215
216
function get_fields( $post_id = false, $format_value = true ) {
217
	
218
	// vars
219
	$fields = get_field_objects( $post_id, $format_value );
220
	$return = array();
221
	
222
	
223
	// populate
224
	if( is_array($fields) ) {
225
		
226
		foreach( $fields as $k => $field ) {
227
		
228
			$return[ $k ] = $field['value'];
229
			
230
		}
231
		
232
	}
233
	
234
	
235
	// return
236
	return $return;	
237
}
238
239
240
/*
241
*  get_field_objects()
242
*
243
*  This function will return an array containing all the custom field objects for a specific post_id.
244
*  The function is not very elegant and wastes a lot of PHP memory / SQL queries if you are not using all the fields / values.
245
*
246
*  @type	function
247
*  @since	3.6
248
*  @date	29/01/13
249
*
250
*  @param	$post_id (mixed) the post_id of which the value is saved against
251
*  @param	$format_value (boolean) whether or not to format the field value
252
*  @param	$load_value (boolean) whether or not to load the field value
253
*  @return	(array)	associative array where field name => field
254
*/
255
256
function get_field_objects( $post_id = false, $format_value = true, $load_value = true ) {
257
	
258
	// global
259
	global $wpdb;
260
	
261
	
262
	// filter post_id
263
	$post_id = acf_get_valid_post_id( $post_id );
0 ignored issues
show
Documentation introduced by
$post_id is of type boolean, but the function expects a integer.

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...
264
265
266
	// vars
267
	$meta = array();
268
	$fields = array();
269
	
270
				
271
	// get field_names
272
	if( is_numeric($post_id) ) {
273
		
274
		$meta = get_post_meta( $post_id );
275
	
276
	} elseif( strpos($post_id, 'user_') !== false ) {
277
		
278
		$user_id = (int) str_replace('user_', '', $post_id);
279
		
280
		$meta = get_user_meta( $user_id );
281
		
282
	} elseif( strpos($post_id, 'comment_') !== false ) {
283
		
284
		$comment_id = (int) str_replace('comment_', '', $post_id);
285
		
286
		$meta = get_comment_meta( $comment_id );
287
		
288
	} else {
289
		
290
		$rows = $wpdb->get_results($wpdb->prepare(
291
			"SELECT option_name, option_value FROM $wpdb->options WHERE option_name LIKE %s OR option_name LIKE %s",
292
			$post_id . '_%' ,
293
			'_' . $post_id . '_%' 
294
		), ARRAY_A);
295
		
296
		if( !empty($rows) ) {
297
			
298
			foreach( $rows as $row ) {
299
				
300
				$meta[ $row['option_name'] ][] = $row['option_value'];
301
				
302
			}
303
			
304
		}
305
		
306
	}
307
	
308
	
309
	// bail early if no meta
310
	if( empty($meta) ) {
311
		
312
		return false;
313
		
314
	}
315
	
316
	
317
	// populate vars
318
	foreach( $meta as $k => $v ) {
319
		
320
		// Hopefuly improve efficiency: bail early if $k does start with an '_'
321
		if( $k[0] === '_' ) {
322
			
323
			continue;
324
			
325
		}
326
		
327
		
328
		// does a field key exist for this value?
329
		if( !array_key_exists("_{$k}", $meta) ) {
330
			
331
			continue;
332
			
333
		}
334
		
335
		
336
		// get field
337
		$field_key = $meta["_{$k}"][0];
338
		$field = acf_get_field( $field_key );
339
		
340
		
341
		// bail early if not a parent field
342
		if( !$field || acf_is_sub_field($field) ) {
343
			
344
			continue;
345
			
346
		}
347
		
348
		
349
		// load value
350
		if( $load_value ) {
351
		
352
			$field['value'] = acf_get_value( $post_id, $field );
353
			
354
		}
355
		
356
		
357
		// format value
358
		if( $format_value ) {
359
			
360
			// get value for field
361
			$field['value'] = acf_format_value( $field['value'], $post_id, $field );
362
			
363
		}
364
		
365
					
366
		// append to $value
367
		$fields[ $field['name'] ] = $field;
368
		
369
	}
370
 	
0 ignored issues
show
Coding Style introduced by
There is some trailing whitespace on this line which should be avoided as per coding-style.
Loading history...
371
 	 	
0 ignored issues
show
Coding Style introduced by
There is some trailing whitespace on this line which should be avoided as per coding-style.
Loading history...
372
	// no value
373
	if( empty($fields) ) {
374
	
375
		return false;
376
	
377
	}
378
	
379
	
380
	// return
381
	return $fields;
382
}
383
384
385
/*
386
*  have_rows
387
*
388
*  This function will instantiate a global variable containing the rows of a repeater or flexible content field,
389
*  afterwhich, it will determine if another row exists to loop through
390
*
391
*  @type	function
392
*  @date	2/09/13
393
*  @since	4.3.0
394
*
395
*  @param	$field_name (string) the field name
396
*  @param	$post_id (mixed) the post_id of which the value is saved against
397
*  @return	(boolean)
398
*/
399
400
function have_rows( $selector, $post_id = false ) {
401
	
402
	// vars
403
	$row = array();
404
	$new_parent_loop = false;
405
	$new_child_loop = false;
406
	$sub_field = false;
407
	$sub_exists = false;
408
	
409
	
410
	// reference
411
	$_post_id = $post_id;
412
	
413
	
414
	// filter post_id
415
	$post_id = acf_get_valid_post_id( $post_id );
0 ignored issues
show
Documentation introduced by
$post_id is of type boolean, but the function expects a integer.

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...
416
	
417
	
418
	// empty?
419
	if( empty($GLOBALS['acf_field']) ) {
420
		
421
		// reset
422
		reset_rows( true );
423
		
424
		
425
		// create a new loop
426
		$new_parent_loop = true;
427
	
428
	} else {
429
		
430
		// vars
431
		$row = end( $GLOBALS['acf_field'] );
432
		$prev = prev( $GLOBALS['acf_field'] );
433
		$change = false;
434
		
435
		
436
		// detect change
437
		if( $post_id != $row['post_id'] ) {
438
			
439
			$change = 'post_id';
440
				
441
		} elseif( $selector != $row['selector'] ) {
442
			
443
			$change = 'selector';
444
				
445
		}
446
		
447
		
448
		// attempt to find sub field
449 View Code Duplication
		if( $change ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $change of type string|false is loosely compared to true; this is ambiguous if the string can be empty. You might want to explicitly use !== false instead.

In PHP, under loose comparison (like ==, or !=, or switch conditions), values of different types might be equal.

For string values, the empty string '' is a special case, in particular the following results might be unexpected:

''   == false // true
''   == null  // true
'ab' == false // false
'ab' == null  // false

// It is often better to use strict comparison
'' === false // false
'' === null  // false
Loading history...
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...
450
			
451
			$sub_field = acf_get_sub_field($selector, $row['field']);
452
			
453
			if( $sub_field ) {
454
				
455
				$sub_exists = isset($row['value'][ $row['i'] ][ $sub_field['key'] ]);
456
				
457
			}
458
			
459
		}
460
		
461
		
462
		// If post_id has changed, this is most likely an archive loop
463
		if( $change == 'post_id' ) {
464
			
465 View Code Duplication
			if( empty($_post_id) && $sub_exists ) {
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...
466
				
467
				// case: Change in $post_id was due to this being a nested loop and not specifying the $post_id
468
				// action: move down one level into a new loop
469
				$new_child_loop = true;
470
			
471
			} elseif( $prev && $prev['post_id'] == $post_id ) {
472
				
473
				// case: Change in $post_id was due to a nested loop ending
474
				// action: move up one level through the loops
475
				reset_rows();
476
			
477
			} else {
478
				
479
				// case: Chang in $post_id is the most obvious, used in an WP_Query loop with multiple $post objects
480
				// action: leave this current loop alone and create a new parent loop
481
				$new_parent_loop = true;
482
				
483
			}
484
			
485
		} elseif( $change == 'selector' ) {
486
			
487 View Code Duplication
			if( $prev && $prev['selector'] == $selector && $prev['post_id'] == $post_id ) {
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...
488
				
489
				// case: Change in $field_name was due to a nested loop ending
490
				// action: move up one level through the loops
491
				reset_rows();
492
				
493
			} elseif( $sub_exists ) {
494
				
495
				// case: Change in $field_name was due to this being a nested loop
496
				// action: move down one level into a new loop
497
				$new_child_loop = true;
498
				
499
			} else {
500
				
501
				// case: Chang in $field_name is the most obvious, this is a new loop for a different field within the $post
502
				// action: leave this current loop alone and create a new parent loop
503
				$new_parent_loop = true;
504
				
505
			}
506
			
507
		}
508
		
509
	}
510
	
511
	
512
	if( $new_parent_loop ) {
513
		
514
		// vars
515
		$field = get_field_object( $selector, $post_id, false );
516
		$value = acf_extract_var( $field, 'value' );
517
		
518
		
519
		// add row
520
		$GLOBALS['acf_field'][] = array(
521
			'selector'	=> $selector,
522
			'name'		=> $field['name'], // used by update_sub_field
523
			'value'		=> $value,
524
			'field'		=> $field,
525
			'i'			=> -1,
526
			'post_id'	=> $post_id,
527
		);
528
		
529
	} elseif( $new_child_loop ) {
530
		
531
		// vars
532
		$value = $row['value'][ $row['i'] ][ $sub_field['key'] ];
533
		
534
		$GLOBALS['acf_field'][] = array(
535
			'selector'	=> $selector,
536
			'name'		=> $row['name'] . '_' . $row['i'], // used by update_sub_field
537
			'value'		=> $value,
538
			'field'		=> $sub_field,
539
			'i'			=> -1,
540
			'post_id'	=> $post_id,
541
		);
542
		
543
	}	
544
	
545
	
546
	// update vars
547
	$row = end( $GLOBALS['acf_field'] );
548
	
549
	
550
	
551
	// return true if next row exists
552
	if( is_array($row['value']) && array_key_exists($row['i']+1, $row['value']) ) {
553
		
554
		return true;
555
		
556
	}
557
	
558
	
559
	// no next row!
560
	reset_rows();
561
	
562
	
563
	// return
564
	return false;
565
  
566
}
567
568
569
/*
570
*  the_row
571
*
572
*  This function will progress the global repeater or flexible content value 1 row
573
*
574
*  @type	function
575
*  @date	2/09/13
576
*  @since	4.3.0
577
*
578
*  @param	N/A
579
*  @return	(array) the current row data
580
*/
581
582
function the_row( $format = false ) {
583
	
584
	// vars
585
	$depth = count($GLOBALS['acf_field']) - 1;
586
587
	
588
	// increase i of current row
589
	$GLOBALS['acf_field'][ $depth ]['i']++;
590
	
591
	
592
	// return
593
	return get_row( $format );
594
	
595
}
596
597
function get_row( $format = false ) {
598
	
599
	// vars
600
	$row = acf_get_row();
601
	
602
	
603
	// bail early if no row
604
	if( !$row ) {
605
		
606
		return false;
607
		
608
	}
609
	
610
	
611
	// get value
612
	$value = $row['value'][ $row['i'] ];
613
	
614
	
615
	// format
616
	if( $format ) {
617
		
618
		// temp wrap value in array
619
		$value = array( $value );
620
		
621
		// format the value (1 row of data)
622
		$value = acf_format_value( $value, $row['post_id'], $row['field'] );
623
		
624
		// extract value from array
625
		$value = $value[0];
626
		
627
	}
628
	
629
	
630
	// return
631
	return $value;
632
	
633
}
634
635
function acf_get_row() {
636
	
637
	// check and return row
638
	if( !empty($GLOBALS['acf_field']) ) {
639
		
640
		return end( $GLOBALS['acf_field'] );
641
		
642
	}
643
	
644
	
645
	// return
646
	return false;
647
	
648
}
649
650
function get_row_index() {
651
	
652
	// vars
653
	$row = acf_get_row();
654
	
655
	
656
	// bail early if no row
657
	if( !$row ) return 0;
658
	
659
	
660
	// return
661
	return $row['i'] + 1;
662
	
663
}
664
665
666
/*
667
*  reset_rows
668
*
669
*  This function will find the current loop and unset it from the global array.
670
*  To bo used when loop finishes or a break is used
671
*
672
*  @type	function
673
*  @date	26/10/13
674
*  @since	5.0.0
675
*
676
*  @param	$hard_reset (boolean) completely wipe the global variable, or just unset the active row
677
*  @return	(boolean)
678
*/
679
680
function reset_rows( $hard_reset = false ) {
681
	
682
	// completely destroy?
683
	if( $hard_reset )
684
	{
685
		$GLOBALS['acf_field'] = array();
686
	}
687
	else
688
	{
689
		// vars
690
		$depth = count( $GLOBALS['acf_field'] ) - 1;
691
		
692
		
693
		// remove
694
		unset( $GLOBALS['acf_field'][$depth] );
695
		
696
		
697
		// refresh index
698
		$GLOBALS['acf_field'] = array_values($GLOBALS['acf_field']);
699
	}
700
	
701
	
702
	// return
703
	return true;
704
	
705
	
706
}
707
708
709
/*
710
*  has_sub_field()
711
*
712
*  This function is used inside a while loop to return either true or false (loop again or stop).
713
*  When using a repeater or flexible content field, it will loop through the rows until 
714
*  there are none left or a break is detected
715
*
716
*  @type	function
717
*  @since	1.0.3
718
*  @date	29/01/13
719
*
720
*  @param	$field_name (string) the field name
721
*  @param	$post_id (mixed) the post_id of which the value is saved against
722
*  @return	(boolean)
723
*/
724
725
function has_sub_field( $field_name, $post_id = false ) {
726
	
727
	// vars
728
	$r = have_rows( $field_name, $post_id );
729
	
730
	
731
	// if has rows, progress through 1 row for the while loop to work
732
	if( $r ) {
733
		
734
		the_row();
735
		
736
	}
737
	
738
	
739
	// return
740
	return $r;
741
	
742
}
743
744
function has_sub_fields( $field_name, $post_id = false ) {
745
	
746
	return has_sub_field( $field_name, $post_id );
747
	
748
}
749
750
751
/*
752
*  get_sub_field()
753
*
754
*  This function is used inside a 'has_sub_field' while loop to return a sub field value
755
*
756
*  @type	function
757
*  @since	1.0.3
758
*  @date	29/01/13
759
*
760
*  @param	$field_name (string) the field name
761
*  @return	(mixed)
762
*/
763
764
function get_sub_field( $selector, $format_value = true ) {
765
	
766
	// vars
767
	$row = acf_get_row();
768
	
769
	
770
	// bail early if no row
771
	if( !$row ) {
772
		
773
		return false;
774
		
775
	}
776
	
777
	
778
	// attempt to find sub field
779
	$sub_field = acf_get_sub_field($selector, $row['field']);
780
	
781
	
782
	// update selector
783
	if( $sub_field ) {
784
		
785
		$selector = $sub_field['key'];
786
		
787
	} else {
788
		
789
		$format_value = false;
790
		
791
	}
792
	
793
	
794
	// return value
795
	if( isset($row['value'][ $row['i'] ][ $selector ]) ) {
796
		
797
		// get
798
		$value = $row['value'][ $row['i'] ][ $selector ];
799
		
800
		
801
		// format
802
		if( $format_value ) {
803
			
804
			$value = acf_format_value( $value, $row['post_id'], $sub_field );
805
			
806
		}
807
		
808
		
809
		// return 
810
		return $value;
811
		
812
	}
813
	
814
	
815
	// return false
816
	return false;
817
}
818
819
820
/*
821
*  the_sub_field()
822
*
823
*  This function is the same as echo get_sub_field
824
*
825
*  @type	function
826
*  @since	1.0.3
827
*  @date	29/01/13
828
*
829
*  @param	$field_name (string) the field name
830
*  @return	n/a
831
*/
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...
832
833
function the_sub_field( $field_name, $format_value = true ) {
834
	
835
	$value = get_sub_field( $field_name, $format_value );
836
	
837
	if( is_array($value) ) {
838
		
839
		$value = implode(', ',$value);
840
		
841
	}
842
	
843
	echo $value;
844
}
845
846
847
/*
848
*  get_sub_field_object()
849
*
850
*  This function is used inside a 'has_sub_field' while loop to return a sub field object
851
*
852
*  @type	function
853
*  @since	3.5.8.1
854
*  @date	29/01/13
855
*
856
*  @param	$child_name (string) the field name
857
*  @return	(array)	
858
*/
859
860
function get_sub_field_object( $selector, $format_value = true, $load_value = true ) {
861
	
862
	// vars
863
	$row = acf_get_row();
864
	
865
	
866
	// bail early if no row
867
	if( !$row ) {
868
		
869
		return false;
870
		
871
	}
872
873
	
874
	// vars
875
	$parent = $row['field'];
876
877
	
878
	// get sub field
879
	$sub_field = acf_get_sub_field( $selector, $parent );
880
	
881
	
882
	// bail early if no sub field
883
	if( !$sub_field ) {
884
		
885
		return false;
886
		
887
	}
888
	
889
	
890
	// load value
891
	if( $load_value ) {
892
	
893
		$sub_field['value'] = get_sub_field( $sub_field['name'], $format_value );
894
		
895
	}
896
	
897
	
898
	// return
899
	return $sub_field;
900
	
901
}
902
903
904
/*
905
*  get_row_layout()
906
*
907
*  This function will return a string representation of the current row layout within a 'have_rows' loop
908
*
909
*  @type	function
910
*  @since	3.0.6
911
*  @date	29/01/13
912
*
913
*  @param	n/a
914
*  @return	(string)
915
*/
916
917
function get_row_layout() {
918
	
919
	// vars
920
	$row = get_row();
921
	
922
	
923
	// return
924
	if( isset($row['acf_fc_layout']) ) {
925
		
926
		return $row['acf_fc_layout'];
927
		
928
	}
929
	
930
	
931
	// return
932
	return false;
933
	
934
}
935
936
937
/*
938
*  acf_shortcode()
939
*
940
*  This function is used to add basic shortcode support for the ACF plugin
941
*  eg. [acf field="heading" post_id="123" format_value="1"]
942
*
943
*  @type	function
944
*  @since	1.1.1
945
*  @date	29/01/13
946
*
947
*  @param	$field (string) the field name or key
948
*  @param	$post_id (mixed) the post_id of which the value is saved against
949
*  @param	$format_value (boolean) whether or not to format the field value
950
*  @return	(string)
951
*/
952
953
function acf_shortcode( $atts )
954
{
955
	// extract attributs
956
	extract( shortcode_atts( array(
0 ignored issues
show
Bug introduced by
shortcode_atts(array('fi...value' => true), $atts) cannot be passed to extract() as the parameter $var_array expects a reference.
Loading history...
957
		'field'			=> '',
958
		'post_id'		=> false,
959
		'format_value'	=> true
960
	), $atts ) );
961
	
962
	
963
	// get value and return it
964
	$value = get_field( $field, $post_id, $format_value );
965
	
966
	
967
	if( is_array($value) )
968
	{
969
		$value = @implode( ', ', $value );
970
	}
971
	
972
	
973
	return $value;
974
}
975
add_shortcode( 'acf', 'acf_shortcode' );
976
977
978
/*
979
*  acf_form_head()
980
*
981
*  This function is placed at the very top of a template (before any HTML is rendered) and saves the $_POST data sent by acf_form.
982
*
983
*  @type	function
984
*  @since	1.1.4
985
*  @date	29/01/13
986
*
987
*  @param	n/a
988
*  @return	n/a
989
*/
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...
990
991
function acf_form_head() {
992
	
993
	// verify nonce
994
	if( acf_verify_nonce('acf_form') ) {
995
		
996
		// validate data
997
	    if( acf_validate_save_post(true) ) {
998
	    	
999
	    	// form
1000
	    	$GLOBALS['acf_form'] = acf_extract_var($_POST, '_acf_form');
1001
	    	$GLOBALS['acf_form'] = @json_decode(base64_decode($GLOBALS['acf_form']), true);
1002
	    	
1003
	    	
1004
	    	// validate
1005
	    	if( empty($GLOBALS['acf_form']) ) {
1006
		    	
1007
		    	return;
1008
		    	
1009
	    	}
1010
	    	
1011
	    	
1012
	    	// vars
1013
	    	$post_id = acf_maybe_get( $GLOBALS['acf_form'], 'post_id', 0 );
1014
			
1015
			
1016
			// allow for custom save
1017
			$post_id = apply_filters('acf/pre_save_post', $post_id, $GLOBALS['acf_form']);
1018
			
1019
			
1020
			// save
1021
			acf_save_post( $post_id );
1022
			
1023
			
1024
			// vars
1025
			$return = acf_maybe_get( $GLOBALS['acf_form'], 'return', '' );
1026
			
1027
			
1028
			// redirect
1029
			if( $return ) {
1030
				
1031
				// update %placeholders%
1032
				$return = str_replace('%post_url%', get_permalink($post_id), $return);
1033
				
1034
				
1035
				// redirect
1036
				wp_redirect( $return );
1037
				exit;
1038
			}
1039
			
1040
		}
1041
		// if
1042
		
1043
	}
1044
	// if
1045
	
1046
	
1047
	// load acf scripts
1048
	acf_enqueue_scripts();
1049
	
1050
}
1051
1052
1053
/*
1054
*  _validate_save_post
1055
*
1056
*  description
1057
*
1058
*  @type	function
1059
*  @date	16/06/2014
1060
*  @since	5.0.0
1061
*
1062
*  @param	$post_id (int)
1063
*  @return	$post_id (int)
1064
*/
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...
1065
1066
add_action('acf/validate_save_post', '_validate_save_post');
1067
1068
function _validate_save_post() {
1069
	
1070
	// save post_title
1071 View Code Duplication
	if( isset($_POST['acf']['_post_title']) ) {
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...
1072
		
1073
		// get field
1074
		$field = acf_get_valid_field(array(
0 ignored issues
show
Documentation introduced by
array('name' => '_post_t...t', 'required' => true) is of type array<string,string|bool...,"required":"boolean"}>, 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...
1075
			'name'		=> '_post_title',
1076
			'label'		=> 'Title',
1077
			'type'		=> 'text',
1078
			'required'	=> true
1079
		));
1080
		
1081
		
1082
		// validate
1083
		acf_validate_value( $_POST['acf']['_post_title'], $field, "acf[_post_title]" );
1084
	
1085
	}
1086
	
1087
}
1088
1089
1090
/*
1091
*  _acf_pre_save_post
1092
*
1093
*  This filter will save post data for the acf_form function
1094
*
1095
*  @type	filter
1096
*  @date	17/01/2014
1097
*  @since	5.0.0
1098
*
1099
*  @param	$post_id (int)
1100
*  @return	$post_id (int)
1101
*/
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...
1102
1103
add_filter('acf/pre_save_post', '_acf_pre_save_post', 0, 2);
1104
1105
function _acf_pre_save_post( $post_id, $form ) {
1106
	
1107
	// vars
1108
	$save = array(
1109
		'ID' => 0
1110
	);
1111
	
1112
	
1113
	// determine save data
1114
	if( is_numeric($post_id) ) {
1115
		
1116
		// update post
1117
		$save['ID'] = $post_id;
1118
		
1119
	} elseif( $post_id == 'new_post' ) {
1120
		
1121
		// new post
1122
		$form['new_post'] = acf_parse_args( $form['new_post'], array(
1123
			'post_type' 	=> 'post',
1124
			'post_status'	=> 'draft',
1125
		));
1126
		
1127
		
1128
		// merge in new post data
1129
		$save = array_merge($save, $form['new_post']);
1130
				
1131
	} else {
1132
		
1133
		// not post
1134
		return $post_id;
1135
		
1136
	}
1137
	
1138
	
1139
	// save post_title
1140
	if( isset($_POST['acf']['_post_title']) ) {
1141
		
1142
		$save['post_title'] = acf_extract_var($_POST['acf'], '_post_title');
1143
	
1144
	}
1145
	
1146
	
1147
	// save post_content
1148
	if( isset($_POST['acf']['_post_content']) ) {
1149
		
1150
		$save['post_content'] = acf_extract_var($_POST['acf'], '_post_content');
1151
		
1152
	}
1153
	
1154
	
1155
	// validate
1156
	if( count($save) == 1 ) {
1157
		
1158
		return $post_id;
1159
		
1160
	}
1161
	
1162
	
1163
	if( $save['ID'] ) {
1164
		
1165
		wp_update_post( $save );
1166
		
1167
	} else {
1168
		
1169
		$post_id = wp_insert_post( $save );
1170
		
1171
	}
1172
		
1173
	
1174
	// return
1175
	return $post_id;
1176
	
1177
}
1178
1179
1180
/*
1181
*  acf_form()
1182
*
1183
*  This function is used to create an ACF form.
1184
*
1185
*  @type	function
1186
*  @since	1.1.4
1187
*  @date	29/01/13
1188
*
1189
*  @param	array		$options: an array containing many options to customize the form
1190
*			string		+ post_id: post id to get field groups from and save data to. Default is false
0 ignored issues
show
Bug introduced by
There is no parameter named $options:. Was it maybe removed?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function.

Consider the following example. The parameter $italy is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $island
 * @param array $italy
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was removed, but the annotation was not.

Loading history...
1191
*			array		+ field_groups: an array containing field group ID's. If this option is set, 
1192
*						  the post_id will not be used to dynamically find the field groups
1193
*			boolean		+ form: display the form tag or not. Defaults to true
1194
*			array		+ form_attributes: an array containg attributes which will be added into the form tag
1195
*			string		+ return: the return URL
1196
*			string		+ html_before_fields: html inside form before fields
1197
*			string		+ html_after_fields: html inside form after fields
1198
*			string		+ submit_value: value of submit button
1199
*			string		+ updated_message: default updated message. Can be false					 
1200
*
1201
*  @return	N/A
1202
*/
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...
1203
1204
function acf_form( $args = array() ) {
1205
	
1206
	// vars
1207
	$url = acf_get_current_url();
1208
	
1209
	
1210
	// defaults
1211
	$args = wp_parse_args( $args, array(
1212
		'id'					=> 'acf-form',
1213
		'post_id'				=> false,
1214
		'new_post'				=> false,
1215
		'field_groups'			=> false,
1216
		'fields'				=> false,
1217
		'post_title'			=> false,
1218
		'post_content'			=> false,
1219
		'form'					=> true,
1220
		'form_attributes'		=> array(),
1221
		'return'				=> add_query_arg( 'updated', 'true', $url ),
1222
		'html_before_fields'	=> '',
1223
		'html_after_fields'		=> '',
1224
		'submit_value'			=> __("Update", 'acf'),
1225
		'updated_message'		=> __("Post updated", 'acf'),
1226
		'label_placement'		=> 'top',
1227
		'instruction_placement'	=> 'label',
1228
		'field_el'				=> 'div',
1229
		'uploader'				=> 'wp'
1230
	));
1231
	
1232
	$args['form_attributes'] = wp_parse_args( $args['form_attributes'], array(
1233
		'id'					=> 'post',
1234
		'class'					=> '',
1235
		'action'				=> '',
1236
		'method'				=> 'post',
1237
	));
1238
	
1239
	
1240
	// filter post_id
1241
	$args['post_id'] = acf_get_valid_post_id( $args['post_id'] );
1242
	
1243
	
1244
	// load values from this post
1245
	$post_id = $args['post_id'];
1246
	
1247
	
1248
	// new post?
1249
	if( $post_id == 'new_post' ) {
1250
		
1251
		// dont load values
1252
		$post_id = false;
1253
		
1254
		
1255
		// new post defaults
1256
		$args['new_post'] = acf_parse_args( $args['new_post'], array(
1257
			'post_type' 	=> 'post',
1258
			'post_status'	=> 'draft',
1259
		));
1260
		
1261
	}
1262
	
1263
	
1264
	// attributes
1265
	$args['form_attributes']['class'] .= ' acf-form';
1266
	
1267
	
1268
	// vars
1269
	$field_groups = array();
1270
	$fields = array();
1271
	
1272
	
1273
	// post_title
1274 View Code Duplication
	if( $args['post_title'] ) {
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...
1275
		
1276
		$fields[] = acf_get_valid_field(array(
0 ignored issues
show
Documentation introduced by
array('name' => '_post_t...'', 'required' => true) is of type array<string,?,{"name":"...,"required":"boolean"}>, 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...
1277
			'name'		=> '_post_title',
1278
			'label'		=> 'Title',
1279
			'type'		=> 'text',
1280
			'value'		=> $post_id ? get_post_field('post_title', $post_id) : '',
1281
			'required'	=> true
1282
		));
1283
		
1284
	}
1285
	
1286
	
1287
	// post_content
1288
	if( $args['post_content'] ) {
1289
		
1290
		$fields[] = acf_get_valid_field(array(
0 ignored issues
show
Documentation introduced by
array('name' => '_post_c...ntent', $post_id) : '') is of type array<string,?,{"name":"...:"string","value":"?"}>, 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...
1291
			'name'		=> '_post_content',
1292
			'label'		=> 'Content',
1293
			'type'		=> 'wysiwyg',
1294
			'value'		=> $post_id ? get_post_field('post_content', $post_id) : ''
1295
		));
1296
		
1297
	}
1298
	
1299
	
1300
	// specific fields
1301
	if( $args['fields'] ) {
1302
		
1303
		foreach( $args['fields'] as $selector ) {
1304
			
1305
			// append field ($strict = false to allow for better compatibility with field names)
1306
			$fields[] = acf_maybe_get_field( $selector, $post_id, false );
1307
			
1308
		}
1309
		
1310
	} elseif( $args['field_groups'] ) {
1311
		
1312
		foreach( $args['field_groups'] as $selector ) {
1313
		
1314
			$field_groups[] = acf_get_field_group( $selector );
1315
			
1316
		}
1317
		
1318
	} elseif( $args['post_id'] == 'new_post' ) {
1319
		
1320
		$field_groups = acf_get_field_groups(array(
0 ignored issues
show
Documentation introduced by
array('post_type' => $ar...ew_post']['post_type']) is of type array<string,?,{"post_type":"?"}>, 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...
1321
			'post_type' => $args['new_post']['post_type']
1322
		));
1323
	
1324
	} else {
1325
		
1326
		$field_groups = acf_get_field_groups(array(
0 ignored issues
show
Documentation introduced by
array('post_id' => $args['post_id']) is of type array<string,?,{"post_id":"?"}>, 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...
1327
			'post_id' => $args['post_id']
1328
		));
1329
		
1330
	}
1331
	
1332
	
1333
	//load fields based on field groups
1334
	if( !empty($field_groups) ) {
1335
		
1336
		foreach( $field_groups as $field_group ) {
1337
			
1338
			$field_group_fields = acf_get_fields( $field_group );
1339
			
1340
			if( !empty($field_group_fields) ) {
1341
				
1342
				foreach( array_keys($field_group_fields) as $i ) {
1343
					
1344
					$fields[] = acf_extract_var($field_group_fields, $i);
1345
				}
1346
				
1347
			}
1348
		
1349
		}
1350
	
1351
	}
1352
	
1353
	
1354
	// updated message
1355
	if( !empty($_GET['updated']) && $args['updated_message'] ) {
1356
	
1357
		echo '<div id="message" class="updated"><p>' . $args['updated_message'] . '</p></div>';
1358
		
1359
	}
1360
	
1361
	
1362
	// uploader (always set incase of multiple forms on the page)
1363
	acf_update_setting('uploader', $args['uploader']);
1364
	
1365
	
1366
	// display form
1367
	if( $args['form'] ): ?>
1368
	
1369
	<form <?php acf_esc_attr_e( $args['form_attributes']); ?>>
1370
	
1371
	<?php endif; 
1372
		
1373
		
1374
	// render post data
1375
	acf_form_data(array( 
1376
		'post_id'	=> $args['post_id'], 
1377
		'nonce'		=> 'acf_form' 
1378
	));
1379
	
1380
	?>
1381
	<div class="acf-hidden">
1382
		<?php acf_hidden_input(array( 'name' => '_acf_form', 'value' => base64_encode(json_encode($args)) )); ?>
1383
	</div>
1384
	<div class="acf-fields acf-form-fields -<?php echo $args['label_placement']; ?>">
1385
	
1386
		<?php
1387
		
1388
		// html before fields
1389
		echo $args['html_before_fields'];
1390
		
1391
		
1392
		// render
1393
		acf_render_fields( $post_id, $fields, $args['field_el'], $args['instruction_placement'] );
1394
		
1395
		
1396
		// html after fields
1397
		echo $args['html_after_fields'];
1398
		
1399
		?>
1400
	
1401
	</div><!-- acf-form-fields -->
1402
	<?php if( $args['form'] ): ?>
1403
	
1404
	<!-- Submit -->
1405
	<div class="acf-form-submit">
1406
	
1407
		<input type="submit" class="button button-primary button-large" value="<?php echo $args['submit_value']; ?>" />
1408
		<span class="acf-spinner"></span>
1409
		
1410
	</div>
1411
	<!-- / Submit -->
1412
	
1413
	</form>
1414
	<?php endif;
1415
}
1416
1417
1418
/*
1419
*  update_field()
1420
*
1421
*  This function will update a value in the database
1422
*
1423
*  @type	function
1424
*  @since	3.1.9
1425
*  @date	29/01/13
1426
*
1427
*  @param	$selector (string) the field name or key
1428
*  @param	$value (mixed) the value to save in the database
1429
*  @param	$post_id (mixed) the post_id of which the value is saved against
1430
*  @return	(boolean)
1431
*/
1432
1433
function update_field( $selector, $value, $post_id = false ) {
1434
	
1435
	// filter post_id
1436
	$post_id = acf_get_valid_post_id( $post_id );
0 ignored issues
show
Documentation introduced by
$post_id is of type boolean, but the function expects a integer.

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...
1437
	
1438
	
1439
	// get field
1440
	$field = acf_maybe_get_field( $selector, $post_id );
1441
	
1442
	
1443
	// create dummy field
1444 View Code Duplication
	if( !$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...
1445
	{
1446
		$field = acf_get_valid_field(array(
0 ignored issues
show
Documentation introduced by
array('name' => $selecto...y' => '', 'type' => '') is of type array<string,?,{"name":"...ring","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...
1447
			'name'	=> $selector,
1448
			'key'	=> '',
1449
			'type'	=> '',
1450
		));
1451
	}
1452
	
1453
	
1454
	// save
1455
	return acf_update_value( $value, $post_id, $field );
1456
		
1457
}
1458
1459
1460
/*
1461
*  update_sub_field
1462
*
1463
*  This function will update a value of a sub field in the database
1464
*
1465
*  @type	function
1466
*  @date	2/04/2014
1467
*  @since	5.0.0
1468
*
1469
*  @param	$selector (mixed) the sub field name or key, or an array of ancestors
1470
*  @param	$value (mixed) the value to save in the database
1471
*  @param	$post_id (mixed) the post_id of which the value is saved against
1472
*  @return	(boolean)
1473
*/
1474
1475
function update_sub_field( $selector, $value, $post_id = false ) {
1476
	
1477
	// filter post_id
1478
	$post_id = acf_get_valid_post_id( $post_id );
0 ignored issues
show
Documentation introduced by
$post_id is of type boolean, but the function expects a integer.

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...
1479
	
1480
	
1481
	// vars
1482
	$field = false;
1483
	
1484
	
1485
	// within a have_rows loop
1486
	if( is_string($selector) ) {
1487
		
1488
		// get current row
1489
		$row = acf_get_row();
1490
		
1491
		
1492
		// override $post_id
1493
		$post_id = $row['post_id'];
1494
		
1495
		
1496
		// get sub field
1497
		$field = get_sub_field_object( $selector, false, false );
1498
		
1499
		
1500
		// create dummy field
1501 View Code Duplication
		if( !$field ) {
0 ignored issues
show
Bug Best Practice introduced by
The expression $field of type array is implicitly converted to a boolean; are you sure this is intended? If so, consider using empty($expr) instead to make it clear that you intend to check for an array without elements.

This check marks implicit conversions of arrays to boolean values in a comparison. While in PHP an empty array is considered to be equal (but not identical) to false, this is not always apparent.

Consider making the comparison explicit by using empty(..) or ! empty(...) instead.

Loading history...
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...
1502
		
1503
			$field = acf_get_valid_field(array(
0 ignored issues
show
Documentation introduced by
array('name' => $selecto...y' => '', 'type' => '') is of type array<string,string,{"na...ring","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...
1504
				'name'	=> $selector,
1505
				'key'	=> '',
1506
				'type'	=> '',
1507
			));
1508
			
1509
		}
1510
		
1511
		
1512
		// update name
1513
		$field['name'] = "{$row['name']}_{$row['i']}_{$field['name']}";
1514
		
1515
		
1516
	} elseif( is_array($selector) ) {
1517
		
1518
		// validate
1519
		if( count($selector) < 3 ) {
1520
			
1521
			return false;
1522
			
1523
		}
1524
		
1525
		
1526
		// vars
1527
		$parent_name = acf_extract_var( $selector, 0 );
1528
		
1529
		
1530
		// load parent
1531
		$field = acf_maybe_get_field( $parent_name, $post_id );
1532
		
1533
		
1534
		// add to name
1535
		$name = $field['name'];
1536
		
1537
		
1538
		// sub fields
1539
		foreach( $selector as $s ) {
1540
				
1541
			if( is_numeric($s) ) {
1542
				
1543
				// get row index
1544
				$row_i = intval($s) - 1;
1545
				
1546
				// add to name
1547
				$name .= "_{$row_i}";
1548
				
1549
			} else {
1550
				
1551
				// update parent
1552
				$field = acf_get_sub_field( $s, $field );
1553
				
1554
				
1555
				// create dummy field
1556
				if( !$field ) {
1557
				
1558
					$field = acf_get_valid_field(array(
0 ignored issues
show
Documentation introduced by
array('name' => $s, 'key' => '', 'type' => '') is of type array<string,?,{"name":"...ring","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...
1559
						'name'	=> $s,
1560
						'key'	=> '',
1561
						'type'	=> '',
1562
					));
1563
					
1564
				}
1565
				
1566
				
1567
				// add to name
1568
				$name .= "_{$field['name']}";
1569
				
1570
			}
1571
			// if
1572
			
1573
		}
1574
		// foreach
1575
		
1576
		
1577
		// update name
1578
		$field['name'] = $name;
1579
				
1580
				
1581
	}
1582
	
1583
	
1584
	// delete
1585
	if( $value === null ) {
1586
		
1587
		return acf_delete_value( $post_id, $field );
1588
		
1589
	}
1590
	
1591
	
1592
	// update
1593
	return acf_update_value( $value, $post_id, $field );
1594
		
1595
}
1596
1597
1598
/*
1599
*  delete_field()
1600
*
1601
*  This function will remove a value from the database
1602
*
1603
*  @type	function
1604
*  @since	3.1.9
1605
*  @date	29/01/13
1606
*
1607
*  @param	$selector (string) the field name or key
1608
*  @param	$post_id (mixed) the post_id of which the value is saved against
1609
*  @return	(boolean)
1610
*/
1611
1612
function delete_field( $selector, $post_id = false ) {
1613
	
1614
	// filter post_id
1615
	$post_id = acf_get_valid_post_id( $post_id );
0 ignored issues
show
Documentation introduced by
$post_id is of type boolean, but the function expects a integer.

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...
1616
	
1617
	
1618
	// get field
1619
	$field = acf_maybe_get_field( $selector, $post_id );
1620
	
1621
	
1622
	// delete
1623
	return acf_delete_value( $post_id, $field );
1624
	
1625
}
1626
1627
1628
/*
1629
*  delete_sub_field
1630
*
1631
*  This function will delete a value of a sub field in the database
1632
*
1633
*  @type	function
1634
*  @date	2/04/2014
1635
*  @since	5.0.0
1636
*
1637
*  @param	$selector (mixed) the sub field name or key, or an array of ancestors
1638
*  @param	$value (mixed) the value to save in the database
1639
*  @param	$post_id (mixed) the post_id of which the value is saved against
1640
*  @return	(boolean)
1641
*/
1642
1643
function delete_sub_field( $selector, $post_id = false ) {
1644
	
1645
	return update_sub_field( $selector, null, $post_id );
1646
		
1647
}
1648
1649
1650
/*
1651
*  add_row
1652
*
1653
*  description
1654
*
1655
*  @type	function
1656
*  @date	16/10/2015
1657
*  @since	5.2.3
1658
*
1659
*  @param	$post_id (int)
1660
*  @return	$post_id (int)
1661
*/
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...
1662
1663
function add_row( $selector, $value, $post_id = false ) {
1664
	
1665
	// filter post_id
1666
	$post_id = acf_get_valid_post_id( $post_id );
0 ignored issues
show
Documentation introduced by
$post_id is of type boolean, but the function expects a integer.

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...
1667
	
1668
	
1669
	// get field
1670
	$field = acf_maybe_get_field( $selector, $post_id );
1671
	
1672
	
1673
	// bail early if no field
1674
	if( !$field ) {
1675
		
1676
		return false;
1677
		
1678
	}
1679
	
1680
	
1681
	// get row count
1682
	$i = (int) acf_get_metadata( $post_id, $field['name'] );
1683
	
1684
	
1685
	// if no rows, save this field via update_field() so that the reference field is created
1686
	if( !$i ) {
1687
		
1688
		// acf_update_value will return boolean, simply convert this to int for 1 | 0 (the number of rows!)
1689
		return (int) acf_update_value( array( $value ), $post_id, $field );
1690
		
1691
	}
1692
	
1693
	
1694
	// increase $i
1695
	$i++;
1696
	
1697
	
1698
	// update meta
1699
	$result = acf_update_metadata( $post_id, $field['name'], $i );
0 ignored issues
show
Unused Code introduced by
$result 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...
1700
	
1701
	
1702
	// update sub fields
1703
	if( $value ) {
1704
		
1705 View Code Duplication
		foreach( $value as $k => $v ) {
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...
1706
		
1707
			update_sub_field( array( $field['key'], $i, $k ), $v, $post_id );
1708
			
1709
		}
1710
	
1711
	}
1712
	
1713
	
1714
	// return
1715
	return $i;
1716
	
1717
}
1718
1719
1720
/*
1721
*  update_row
1722
*
1723
*  description
1724
*
1725
*  @type	function
1726
*  @date	19/10/2015
1727
*  @since	5.2.3
1728
*
1729
*  @param	$post_id (int)
1730
*  @return	$post_id (int)
1731
*/
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...
1732
1733
function update_row( $selector, $row = 1, $value = false, $post_id = false ) {
1734
	
1735
	// bail early if no value
1736
	if( empty($value) ) {
1737
		
1738
		return false;
1739
		
1740
	}
1741
	
1742
	
1743
	// filter post_id
1744
	$post_id = acf_get_valid_post_id( $post_id );
0 ignored issues
show
Documentation introduced by
$post_id is of type boolean, but the function expects a integer.

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...
1745
	
1746
	
1747
	// get field
1748
	$field = acf_maybe_get_field( $selector, $post_id );
1749
	
1750
	
1751
	// bail early if no field
1752
	if( !$field ) return false;
1753
	
1754
	
1755
	// update sub fields
1756 View Code Duplication
	foreach( $value as $k => $v ) {
0 ignored issues
show
Bug introduced by
The expression $value of type boolean is not traversable.
Loading history...
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...
1757
		
1758
		update_sub_field( array( $field['key'], $row, $k ), $v, $post_id );
1759
		
1760
	}
1761
	
1762
	
1763
	// return
1764
	return true;
1765
	
1766
}
1767
1768
1769
/*
1770
*  delete_row
1771
*
1772
*  description
1773
*
1774
*  @type	function
1775
*  @date	19/10/2015
1776
*  @since	5.2.3
1777
*
1778
*  @param	$post_id (int)
1779
*  @return	$post_id (int)
1780
*/
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...
1781
1782
function delete_row( $selector, $row = 1, $post_id = false ) {
0 ignored issues
show
Unused Code introduced by
The parameter $row is not used and could be removed.

This check looks from parameters that have been defined for a function or method, but which are not used in the method body.

Loading history...
1783
	
1784
	// filter post_id
1785
	$post_id = acf_get_valid_post_id( $post_id );
0 ignored issues
show
Documentation introduced by
$post_id is of type boolean, but the function expects a integer.

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...
1786
	
1787
	
1788
	// get field
1789
	$field = acf_maybe_get_field( $selector, $post_id );
1790
	
1791
	
1792
	// bail early if no field
1793
	if( !$field ) {
1794
		
1795
		return false;
1796
		
1797
	}
1798
	
1799
	
1800
	// get value
1801
	$rows = acf_get_value( $post_id, $field );
1802
	
1803
	
1804
	// bail early if no value
1805
	if( empty($rows) ) {
1806
		
1807
		return false;
1808
		
1809
	}
1810
	
1811
	
1812
	// deincrement
1813
	if( $row = count($rows) ) {
1814
		
1815
		acf_update_metadata( $post_id, $field['name'], $row-1 );
1816
		
1817
	}
1818
	
1819
	
1820
	// update sub field values
1821 View Code Duplication
	foreach( $rows[0] as $k => $v ) {
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...
1822
		
1823
		update_sub_field( array( $field['key'], $row, $k ), null, $post_id );
1824
		
1825
	}
1826
	
1827
	
1828
	// return
1829
	return true;
1830
	
1831
}
1832
1833
1834
/*
1835
*  create_field()
1836
*
1837
*  This function will creat the HTML for a field
1838
*
1839
*  @type	function
1840
*  @since	4.0.0
1841
*  @date	17/03/13
1842
*
1843
*  @param	array	$field - an array containing all the field attributes
1844
*
1845
*  @return	N/A
1846
*/
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...
1847
1848
function create_field( $field ) {
1849
1850
	acf_render_field( $field );
0 ignored issues
show
Documentation introduced by
$field is of type array, 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...
1851
}
1852
1853
function render_field( $field ) {
1854
1855
	acf_render_field( $field );
1856
}
1857
1858
1859
/*
1860
*  acf_convert_field_names_to_keys()
1861
*
1862
*  Helper for the update_field function
1863
*
1864
*  @type	function
1865
*  @since	4.0.0
1866
*  @date	17/03/13
1867
*
1868
*  @param	array	$value: the value returned via get_field
1869
*  @param	array	$field: the field or layout to find sub fields from
0 ignored issues
show
Documentation introduced by
There is no parameter named $value:. Did you maybe mean $value?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
1870
*
0 ignored issues
show
Documentation introduced by
There is no parameter named $field:. Did you maybe mean $field?

This check looks for PHPDoc comments describing methods or function parameters that do not exist on the corresponding method or function. It has, however, found a similar but not annotated parameter which might be a good fit.

Consider the following example. The parameter $ireland is not defined by the method finale(...).

/**
 * @param array $germany
 * @param array $ireland
 */
function finale($germany, $island) {
    return "2:1";
}

The most likely cause is that the parameter was changed, but the annotation was not.

Loading history...
1871
*  @return	N/A
1872
*/
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...
1873
1874
function acf_convert_field_names_to_keys( $value, $field ) {
1875
	
1876
	// only if $field has sub fields
1877
	if( !isset($field['sub_fields']) ) {
1878
		
1879
		return $value;
1880
		
1881
	}
1882
	
1883
1884
	// define sub field keys
1885
	$sub_fields = array();
1886
	if( $field['sub_fields'] ) {
1887
		
1888
		foreach( $field['sub_fields'] as $sub_field ) {
1889
			
1890
			$sub_fields[ $sub_field['name'] ] = $sub_field;
1891
			
1892
		}
1893
		
1894
	}
1895
	
1896
	
1897
	// loop through the values and format the array to use sub field keys
1898
	if( is_array($value) ) {
1899
		
1900
		foreach( $value as $row_i => $row) {
1901
			
1902
			if( $row ) {
1903
				
1904
				foreach( $row as $sub_field_name => $sub_field_value ) {
1905
					
1906
					// sub field must exist!
1907
					if( !isset($sub_fields[ $sub_field_name ]) ) {
1908
						
1909
						continue;
1910
						
1911
					}
1912
					
1913
					
1914
					// vars
1915
					$sub_field = $sub_fields[ $sub_field_name ];
1916
					$sub_field_value = acf_convert_field_names_to_keys( $sub_field_value, $sub_field );
1917
					
1918
					
1919
					// set new value
1920
					$value[$row_i][ $sub_field['key'] ] = $sub_field_value;
1921
					
1922
					
1923
					// unset old value
1924
					unset( $value[$row_i][$sub_field_name] );
1925
						
1926
					
1927
				}
1928
				// foreach( $row as $sub_field_name => $sub_field_value )
1929
				
1930
			}
1931
			// if( $row )
1932
			
1933
		}
1934
		// foreach( $value as $row_i => $row)
1935
		
1936
	}
1937
	// if( $value )
1938
	
1939
	
1940
	// return
1941
	return $value;
1942
1943
}
1944
1945
1946
/*
1947
*  register_field_group
1948
*
1949
*  description
1950
*
1951
*  @type	function
1952
*  @date	11/03/2014
1953
*  @since	5.0.0
1954
*
1955
*  @param	$post_id (int)
1956
*  @return	$post_id (int)
1957
*/
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...
1958
1959
function register_field_group( $field_group ) {
1960
	
1961
	// add local
1962
	acf_add_local_field_group( $field_group );
1963
	
1964
}
1965
1966
1967
/*
1968
*  Depreceated Functions
1969
*
1970
*  These functions are outdated
1971
*
1972
*  @type	function
1973
*  @date	4/03/2014
1974
*  @since	1.0.0
1975
*
1976
*  @param	n/a
1977
*  @return	n/a
1978
*/
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...
1979
1980
function reset_the_repeater_field() {
1981
	
1982
	return reset_rows();
1983
	
1984
}
1985
1986
function the_repeater_field( $field_name, $post_id = false ) {
1987
	
1988
	return has_sub_field( $field_name, $post_id );
1989
	
1990
}
1991
1992
function the_flexible_field( $field_name, $post_id = false ) {
1993
	
1994
	return has_sub_field( $field_name, $post_id );
1995
	
1996
}
1997
1998
function acf_filter_post_id( $post_id ) {
1999
	
2000
	return acf_get_valid_post_id( $post_id );
2001
	
2002
}
2003
2004
?>
2005