PluginProbe
Advanced Custom Fields (ACF®) / 5.7.10
Advanced Custom Fields (ACF®) v5.7.10
6.8.9 6.8.8 6.8.7 6.8.6 6.8.5 6.8.4 6.8.3 6.8.2 6.8.1 5.8.5 5.8.6 5.8.7 5.8.8 5.8.9 5.9.0 5.9.1 5.9.2 5.9.3 5.9.4 5.9.5 5.9.6 5.9.7 5.9.8 5.9.9 6.0.0 All 230 releases
advanced-custom-fields / includes / api / api-field.php
api-field.php
2,177 lines 38.3 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 /*
4 * acf_is_field_key
5 *
6 * This function will return true or false for the given $field_key parameter
7 *
8 * @type function
9 * @date 6/12/2013
10 * @since 5.0.0
11 *
12 * @param $field_key (string)
13 * @return (boolean)
14 */
15
16 function acf_is_field_key( $key = '' ) {
17
18 // bail early if not string
19 if( !is_string($key) ) return false;
20
21
22 // bail early if is numeric (could be numeric string '123')
23 if( is_numeric($key) ) return false;
24
25
26 // default - starts with 'field_'
27 if( substr($key, 0, 6) === 'field_' ) return true;
28
29
30 // special - allow local field key to be any string
31 if( acf_is_local_field_key($key) ) return true;
32
33
34 // return
35 return false;
36
37 }
38
39
40 /*
41 * acf_get_valid_field
42 *
43 * This function will fill in any missing keys to the $field array making it valid
44 *
45 * @type function
46 * @date 28/09/13
47 * @since 5.0.0
48 *
49 * @param $field (array)
50 * @return $field (array)
51 */
52
53 function acf_get_valid_field( $field = false ) {
54
55 // $field must be an array
56 if( !is_array($field) ) $field = array();
57
58
59 // bail ealry if already valid
60 if( !empty($field['_valid']) ) return $field;
61
62
63 // defaults
64 $field = wp_parse_args($field, array(
65 'ID' => 0,
66 'key' => '',
67 'label' => '',
68 'name' => '',
69 'prefix' => '',
70 'type' => 'text',
71 'value' => null,
72 'menu_order' => 0,
73 'instructions' => '',
74 'required' => 0,
75 'id' => '',
76 'class' => '',
77 'conditional_logic' => 0,
78 'parent' => 0,
79 'wrapper' => array(),
80 '_name' => '',
81 '_prepare' => 0,
82 '_valid' => 0,
83 ));
84
85 $field['wrapper'] = wp_parse_args($field['wrapper'], array(
86 'width' => '',
87 'class' => '',
88 'id' => ''
89 ));
90
91
92 // _name
93 $field['_name'] = $field['name'];
94
95
96 // field is now valid
97 $field['_valid'] = 1;
98
99
100 /**
101 * Filters the $field array to validate settings.
102 *
103 * @date 12/02/2014
104 * @since 5.0.0
105 *
106 * @param array $field The field array.
107 */
108 $field = apply_filters( "acf/validate_field/type={$field['type']}", $field );
109 $field = apply_filters( "acf/validate_field", $field );
110
111
112 // translate
113 $field = acf_translate_field( $field );
114
115
116 // return
117 return $field;
118
119 }
120
121
122 /*
123 * acf_translate_field
124 *
125 * This function will translate field's settings
126 *
127 * @type function
128 * @date 8/03/2016
129 * @since 5.3.2
130 *
131 * @param $field (array)
132 * @return $field
133 */
134
135 function acf_translate_field( $field ) {
136
137 // vars
138 $l10n = acf_get_setting('l10n');
139 $l10n_textdomain = acf_get_setting('l10n_textdomain');
140
141
142 // if
143 if( $l10n && $l10n_textdomain ) {
144
145 // translate
146 $field['label'] = acf_translate( $field['label'] );
147 $field['instructions'] = acf_translate( $field['instructions'] );
148
149
150 /**
151 * Filters the $field array to translate strings.
152 *
153 * @date 12/02/2014
154 * @since 5.0.0
155 *
156 * @param array $field The field array.
157 */
158 $field = apply_filters( "acf/translate_field/type={$field['type']}", $field );
159 $field = apply_filters( "acf/translate_field", $field );
160
161 }
162
163
164 // return
165 return $field;
166
167 }
168
169
170 /*
171 * acf_clone_field
172 *
173 * This function will allow customization to a field when it is cloned
174 * Cloning a field is the act of mimicing another. Some settings may need to be altered
175 *
176 * @type function
177 * @date 8/03/2016
178 * @since 5.3.2
179 *
180 * @param $field (array)
181 * @return $field
182 */
183
184 function acf_clone_field( $field, $clone_field ) {
185
186 // add reference
187 $field['_clone'] = $clone_field['key'];
188
189
190 /**
191 * Filters the $field array when it is being cloned.
192 *
193 * @date 12/02/2014
194 * @since 5.0.0
195 *
196 * @param array $field The field array.
197 * @param array $clone_field The clone field array.
198 */
199 $field = apply_filters( "acf/clone_field/type={$field['type']}", $field, $clone_field );
200 $field = apply_filters( "acf/clone_field", $field, $clone_field );
201
202
203 // return
204 return $field;
205
206 }
207
208
209 /*
210 * acf_prepare_field
211 *
212 * This function will prepare the field for input
213 *
214 * @type function
215 * @date 12/02/2014
216 * @since 5.0.0
217 *
218 * @param $field (array)
219 * @return $field (array)
220 */
221
222 function acf_prepare_field( $field ) {
223
224 // bail early if already prepared
225 if( $field['_prepare'] ) return $field;
226
227
228 // key overrides name
229 if( $field['key'] ) $field['name'] = $field['key'];
230
231
232 // prefix
233 if( $field['prefix'] ) $field['name'] = $field['prefix'] . '[' . $field['name'] . ']';
234
235
236 // field is now prepared
237 $field['_prepare'] = 1;
238
239
240 /**
241 * Filters the $field array.
242 *
243 * Allows developers to modify field settings or return false to remove field.
244 *
245 * @date 12/02/2014
246 * @since 5.0.0
247 *
248 * @param array $field The field array.
249 */
250 $field = apply_filters( "acf/prepare_field/type={$field['type']}", $field );
251 $field = apply_filters( "acf/prepare_field/name={$field['_name']}", $field );
252 $field = apply_filters( "acf/prepare_field/key={$field['key']}", $field );
253 $field = apply_filters( "acf/prepare_field", $field );
254
255
256 // bail ealry if no field
257 if( !$field ) return false;
258
259
260 // id attr is generated from name
261 $field['id'] = acf_idify( $field['name'] );
262
263
264 // return
265 return $field;
266
267 }
268
269
270 /*
271 * acf_is_sub_field
272 *
273 * This function will return true if the field is a sub field
274 *
275 * @type function
276 * @date 17/05/2014
277 * @since 5.0.0
278 *
279 * @param $field (array)
280 * @return (boolean)
281 */
282
283 function acf_is_sub_field( $field ) {
284
285 // local field uses a field instead of ID
286 if( acf_is_field_key($field['parent']) ) return true;
287
288
289 // attempt to load parent field
290 if( acf_get_field($field['parent']) ) return true;
291
292
293 // return
294 return false;
295
296 }
297
298
299 /*
300 * acf_get_field_label
301 *
302 * This function will return the field label with appropriate required label
303 *
304 * @type function
305 * @date 4/11/2013
306 * @since 5.0.0
307 *
308 * @param $field (array)
309 * @return $label (string)
310 */
311
312 function acf_get_field_label( $field, $context = '' ) {
313
314 // vars
315 $label = $field['label'];
316
317
318 // show (no label) when editing field
319 if( $context == 'admin' && $label === '' ) {
320 $label = __('(no label)', 'acf');
321 }
322
323
324 // required
325 if( $field['required'] ) {
326 $label .= ' <span class="acf-required">*</span>';
327 }
328
329
330 // filter for 3rd party customization
331 $label = apply_filters("acf/get_field_label", $label, $field);
332
333
334 // return
335 return $label;
336
337 }
338
339 function acf_the_field_label( $field ) {
340
341 echo acf_get_field_label( $field );
342
343 }
344
345
346 /*
347 * acf_render_fields
348 *
349 * This function will render an array of fields for a given form.
350 * Becasue the $field's values have not been loaded yet, this function will also load values
351 *
352 * @type function
353 * @date 8/10/13
354 * @since 5.0.0
355 *
356 * @param $post_id (int) the post to load values from
357 * @param $fields (array) the fields to render
358 * @param $el (string) the wrapping element type
359 * @param $instruction (int) the instructions position
360 * @return n/a
361 */
362
363 function acf_render_fields( $fields, $post_id = 0, $el = 'div', $instruction = 'label' ) {
364
365 // parameter order changed in ACF 5.6.9
366 if( is_array($post_id) ) {
367 $args = func_get_args();
368 $fields = $args[1];
369 $post_id = $args[0];
370 }
371
372 // filter
373 $fields = apply_filters('acf/pre_render_fields', $fields, $post_id);
374
375 // bail early if no fields
376 if( empty($fields) ) return;
377
378 // loop
379 foreach( $fields as $field ) {
380
381 // bail ealry if no field
382 if( !$field ) continue;
383
384 // load value
385 if( $field['value'] === null ) {
386 $field['value'] = acf_get_value( $post_id, $field );
387 }
388
389 // render
390 acf_render_field_wrap( $field, $el, $instruction );
391 }
392
393 // action
394 do_action( 'acf/render_fields', $fields, $post_id );
395 }
396
397
398 /*
399 * acf_render_field
400 *
401 * This function will render a field input
402 *
403 * @type function
404 * @date 28/09/13
405 * @since 5.0.0
406 *
407 * @param $field (array)
408 * @return n/a
409 */
410
411 function acf_render_field( $field = false ) {
412
413 // get valid field
414 $field = acf_get_valid_field( $field );
415
416
417 // prepare field for input
418 $field = acf_prepare_field( $field );
419
420
421 // bail ealry if no field
422 if( !$field ) return;
423
424
425 /**
426 * Fires when rendering a field.
427 *
428 * @date 12/02/2014
429 * @since 5.0.0
430 *
431 * @param array $field The field array.
432 */
433 do_action( "acf/render_field/type={$field['type']}", $field );
434 do_action( "acf/render_field/name={$field['_name']}", $field );
435 do_action( "acf/render_field/key={$field['key']}", $field );
436 do_action( "acf/render_field", $field );
437 }
438
439
440 /*
441 * acf_render_field_wrap
442 *
443 * This function will render the complete HTML wrap with label & field
444 *
445 * @type function
446 * @date 28/09/13
447 * @since 5.0.0
448 *
449 * @param $field (array) must be a valid ACF field array
450 * @param $el (string) modifys the rendered wrapping elements. Default to 'div', but can be 'tr', 'ul', 'ol', 'dt' or custom
451 * @param $instruction (string) specifys the placement of the instructions. Default to 'label', but can be 'field'
452 * @param $atts (array) an array of custom attributes to render on the $el
453 * @return N/A
454 */
455
456 function acf_render_field_wrap( $field, $el = 'div', $instruction = 'label' ) {
457
458 // get valid field
459 $field = acf_get_valid_field( $field );
460
461
462 // prepare field for input
463 $field = acf_prepare_field( $field );
464
465
466 // bail ealry if no field
467 if( !$field ) return;
468
469
470 // elements
471 $elements = array(
472 'div' => 'div',
473 'tr' => 'td',
474 'ul' => 'li',
475 'ol' => 'li',
476 'dl' => 'dt',
477 'td' => 'div' // special case for sub field!
478 );
479
480
481 // vars
482 $el = isset($elements[ $el ]) ? $el : 'div';
483 $el2 = $elements[ $el ];
484 $show_label = ($el !== 'td') ? true : false;
485
486
487 // wrapper
488 $wrapper = array(
489 'id' => '',
490 'class' => 'acf-field',
491 'width' => '',
492 'style' => '',
493 'data-name' => $field['_name'],
494 'data-type' => $field['type'],
495 'data-key' => '',
496 );
497
498
499 // add required
500 if( $field['required'] ) {
501 $wrapper['data-required'] = 1;
502 }
503
504
505 // add type
506 $wrapper['class'] .= " acf-field-{$field['type']}";
507
508
509 // add key
510 if( $field['key'] ) {
511
512 $wrapper['class'] .= " acf-field-{$field['key']}";
513 $wrapper['data-key'] = $field['key'];
514
515 }
516
517
518 // replace
519 $wrapper['class'] = str_replace('_', '-', $wrapper['class']);
520 $wrapper['class'] = str_replace('field-field-', 'field-', $wrapper['class']);
521
522
523 // wrap classes have changed (5.2.7)
524 if( acf_get_compatibility('field_wrapper_class') ) {
525
526 $wrapper['class'] .= " field_type-{$field['type']}";
527
528 if( $field['key'] ) {
529
530 $wrapper['class'] .= " field_key-{$field['key']}";
531
532 }
533
534 }
535
536
537 // merge in atts
538 $wrapper = acf_merge_atts( $wrapper, $field['wrapper'] );
539
540
541 // add width
542 $width = (int) acf_extract_var( $wrapper, 'width' );
543
544 if( $el == 'tr' || $el == 'td' ) {
545
546 // do nothing
547
548 } elseif( $width > 0 && $width < 100 ) {
549
550 $wrapper['data-width'] = $width;
551 $wrapper['style'] .= " width:{$width}%;";
552
553 }
554
555
556 // remove empty attributes
557 $wrapper = array_filter($wrapper);
558
559
560 // conditional logic
561 if( !empty($field['conditional_logic']) ) {
562 $field['conditions'] = $field['conditional_logic'];
563 }
564
565 // conditions
566 if( !empty($field['conditions']) ) {
567 $wrapper['data-conditions'] = $field['conditions'];
568 }
569
570
571 // html
572 ?>
573 <<?php echo $el; ?> <?php acf_esc_attr_e($wrapper); ?>>
574 <?php if( $show_label ): ?>
575 <<?php echo $el2; ?> class="acf-label"><?php
576
577 acf_render_field_label( $field );
578
579 if( $instruction == 'label' ) acf_render_field_instructions( $field );
580
581 ?></<?php echo $el2; ?>>
582 <?php endif; ?>
583 <<?php echo $el2; ?> class="acf-input">
584 <?php acf_render_field( $field ); ?>
585 <?php if( $instruction == 'field' ) acf_render_field_instructions( $field ); ?>
586 </<?php echo $el2; ?>>
587 </<?php echo $el; ?>>
588 <?php
589
590 }
591
592
593 /**
594 * acf_render_field_label
595 *
596 * This function will maybe output the field's label
597 *
598 * @date 19/9/17
599 * @since 5.6.3
600 *
601 * @param array $field
602 * @return n/a
603 */
604
605 function acf_render_field_label( $field ) {
606
607 // vars
608 $label = acf_get_field_label( $field );
609
610
611 // check
612 if( $label ) {
613 echo '<label' . ($field['id'] ? ' for="' . esc_attr($field['id']) . '"' : '' ) . '>' . acf_esc_html($label) . '</label>';
614 }
615
616 }
617
618
619 /* depreciated since 5.6.5 */
620 function acf_render_field_wrap_label( $field ) {
621 acf_render_field_label( $field );
622 }
623
624
625 /**
626 * acf_render_field_instructions
627 *
628 * This function will maybe output the field's instructions
629 *
630 * @date 19/9/17
631 * @since 5.6.3
632 *
633 * @param array $field
634 * @return n/a
635 */
636
637 function acf_render_field_instructions( $field ) {
638
639 // vars
640 $instructions = $field['instructions'];
641
642
643 // check
644 if( $instructions ) {
645 echo '<p class="description">' . acf_esc_html($instructions) . '</p>';
646 }
647
648 }
649
650
651 /* depreciated since 5.6.5 */
652 function acf_render_field_wrap_description( $field ) {
653 acf_render_field_instructions( $field );
654 }
655
656
657 /*
658 * acf_render_field_setting
659 *
660 * This function will render a tr element containing a label and field cell, but also setting the tr data attribute for AJAX
661 *
662 * @type function
663 * @date 28/09/13
664 * @since 5.0.0
665 *
666 * @param $field (array) the origional field being edited
667 * @param $setting (array) the settings field to create
668 * @return n/a
669 */
670
671 function acf_render_field_setting( $field, $setting, $global = false ) {
672
673 // validate
674 $setting = acf_get_valid_field( $setting );
675
676 // custom key and class
677 $setting['wrapper']['data-key'] = $setting['name'];
678 $setting['wrapper']['class'] .= ' acf-field-setting-' . $setting['name'];
679
680 // context
681 if( !$global ) {
682 $setting['wrapper']['data-setting'] = $field['type'];
683 }
684
685 // copy across prefix
686 $setting['prefix'] = $field['prefix'];
687
688 // attempt find value
689 if( $setting['value'] === null ) {
690
691 // name
692 if( isset($field[ $setting['name'] ]) ) {
693 $setting['value'] = $field[ $setting['name'] ];
694
695 // default
696 } elseif( isset($setting['default_value']) ) {
697 $setting['value'] = $setting['default_value'];
698 }
699 }
700
701 // append (used by JS to join settings)
702 if( isset($setting['_append']) ) {
703 $setting['wrapper']['data-append'] = $setting['_append'];
704 }
705
706 // render
707 acf_render_field_wrap( $setting, 'tr', 'label' );
708 }
709
710
711 /*
712 * acf_get_fields
713 *
714 * This function will return an array of fields for the given $parent
715 *
716 * @type function
717 * @date 30/09/13
718 * @since 5.0.0
719 *
720 * @param $parent (array) a field or field group
721 * @return (array)
722 */
723
724 function acf_get_fields( $parent = false ) {
725
726 // allow $parent to be a field group ID
727 if( !is_array($parent) ) {
728
729 $parent = acf_get_field_group( $parent );
730
731 }
732
733
734 // bail early if no parent
735 if( !$parent ) return false;
736
737
738 // vars
739 $fields = array();
740
741
742 // try JSON before DB to save query time
743 if( acf_have_local_fields( $parent['key'] ) ) {
744
745 $fields = acf_get_local_fields( $parent['key'] );
746
747 } else {
748
749 $fields = acf_get_fields_by_id( $parent['ID'] );
750
751 }
752
753
754 // filter
755 $fields = apply_filters('acf/load_fields', $fields, $parent);
756 $fields = apply_filters('acf/get_fields', $fields, $parent);
757
758
759 // return
760 return $fields;
761
762 }
763
764
765 /*
766 * acf_get_fields_by_id
767 *
768 * This function will get all fields for the given parent
769 *
770 * @type function
771 * @date 27/02/2014
772 * @since 5.0.0
773 *
774 * @param $post_id (int)
775 * @return $fields (array)
776 */
777
778 function acf_get_fields_by_id( $parent_id = 0 ) {
779
780 // bail early if no ID
781 if( !$parent_id ) return false;
782
783
784 // vars
785 $fields = array();
786 $post_ids = array();
787 $cache_key = "get_fields/ID={$parent_id}";
788
789
790 // check cache for child ids
791 if( acf_isset_cache($cache_key) ) {
792
793 $post_ids = acf_get_cache($cache_key);
794
795 // query DB for child ids
796 } else {
797
798 // query
799 $posts = get_posts(array(
800 'posts_per_page' => -1,
801 'post_type' => 'acf-field',
802 'orderby' => 'menu_order',
803 'order' => 'ASC',
804 'suppress_filters' => true, // DO NOT allow WPML to modify the query
805 'post_parent' => $parent_id,
806 'post_status' => 'publish, trash', // 'any' won't get trashed fields
807 'update_post_meta_cache' => false,
808 'update_post_term_cache' => false
809 ));
810
811
812 // loop
813 if( $posts ) {
814
815 foreach( $posts as $post ) {
816
817 $post_ids[] = $post->ID;
818
819 }
820
821 }
822
823
824 // update cache
825 acf_set_cache($cache_key, $post_ids);
826
827 }
828
829
830 // bail early if no children
831 if( empty($post_ids) ) return false;
832
833
834 // load fields
835 foreach( $post_ids as $post_id ) {
836
837 $fields[] = acf_get_field( $post_id );
838
839 }
840
841
842 // return
843 return $fields;
844
845 }
846
847
848 /*
849 * acf_get_field
850 *
851 * This function will return a field for the given selector.
852 *
853 * @type function
854 * @date 30/09/13
855 * @since 5.0.0
856 *
857 * @param $selector (mixed) identifyer of field. Can be an ID, key, name or post object
858 * @param $db_only (boolean) return $field in it's raw form without filters or cache
859 * @return $field (array)
860 */
861
862 function acf_get_field( $selector = null, $db_only = false ) {
863
864 // vars
865 $field = false;
866 $type = 'ID';
867
868
869 // ID
870 if( is_numeric($selector) ) {
871
872 // do nothing
873
874 // object
875 } elseif( is_object($selector) ) {
876
877 $selector = $selector->ID;
878
879 // string
880 } elseif( is_string($selector) ) {
881
882 $type = acf_is_field_key($selector) ? 'key' : 'name';
883
884 // other
885 } else {
886
887 return false;
888
889 }
890
891
892 // return early if cache is found
893 $cache_key = "get_field/{$type}={$selector}";
894
895 if( !$db_only && acf_isset_cache($cache_key) ) {
896
897 return acf_get_cache($cache_key);
898
899 }
900
901
902 // ID
903 if( $type == 'ID' ) {
904
905 $field = _acf_get_field_by_id( $selector, $db_only );
906
907 // key
908 } elseif( $type == 'key' ) {
909
910 $field = _acf_get_field_by_key( $selector, $db_only );
911
912 // name (rare case)
913 } else {
914
915 $field = _acf_get_field_by_name( $selector, $db_only );
916
917 }
918
919
920 // bail early if no field
921 if( !$field ) return false;
922
923
924 // validate
925 $field = acf_get_valid_field( $field );
926
927
928 // set prefix (acf fields save with prefix 'acf')
929 $field['prefix'] = 'acf';
930
931
932 // bail early if db only value (no need to update cache)
933 if( $db_only ) return $field;
934
935
936 /**
937 * Filters the $field array after it has been loaded.
938 *
939 * @date 12/02/2014
940 * @since 5.0.0
941 *
942 * @param array $field The field array.
943 */
944 $field = apply_filters( "acf/load_field/type={$field['type']}", $field );
945 $field = apply_filters( "acf/load_field/name={$field['_name']}", $field );
946 $field = apply_filters( "acf/load_field/key={$field['key']}", $field );
947 $field = apply_filters( "acf/load_field", $field );
948
949
950 // update cache
951 // - Use key instead of ID for best compatibility (not all fields exist in the DB)
952 $cache_key = acf_set_cache("get_field/key={$field['key']}", $field);
953
954
955 // update cache reference
956 // - allow cache to return if using an ID selector
957 acf_set_cache_reference("get_field/ID={$field['ID']}", $cache_key);
958
959
960 // return
961 return $field;
962
963 }
964
965
966 /*
967 * _acf_get_field_by_id
968 *
969 * This function will get a field via its ID
970 *
971 * @type function
972 * @date 27/02/2014
973 * @since 5.0.0
974 *
975 * @param $post_id (int)
976 * @return $field (array)
977 */
978
979 function _acf_get_field_by_id( $post_id = 0, $db_only = false ) {
980
981 // get post
982 $post = get_post( $post_id );
983
984
985 // bail early if no post, or is not a field
986 if( empty($post) || $post->post_type != 'acf-field' ) return false;
987
988
989 // unserialize
990 $field = maybe_unserialize( $post->post_content );
991
992
993 // update attributes
994 $field['ID'] = $post->ID;
995 $field['key'] = $post->post_name;
996 $field['label'] = $post->post_title;
997 $field['name'] = $post->post_excerpt;
998 $field['menu_order'] = $post->menu_order;
999 $field['parent'] = $post->post_parent;
1000
1001
1002 // override with JSON
1003 if( !$db_only && acf_is_local_field($field['key']) ) {
1004
1005 // load JSON field
1006 $local = acf_get_local_field( $field['key'] );
1007
1008
1009 // override IDs
1010 $local['ID'] = $field['ID'];
1011 $local['parent'] = $field['parent'];
1012
1013
1014 // return
1015 return $local;
1016
1017 }
1018
1019
1020 // return
1021 return $field;
1022
1023 }
1024
1025
1026 /*
1027 * _acf_get_field_by_key
1028 *
1029 * This function will get a field via its key
1030 *
1031 * @type function
1032 * @date 27/02/2014
1033 * @since 5.0.0
1034 *
1035 * @param $key (string)
1036 * @return $field (array)
1037 */
1038
1039 function _acf_get_field_by_key( $key = '', $db_only = false ) {
1040
1041 // try JSON before DB to save query time
1042 if( !$db_only && acf_is_local_field( $key ) ) {
1043
1044 return acf_get_local_field( $key );
1045
1046 }
1047
1048
1049 // vars
1050 $post_id = acf_get_field_id( $key );
1051
1052
1053 // bail early if no post_id
1054 if( !$post_id ) return false;
1055
1056
1057 // return
1058 return _acf_get_field_by_id( $post_id, $db_only );
1059
1060 }
1061
1062
1063 /*
1064 * _acf_get_field_by_name
1065 *
1066 * This function will get a field via its name
1067 *
1068 * @type function
1069 * @date 27/02/2014
1070 * @since 5.0.0
1071 *
1072 * @param $key (string)
1073 * @return $field (array)
1074 */
1075
1076 function _acf_get_field_by_name( $name = '', $db_only = false ) {
1077
1078 // try JSON before DB to save query time
1079 if( !$db_only && acf_is_local_field( $name ) ) {
1080
1081 return acf_get_local_field( $name );
1082
1083 }
1084
1085
1086 // vars
1087 $args = array(
1088 'posts_per_page' => 1,
1089 'post_type' => 'acf-field',
1090 'orderby' => 'menu_order title',
1091 'order' => 'ASC',
1092 'suppress_filters' => false,
1093 'acf_field_name' => $name,
1094 'update_post_meta_cache' => false,
1095 'update_post_term_cache' => false
1096 );
1097
1098
1099 // load posts
1100 $posts = get_posts( $args );
1101
1102
1103 // bail early if no posts
1104 if( empty($posts) ) return false;
1105
1106
1107 // return
1108 return _acf_get_field_by_id( $posts[0]->ID, $db_only );
1109
1110 }
1111
1112
1113 /*
1114 * acf_maybe_get_field
1115 *
1116 * This function will return a field for the given selector.
1117 * It will also review the field_reference to ensure the correct field is returned which makes it useful for the template API
1118 *
1119 * @type function
1120 * @date 4/08/2015
1121 * @since 5.2.3
1122 *
1123 * @param $selector (mixed) identifyer of field. Can be an ID, key, name or post object
1124 * @param $post_id (mixed) the post_id of which the value is saved against
1125 * @param $strict (boolean) if true, return a field only when a field key is found.
1126 * @return $field (array)
1127 */
1128
1129 function acf_maybe_get_field( $selector, $post_id = false, $strict = true ) {
1130
1131 // init
1132 acf_init();
1133
1134
1135 // bail early if is field key
1136 if( acf_is_field_key($selector) ) {
1137
1138 return acf_get_field( $selector );
1139
1140 }
1141
1142
1143 // save selector as field_name (could be sub field name 'images_0_image')
1144 $field_name = $selector;
1145
1146
1147 // get valid post_id
1148 $post_id = acf_get_valid_post_id( $post_id );
1149
1150
1151 // get reference
1152 $field_key = acf_get_reference( $selector, $post_id );
1153
1154
1155 // update selector
1156 if( $field_key ) {
1157
1158 $selector = $field_key;
1159
1160 // bail early if no reference
1161 } elseif( $strict ) {
1162
1163 return false;
1164
1165 }
1166
1167
1168 // get field
1169 $field = acf_get_field( $selector );
1170
1171
1172 // update name
1173 if( $field ) $field['name'] = $field_name;
1174
1175
1176 // return
1177 return $field;
1178
1179 }
1180
1181
1182 /*
1183 * acf_get_field_id
1184 *
1185 * This function will lookup a field's ID from the DB
1186 * Useful for local fields to find DB sibling
1187 *
1188 * @type function
1189 * @date 25/06/2015
1190 * @since 5.2.3
1191 *
1192 * @param $key (string)
1193 * @return $post_id (int)
1194 */
1195
1196 function acf_get_field_id( $key = '' ) {
1197
1198 // vars
1199 $args = array(
1200 'posts_per_page' => 1,
1201 'post_type' => 'acf-field',
1202 'orderby' => 'menu_order title',
1203 'order' => 'ASC',
1204 'suppress_filters' => false,
1205 'acf_field_key' => $key,
1206 'update_post_meta_cache' => false,
1207 'update_post_term_cache' => false
1208 );
1209
1210
1211 // load posts
1212 $posts = get_posts( $args );
1213
1214
1215 // validate
1216 if( empty($posts) ) return 0;
1217
1218
1219 // return
1220 return $posts[0]->ID;
1221
1222 }
1223
1224
1225 /*
1226 * acf_update_field
1227 *
1228 * This function will update a field into the DB.
1229 * The returned field will always contain an ID
1230 *
1231 * @type function
1232 * @date 1/10/13
1233 * @since 5.0.0
1234 *
1235 * @param $field (array)
1236 * @return $field (array)
1237 */
1238
1239 function acf_update_field( $field = false, $specific = false ) {
1240
1241 // $field must be an array
1242 if( !is_array($field) ) return false;
1243
1244
1245 // validate
1246 $field = acf_get_valid_field( $field );
1247
1248
1249 // may have been posted. Remove slashes
1250 $field = wp_unslash( $field );
1251
1252
1253 // parse types (converts string '0' to int 0)
1254 $field = acf_parse_types( $field );
1255
1256
1257 // clean up conditional logic keys
1258 if( !empty($field['conditional_logic']) ) {
1259
1260 // extract groups
1261 $groups = acf_extract_var( $field, 'conditional_logic' );
1262
1263
1264 // clean array
1265 $groups = array_filter($groups);
1266 $groups = array_values($groups);
1267
1268
1269 // clean rules
1270 foreach( array_keys($groups) as $i ) {
1271
1272 $groups[ $i ] = array_filter($groups[ $i ]);
1273 $groups[ $i ] = array_values($groups[ $i ]);
1274
1275 }
1276
1277
1278 // reset conditional logic
1279 $field['conditional_logic'] = $groups;
1280
1281 }
1282
1283
1284 // parent may be a field key
1285 // - lookup parent ID
1286 if( acf_is_field_key($field['parent']) ) {
1287
1288 $field['parent'] = acf_get_field_id( $field['parent'] );
1289
1290 }
1291
1292
1293 /**
1294 * Filters the $field array before it is updated.
1295 *
1296 * @date 12/02/2014
1297 * @since 5.0.0
1298 *
1299 * @param array $field The field array.
1300 */
1301 $field = apply_filters( "acf/update_field/type={$field['type']}", $field );
1302 $field = apply_filters( "acf/update_field/name={$field['_name']}", $field );
1303 $field = apply_filters( "acf/update_field/key={$field['key']}", $field );
1304 $field = apply_filters( "acf/update_field", $field );
1305
1306
1307 // store origional field for return
1308 $data = $field;
1309
1310
1311 // extract some args
1312 $extract = acf_extract_vars($data, array(
1313 'ID',
1314 'key',
1315 'label',
1316 'name',
1317 'prefix',
1318 'value',
1319 'menu_order',
1320 'id',
1321 'class',
1322 'parent',
1323 '_name',
1324 '_prepare',
1325 '_valid',
1326 ));
1327
1328
1329 // serialize for DB
1330 $data = maybe_serialize( $data );
1331
1332
1333 // save
1334 $save = array(
1335 'ID' => $extract['ID'],
1336 'post_status' => 'publish',
1337 'post_type' => 'acf-field',
1338 'post_title' => $extract['label'],
1339 'post_name' => $extract['key'],
1340 'post_excerpt' => $extract['name'],
1341 'post_content' => $data,
1342 'post_parent' => $extract['parent'],
1343 'menu_order' => $extract['menu_order'],
1344 );
1345
1346
1347 // specific
1348 if( acf_is_array($specific) ) {
1349
1350 // append ID
1351 $specific[] = 'ID';
1352
1353
1354 // get sub array
1355 $save = acf_get_sub_array( $save, $specific );
1356
1357 }
1358
1359
1360 // allow fields to contain the same name
1361 add_filter( 'wp_unique_post_slug', 'acf_update_field_wp_unique_post_slug', 999, 6 );
1362
1363
1364 // slash data
1365 // - WP expects all data to be slashed and will unslash it (fixes '\' character issues)
1366 $save = wp_slash( $save );
1367
1368
1369 // update the field and update the ID
1370 if( $field['ID'] ) {
1371
1372 wp_update_post( $save );
1373
1374 } else {
1375
1376 $field['ID'] = wp_insert_post( $save );
1377
1378 }
1379
1380
1381 // clear cache
1382 acf_delete_cache("get_field/key={$field['key']}");
1383
1384
1385 // return
1386 return $field;
1387
1388 }
1389
1390 function acf_update_field_wp_unique_post_slug( $slug, $post_ID, $post_status, $post_type, $post_parent, $original_slug ) {
1391
1392 if( $post_type == 'acf-field' ) {
1393
1394 $slug = $original_slug;
1395
1396 }
1397
1398 // return
1399 return $slug;
1400
1401 }
1402
1403
1404 /*
1405 * acf_duplicate_fields
1406 *
1407 * This function will duplicate an array of fields and update conditional logic references
1408 *
1409 * @type function
1410 * @date 16/06/2014
1411 * @since 5.0.0
1412 *
1413 * @param $fields (array)
1414 * @param $new_parent (int)
1415 * @return n/a
1416 */
1417
1418 function acf_duplicate_fields( $fields, $new_parent = 0 ) {
1419
1420 // bail early if no fields
1421 if( empty($fields) ) return;
1422
1423
1424 // create new field keys (for conditional logic fixes)
1425 foreach( $fields as $field ) {
1426
1427 // ensure a delay for unique ID
1428 usleep(1);
1429
1430 acf_update_setting( 'duplicate_key_' . $field['key'] , uniqid('field_') );
1431
1432 }
1433
1434
1435 // duplicate fields
1436 foreach( $fields as $field ) {
1437
1438 // duplicate
1439 acf_duplicate_field( $field['ID'], $new_parent );
1440
1441 }
1442
1443 }
1444
1445
1446 /*
1447 * acf_duplicate_field
1448 *
1449 * This function will duplicate a field and attach it to the given field group ID
1450 *
1451 * @type function
1452 * @date 17/10/13
1453 * @since 5.0.0
1454 *
1455 * @param $selector (int)
1456 * @param $new_parent (int)
1457 * @return $field (array) the new field
1458 */
1459
1460 function acf_duplicate_field( $selector = 0, $new_parent = 0 ){
1461
1462 // disable filters to ensure ACF loads raw data from DB
1463 acf_disable_filters();
1464
1465
1466 // load the origional field
1467 $field = acf_get_field( $selector );
1468
1469
1470 // bail early if field did not load correctly
1471 if( empty($field) ) {
1472
1473 return false;
1474
1475 }
1476
1477
1478 // update ID
1479 $field['ID'] = false;
1480
1481
1482 // try duplicate keys
1483 $field['key'] = acf_get_setting( 'duplicate_key_' . $field['key'] );
1484
1485
1486 // default key
1487 if( empty($field['key']) ) {
1488
1489 $field['key'] = uniqid('field_');
1490
1491 }
1492
1493
1494 // update parent
1495 if( $new_parent ) {
1496
1497 $field['parent'] = $new_parent;
1498
1499 }
1500
1501
1502 // update conditional logic references (because field keys have changed)
1503 if( !empty($field['conditional_logic']) ) {
1504
1505 // extract groups
1506 $groups = acf_extract_var( $field, 'conditional_logic' );
1507
1508
1509 // loop over groups
1510 foreach( array_keys($groups) as $g ) {
1511
1512 // extract group
1513 $group = acf_extract_var( $groups, $g );
1514
1515
1516 // bail early if empty
1517 if( empty($group) ) {
1518
1519 continue;
1520
1521 }
1522
1523
1524 // loop over rules
1525 foreach( array_keys($group) as $r ) {
1526
1527 // extract rule
1528 $rule = acf_extract_var( $group, $r );
1529
1530
1531 // vars
1532 $new_key = acf_get_setting( 'duplicate_key_' . $rule['field'] );
1533
1534
1535 // update rule with new key
1536 if( $new_key ) {
1537
1538 $rule['field'] = $new_key;
1539
1540 }
1541
1542
1543 // append to group
1544 $group[ $r ] = $rule;
1545
1546 }
1547
1548
1549 // append to groups
1550 $groups[ $g ] = $group;
1551
1552 }
1553
1554
1555 // update conditional logic
1556 $field['conditional_logic'] = $groups;
1557
1558
1559 }
1560
1561
1562 /**
1563 * Filters the $field array after it has been duplicated.
1564 *
1565 * @date 12/02/2014
1566 * @since 5.0.0
1567 *
1568 * @param array $field The field array.
1569 */
1570 $field = apply_filters( "acf/duplicate_field/type={$field['type']}", $field );
1571 $field = apply_filters( "acf/duplicate_field", $field);
1572
1573
1574 // save
1575 return acf_update_field( $field );
1576
1577 }
1578
1579
1580 /*
1581 * acf_delete_field
1582 *
1583 * This function will delete a field from the databse
1584 *
1585 * @type function
1586 * @date 2/10/13
1587 * @since 5.0.0
1588 *
1589 * @param $id (int)
1590 * @return (boolean)
1591 */
1592
1593 function acf_delete_field( $selector = 0 ) {
1594
1595 // disable filters to ensure ACF loads raw data from DB
1596 acf_disable_filters();
1597
1598
1599 // load the origional field gorup
1600 $field = acf_get_field( $selector );
1601
1602
1603 // bail early if field did not load correctly
1604 if( empty($field) ) return false;
1605
1606
1607 // delete field
1608 wp_delete_post( $field['ID'], true );
1609
1610
1611 /**
1612 * Fires immediately after a field has been deleted.
1613 *
1614 * @date 12/02/2014
1615 * @since 5.0.0
1616 *
1617 * @param array $field The field array.
1618 */
1619 do_action( "acf/delete_field/type={$field['type']}", $field );
1620 do_action( "acf/delete_field/name={$field['_name']}", $field );
1621 do_action( "acf/delete_field/key={$field['key']}", $field );
1622 do_action( "acf/delete_field", $field );
1623
1624
1625 // clear cache
1626 acf_delete_cache("get_field/key={$field['key']}");
1627
1628
1629 // return
1630 return true;
1631
1632 }
1633
1634
1635 /*
1636 * acf_trash_field
1637 *
1638 * This function will trash a field from the databse
1639 *
1640 * @type function
1641 * @date 2/10/13
1642 * @since 5.0.0
1643 *
1644 * @param $id (int)
1645 * @return (boolean)
1646 */
1647
1648 function acf_trash_field( $selector = 0 ) {
1649
1650 // disable filters to ensure ACF loads raw data from DB
1651 acf_disable_filters();
1652
1653
1654 // load the origional field gorup
1655 $field = acf_get_field( $selector );
1656
1657
1658 // bail early if field did not load correctly
1659 if( empty($field) ) return false;
1660
1661
1662 // delete field
1663 wp_trash_post( $field['ID'] );
1664
1665
1666 // action for 3rd party customisation
1667 do_action( 'acf/trash_field', $field );
1668
1669
1670 // return
1671 return true;
1672
1673 }
1674
1675
1676 /*
1677 * acf_untrash_field
1678 *
1679 * This function will restore a field from the trash
1680 *
1681 * @type function
1682 * @date 2/10/13
1683 * @since 5.0.0
1684 *
1685 * @param $id (int)
1686 * @return (boolean)
1687 */
1688
1689 function acf_untrash_field( $selector = 0 ) {
1690
1691 // disable filters to ensure ACF loads raw data from DB
1692 acf_disable_filters();
1693
1694
1695 // load the origional field gorup
1696 $field = acf_get_field( $selector );
1697
1698
1699 // bail early if field did not load correctly
1700 if( empty($field) ) return false;
1701
1702
1703 // delete field
1704 wp_untrash_post( $field['ID'] );
1705
1706
1707 // action for 3rd party customisation
1708 do_action( 'acf/untrash_field', $field );
1709
1710
1711 // return
1712 return true;
1713 }
1714
1715
1716 /*
1717 * acf_prepare_fields_for_export
1718 *
1719 * description
1720 *
1721 * @type function
1722 * @date 11/03/2014
1723 * @since 5.0.0
1724 *
1725 * @param $post_id (int)
1726 * @return $post_id (int)
1727 */
1728
1729 function acf_prepare_fields_for_export( $fields = false ) {
1730
1731 // validate
1732 if( empty($fields) ) return $fields;
1733
1734
1735 // format
1736 foreach( array_keys($fields) as $i ) {
1737
1738 // prepare
1739 $fields[ $i ] = acf_prepare_field_for_export( $fields[ $i ] );
1740
1741 }
1742
1743
1744 // return
1745 return $fields;
1746
1747 }
1748
1749
1750 /*
1751 * acf_prepare_field_for_export
1752 *
1753 * description
1754 *
1755 * @type function
1756 * @date 11/03/2014
1757 * @since 5.0.0
1758 *
1759 * @param $post_id (int)
1760 * @return $post_id (int)
1761 */
1762
1763 function acf_prepare_field_for_export( $field ) {
1764
1765 // extract some args
1766 $extract = acf_extract_vars($field, array(
1767 'ID',
1768 'prefix',
1769 'value',
1770 'menu_order',
1771 'id',
1772 'class',
1773 'parent',
1774 '_name',
1775 '_prepare',
1776 '_valid',
1777 ));
1778
1779
1780 /**
1781 * Filters the $field array before being returned to the export tool.
1782 *
1783 * @date 12/02/2014
1784 * @since 5.0.0
1785 *
1786 * @param array $field The field array.
1787 */
1788 $field = apply_filters( "acf/prepare_field_for_export/type={$field['type']}", $field );
1789 $field = apply_filters( "acf/prepare_field_for_export", $field );
1790
1791
1792 // return
1793 return $field;
1794 }
1795
1796
1797 /*
1798 * acf_prepare_fields_for_import
1799 *
1800 * description
1801 *
1802 * @type function
1803 * @date 11/03/2014
1804 * @since 5.0.0
1805 *
1806 * @param $post_id (int)
1807 * @return $post_id (int)
1808 */
1809
1810 function acf_prepare_fields_for_import( $fields = false ) {
1811
1812 // validate
1813 if( empty($fields) ) return array();
1814
1815
1816 // re-index array
1817 $fields = array_values($fields);
1818
1819
1820 // vars
1821 $i = 0;
1822
1823
1824 // format
1825 while( $i < count($fields) ) {
1826
1827 // prepare field
1828 $field = acf_prepare_field_for_import( $fields[ $i ] );
1829
1830
1831 // allow multiple fields to be returned ($field + $sub_fields)
1832 if( !isset($field['key']) && isset($field[0]) ) {
1833
1834 // merge in $field (1 or more fields)
1835 array_splice($fields, $i, 1, $field);
1836
1837 }
1838
1839
1840 // $i
1841 $i++;
1842
1843 }
1844
1845
1846 // filter for 3rd party customization
1847 $fields = apply_filters('acf/prepare_fields_for_import', $fields);
1848
1849
1850 // return
1851 return $fields;
1852
1853 }
1854
1855
1856 /*
1857 * acf_prepare_field_for_import
1858 *
1859 * description
1860 *
1861 * @type function
1862 * @date 11/03/2014
1863 * @since 5.0.0
1864 *
1865 * @param $post_id (int)
1866 * @return $post_id (int)
1867 */
1868
1869 function acf_prepare_field_for_import( $field ) {
1870
1871 // extract some args
1872 $extract = acf_extract_vars($field, array(
1873 'value',
1874 'id',
1875 'class',
1876 '_name',
1877 '_prepare',
1878 '_valid',
1879 ));
1880
1881
1882 /**
1883 * Filters the $field array before being returned to the import tool.
1884 *
1885 * @date 12/02/2014
1886 * @since 5.0.0
1887 *
1888 * @param array $field The field array.
1889 */
1890 $field = apply_filters( "acf/prepare_field_for_import/type={$field['type']}", $field );
1891 $field = apply_filters( "acf/prepare_field_for_import", $field );
1892
1893
1894 // return
1895 return $field;
1896 }
1897
1898
1899 /*
1900 * acf_get_sub_field
1901 *
1902 * This function will return a field for the given selector, and $field (parent).
1903 *
1904 * @type function
1905 * @date 30/09/13
1906 * @since 5.0.0
1907 *
1908 * @param $selector (string)
1909 * @param $field (mixed)
1910 * @return $field (array)
1911 */
1912
1913 function acf_get_sub_field( $selector, $field ) {
1914
1915 // vars
1916 $sub_field = false;
1917
1918
1919 // check sub_fields
1920 if( isset($field['sub_fields']) ) {
1921
1922 // loop
1923 foreach( $field['sub_fields'] as $_sub_field ) {
1924
1925 // check name and key
1926 if( acf_is_field($_sub_field, $selector) ) {
1927
1928 $sub_field = $_sub_field;
1929 break;
1930
1931 }
1932
1933 }
1934
1935 }
1936
1937
1938 /**
1939 * Filters the $sub_field found.
1940 *
1941 * @date 12/02/2014
1942 * @since 5.0.0
1943 *
1944 * @param array $sub_field The found sub field array.
1945 * @param string $selector The selector used to search.
1946 * @param array $field The parent field array.
1947 */
1948 $sub_field = apply_filters( "acf/get_sub_field/type={$field['type']}", $sub_field, $selector, $field );
1949 $sub_field = apply_filters( "acf/get_sub_field", $sub_field, $selector, $field );
1950
1951
1952 // return
1953 return $sub_field;
1954
1955 }
1956
1957
1958 /*
1959 * acf_is_field
1960 *
1961 * This function will compare a $selector against a $field array
1962 *
1963 * @type function
1964 * @date 1/7/17
1965 * @since 5.6.0
1966 *
1967 * @param $post_id (int)
1968 * @return $post_id (int)
1969 */
1970
1971 function acf_is_field( $field, $selector = '' ) {
1972
1973 // vars
1974 $keys = array(
1975 'ID',
1976 'name',
1977 'key',
1978 '_name',
1979 '__name',
1980 );
1981
1982
1983 // loop
1984 foreach( $keys as $k ) {
1985
1986 if( isset($field[ $k ]) && $field[ $k ] === $selector ) return true;
1987
1988 }
1989
1990
1991 // return
1992 return false;
1993
1994 }
1995
1996
1997 /*
1998 * acf_get_field_ancestors
1999 *
2000 * This function will return an array of all ancestor fields
2001 *
2002 * @type function
2003 * @date 22/06/2016
2004 * @since 5.3.8
2005 *
2006 * @param $field (array)
2007 * @return (array)
2008 */
2009
2010 function acf_get_field_ancestors( $field ) {
2011
2012 // get field
2013 $ancestors = array();
2014
2015
2016 // loop
2017 while( $field && acf_is_field_key($field['parent']) ) {
2018
2019 $ancestors[] = $field['parent'];
2020 $field = acf_get_field($field['parent']);
2021
2022 }
2023
2024
2025 // return
2026 return $ancestors;
2027
2028 }
2029
2030
2031 /*
2032 * acf_maybe_get_sub_field
2033 *
2034 * This function will attempt to find a sub field
2035 *
2036 * @type function
2037 * @date 3/10/2016
2038 * @since 5.4.0
2039 *
2040 * @param $post_id (int)
2041 * @return $post_id (int)
2042 */
2043
2044 function acf_maybe_get_sub_field( $selectors, $post_id = false, $strict = true ) {
2045
2046 // bail ealry if not enough selectors
2047 if( !is_array($selectors) || count($selectors) < 3 ) return false;
2048
2049
2050 // vars
2051 $offset = acf_get_setting('row_index_offset');
2052 $selector = acf_extract_var( $selectors, 0 );
2053 $selectors = array_values( $selectors ); // reset keys
2054
2055
2056 // attempt get field
2057 $field = acf_maybe_get_field( $selector, $post_id, $strict );
2058
2059
2060 // bail early if no field
2061 if( !$field ) return false;
2062
2063
2064 // loop
2065 for( $j = 0; $j < count($selectors); $j+=2 ) {
2066
2067 // vars
2068 $sub_i = $selectors[ $j ];
2069 $sub_s = $selectors[ $j+1 ];
2070 $field_name = $field['name'];
2071
2072
2073 // find sub field
2074 $field = acf_get_sub_field( $sub_s, $field );
2075
2076
2077 // bail early if no sub field
2078 if( !$field ) return false;
2079
2080
2081 // add to name
2082 $field['name'] = $field_name . '_' . ($sub_i-$offset) . '_' . $field['name'];
2083
2084 }
2085
2086
2087 // return
2088 return $field;
2089
2090
2091 }
2092
2093
2094 /*
2095 * acf_prefix_fields
2096 *
2097 * This funtion will safely change the prefix for an array of fields
2098 * Needed to allow clone field to continue working on nave menu item and widget forms
2099 *
2100 * @type function
2101 * @date 5/9/17
2102 * @since 5.6.0
2103 *
2104 * @param $post_id (int)
2105 * @return $post_id (int)
2106 */
2107
2108 function acf_prefix_fields( &$fields, $prefix = 'acf' ) {
2109
2110 // loop
2111 foreach( $fields as &$field ) {
2112
2113 // replace 'acf' with $prefix
2114 $field['prefix'] = substr_replace($field['prefix'], $prefix, 0, 3);
2115
2116 }
2117
2118
2119 // return
2120 return $fields;
2121
2122 }
2123
2124 /**
2125 * acf_apply_field_filters
2126 *
2127 * description
2128 *
2129 * @date 11/9/18
2130 * @since 5.7.6
2131 *
2132 * @param type $var Description. Default.
2133 * @return type Description.
2134 */
2135 /*
2136 function acf_apply_field_filters( $value ) {
2137
2138 // get function args
2139 $args = func_get_args();
2140
2141 // find field in $args
2142 $field = false;
2143 foreach( $args as $arg ) {
2144 if( is_array($arg) && isset($arg['key'], $arg['type'], $arg['_name']) ) {
2145 $field = $arg;
2146 break;
2147 }
2148 }
2149
2150 // vars
2151 $filter = current_filter();
2152
2153 // unshift tag to args
2154 array_unshift($args, $filter);
2155
2156 // apply field filters
2157 if( $field ) {
2158
2159 // $filter/type=$type
2160 $args[0] = "{$filter}/type={$field['type']}";
2161 $value = call_user_func_array('apply_filters', $args);
2162
2163 // $filter/name=$name
2164 $args[0] = "{$filter}/name={$field['_name']}";
2165 $value = call_user_func_array('apply_filters', $args);
2166
2167 // $filter/key=$key
2168 $args[0] = "{$filter}/key={$field['key']}";
2169 $value = call_user_func_array('apply_filters', $args);
2170 }
2171
2172 // return
2173 return $value;
2174 }
2175 */
2176
2177 ?>