PluginProbe
Advanced Custom Fields (ACF®) / 4.0.3
Advanced Custom Fields (ACF®) v4.0.3
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 / core / api.php

api.php in Advanced Custom Fields (ACF®) 4.0.3, at core/api.php

1,423 lines 28.5 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2
3 // vars
4 $GLOBALS['acf_field'] = array();
5
6
7 /*
8 * acf_filter_post_id()
9 *
10 * A helper function to filter the post_id variable.
11 *
12 * @type function
13 * @since 3.6
14 * @date 29/01/13
15 *
16 * @param mixed $post_id
17 *
18 * @return mixed $post_id
19 */
20
21 function acf_filter_post_id( $post_id )
22 {
23 // set post_id to global
24 if( !$post_id )
25 {
26 global $post;
27
28 if( $post )
29 {
30 $post_id = $post->ID;
31 }
32 }
33
34
35 // allow for option == options
36 if( $post_id == "option" )
37 {
38 $post_id = "options";
39 }
40
41
42 /*
43 * Override for preview
44 *
45 * If the $_GET['preview_id'] is set, then the user wants to see the preview data.
46 * There is also the case of previewing a page with post_id = 1, but using get_field
47 * to load data from another post_id.
48 * In this case, we need to make sure that the autosave revision is actually related
49 * to the $post_id variable. If they match, then the autosave data will be used, otherwise,
50 * the user wants to load data from a completely different post_id
51 */
52
53 if( isset($_GET['preview_id']) )
54 {
55 $autosave = wp_get_post_autosave( $_GET['preview_id'] );
56 if( $autosave->post_parent == $post_id )
57 {
58 $post_id = $autosave->ID;
59 }
60 }
61
62
63 // return
64 return $post_id;
65 }
66
67
68 /*
69 * get_field_reference()
70 *
71 * This function will find the $field_key that is related to the $field_name.
72 * This is know as the field value reference
73 *
74 * @type function
75 * @since 3.6
76 * @date 29/01/13
77 *
78 * @param mixed $field_name: the name of the field - 'sub_heading'
79 * @param int $post_id: the post_id of which the value is saved against
80 *
81 * @return string $return: a string containing the field_key
82 */
83
84 function get_field_reference( $field_name, $post_id )
85 {
86 // cache
87 $cache = wp_cache_get( 'field_reference-' . $post_id . '-' . $field_name, 'acf' );
88 if( $cache )
89 {
90 return $cache;
91 }
92
93
94 // vars
95 $return = '';
96
97
98 // get field key
99 if( is_numeric($post_id) )
100 {
101 $return = get_post_meta($post_id, '_' . $field_name, true);
102 }
103 elseif( strpos($post_id, 'user_') !== false )
104 {
105 $temp_post_id = str_replace('user_', '', $post_id);
106 $return = get_user_meta($temp_post_id, '_' . $field_name, true);
107 }
108 else
109 {
110 $return = get_option('_' . $post_id . '_' . $field_name);
111 }
112
113
114 // set cache
115 wp_cache_set( 'field_reference-' . $post_id . '-' . $field_name, $return, 'acf' );
116
117
118 // return
119 return $return;
120 }
121
122
123 /*
124 * get_field_objects()
125 *
126 * This function will return an array containing all the custom field objects for a specific post_id.
127 * The function is not very elegant and wastes a lot of PHP memory / SQL queries if you are not using all the fields / values.
128 *
129 * @type function
130 * @since 3.6
131 * @date 29/01/13
132 *
133 * @param mixed $post_id: the post_id of which the value is saved against
134 *
135 * @return array $return: an array containin the field groups
136 */
137
138 function get_field_objects( $post_id = false, $options = array() )
139 {
140 // global
141 global $wpdb;
142
143
144 // filter post_id
145 $post_id = acf_filter_post_id( $post_id );
146
147
148 // vars
149 $field_key = '';
150 $value = array();
151
152
153 // get field_names
154 if( is_numeric($post_id) )
155 {
156 $keys = $wpdb->get_col($wpdb->prepare(
157 "SELECT meta_value FROM $wpdb->postmeta WHERE post_id = %d and meta_key LIKE %s AND meta_value LIKE %s",
158 $post_id,
159 '\_%',
160 'field\_%'
161 ));
162 }
163 elseif( strpos($post_id, 'user_') !== false )
164 {
165 $user_id = str_replace('user_', '', $post_id);
166
167 $keys = $wpdb->get_col($wpdb->prepare(
168 "SELECT meta_value FROM $wpdb->usermeta WHERE user_id = %d and meta_key LIKE %s AND meta_value LIKE %s",
169 $user_id,
170 '\_%',
171 'field\_%'
172 ));
173 }
174 else
175 {
176 $keys = $wpdb->get_col($wpdb->prepare(
177 "SELECT option_name FROM $wpdb->options WHERE option_name LIKE %s",
178 '\_' . $post_id . '\_%'
179 ));
180 }
181
182
183 if( is_array($keys) )
184 {
185 foreach( $keys as $key )
186 {
187 $field = get_field_object( $key, $post_id, $options );
188
189 if( !is_array($field) )
190 {
191 continue;
192 }
193
194 $value[ $field['name'] ] = $field;
195 }
196 }
197
198
199 // no value
200 if( empty($value) )
201 {
202 return false;
203 }
204
205
206 // return
207 return $value;
208 }
209
210
211 /*
212 * get_fields()
213 *
214 * This function will return an array containing all the custom field values for a specific post_id.
215 * The function is not very elegant and wastes a lot of PHP memory / SQL queries if you are not using all the values.
216 *
217 * @type function
218 * @since 3.6
219 * @date 29/01/13
220 *
221 * @param mixed $post_id: the post_id of which the value is saved against
222 *
223 * @return array $return: an array containin the field values
224 */
225
226 function get_fields( $post_id = false )
227 {
228 $fields = get_field_objects( $post_id );
229
230 if( is_array($fields) )
231 {
232 foreach( $fields as $k => $field )
233 {
234 $fields[ $k ] = $field['value'];
235 }
236 }
237
238 return $fields;
239 }
240
241
242 /*
243 * get_field()
244 *
245 * This function will return a custom field value for a specific field name/key + post_id.
246 * There is a 3rd parameter to turn on/off formating. This means that an Image field will not use
247 * its 'return option' to format the value but return only what was saved in the database
248 *
249 * @type function
250 * @since 3.6
251 * @date 29/01/13
252 *
253 * @param string $field_key: string containing the name of teh field name / key ('sub_field' / 'field_1')
254 * @param mixed $post_id: the post_id of which the value is saved against
255 * @param boolean $format_value: whether or not to format the value as described above
256 *
257 * @return mixed $value: the value found
258 */
259
260 function get_field( $field_key, $post_id = false, $format_value = true )
261 {
262 // vars
263 $return = false;
264 $options = array(
265 'load_value' => true,
266 'format_value' => $format_value
267 );
268
269
270 $field = get_field_object( $field_key, $post_id, $options);
271
272
273 if( is_array($field) )
274 {
275 $return = $field['value'];
276 }
277
278
279 return $return;
280
281 }
282
283
284 /*
285 * get_field_object()
286 *
287 * This function will return an array containing all the field data for a given field_name
288 *
289 * @type function
290 * @since 3.6
291 * @date 3/02/13
292 *
293 * @param string $field_key: string containing the name of teh field name / key ('sub_field' / 'field_1')
294 * @param mixed $post_id: the post_id of which the value is saved against
295 * @param array $options: an array containing options
296 * boolean + load_value: load the field value or not. Defaults to true
297 * boolean + format_value: format the field value or not. Defaults to true
298 *
299 * @return array $return: an array containin the field groups
300 */
301
302 function get_field_object( $field_key, $post_id = false, $options = array() )
303 {
304 // filter post_id
305 $post_id = acf_filter_post_id( $post_id );
306 $field = false;
307 $orig_field_key = $field_key;
308
309
310 // defaults for options
311 $defaults = array(
312 'load_value' => true,
313 'format_value' => true,
314 );
315
316 $options = array_merge($defaults, $options);
317
318
319 // is $field_name a name? pre 3.4.0
320 if( strpos($field_key, "field_") === false )
321 {
322 // get field key
323 $field_key = get_field_reference( $field_key, $post_id );
324 }
325
326
327 // get field
328 if( strpos($field_key, "field_") !== false )
329 {
330 $field = apply_filters('acf/load_field', false, $field_key );
331 }
332
333
334 // validate field
335 if( !$field )
336 {
337 // treat as text field
338 $field = array(
339 'type' => 'text',
340 'name' => $orig_field_key,
341 'key' => 'temp_key_for_' . $orig_field_key,
342 );
343 }
344
345
346 // load value
347 if( $options['load_value'] )
348 {
349 $field['value'] = apply_filters('acf/load_value', false, $post_id, $field);
350
351
352 // format value
353 if( $options['format_value'] )
354 {
355 $field['value'] = apply_filters('acf/format_value_for_api', $field['value'], $post_id, $field);
356 }
357 }
358
359
360 return $field;
361
362 }
363
364
365 /*
366 * the_field()
367 *
368 * This function is the same as echo get_field().
369 *
370 * @type function
371 * @since 1.0.3
372 * @date 29/01/13
373 *
374 * @param string $field_name: the name of the field - 'sub_heading'
375 * @param mixed $post_id: the post_id of which the value is saved against
376 *
377 * @return string $value
378 */
379
380 function the_field( $field_name, $post_id = false )
381 {
382 $value = get_field($field_name, $post_id);
383
384 if( is_array($value) )
385 {
386 $value = @implode(', ',$value);
387 }
388
389 echo $value;
390 }
391
392
393 /*
394 * has_sub_field()
395 *
396 * This function is used inside a while loop to return either true or false (loop again or stop).
397 * When using a repeater or flexible content field, it will loop through the rows until
398 * there are none left or a break is detected
399 *
400 * @type function
401 * @since 1.0.3
402 * @date 29/01/13
403 *
404 * @param string $field_name: the name of the field - 'sub_heading'
405 * @param mixed $post_id: the post_id of which the value is saved against
406 *
407 * @return bool
408 */
409
410 function has_sub_field( $field_name, $post_id = false )
411 {
412
413 // filter post_id
414 $post_id = acf_filter_post_id( $post_id );
415
416
417 // empty?
418 if( empty($GLOBALS['acf_field']) )
419 {
420 // vars
421 $f = get_field_object( $field_name, $post_id );
422 $v = $f['value'];
423 unset( $f['value'] );
424
425
426 $GLOBALS['acf_field'][] = array(
427 'name' => $field_name,
428 'value' => $v,
429 'field' => $f,
430 'row' => -1,
431 'post_id' => $post_id,
432 );
433 }
434
435
436 // vars
437 $depth = count( $GLOBALS['acf_field'] ) - 1;
438 $name = $GLOBALS['acf_field'][$depth]['name'];
439 $value = $GLOBALS['acf_field'][$depth]['value'];
440 $field = $GLOBALS['acf_field'][$depth]['field'];
441 $row = $GLOBALS['acf_field'][$depth]['row'];
442 $id = $GLOBALS['acf_field'][$depth]['post_id'];
443
444
445 // if ID has changed, this is a new repeater / flexible field!
446 if( $post_id != $id )
447 {
448 // vars
449 $f = get_field_object( $field_name, $post_id );
450 $v = $f['value'];
451 unset( $f['value'] );
452
453
454 $GLOBALS['acf_field'][] = array(
455 'name' => $field_name,
456 'value' => $v,
457 'field' => $f,
458 'row' => -1,
459 'post_id' => $post_id,
460 );
461
462 return has_sub_field($field_name, $post_id);
463 }
464
465
466 // does the given $field_name match the current field?
467 if( $field_name != $name )
468 {
469 // is this a "new" while loop refering to a sub field?
470 if( isset($value[ $row ][ $field_name ]) )
471 {
472 $GLOBALS['acf_field'][] = array(
473 'name' => $field_name,
474 'value' => $value[ $row ][ $field_name ],
475 'field' => acf_get_child_field_from_parent_field( $field_name, $field ),
476 'row' => -1,
477 'post_id' => $post_id,
478 );
479 }
480 elseif( isset($GLOBALS['acf_field'][$depth-1]) && $GLOBALS['acf_field'][$depth-1]['name'] == $field_name )
481 {
482 // if someone used break; We should see if the parent value has this field_name as a value.
483 unset( $GLOBALS['acf_field'][$depth] );
484 $GLOBALS['acf_field'] = array_values($GLOBALS['acf_field']);
485 }
486 else
487 {
488 // this was a break; (probably to get the first row only). Clear the repeater
489 $GLOBALS['acf_field'] = array();
490 return has_sub_field($field_name, $post_id);
491 }
492
493 }
494
495
496 // update vars
497 $depth = count( $GLOBALS['acf_field'] ) - 1;
498 $value = $GLOBALS['acf_field'][$depth]['value'];
499 $field = $GLOBALS['acf_field'][$depth]['field'];
500 $row = $GLOBALS['acf_field'][$depth]['row'];
501
502
503 // increase row number
504 $GLOBALS['acf_field'][$depth]['row']++;
505 $row++;
506
507
508 if( isset($value[$row]) )
509 {
510 // next row exists
511 return true;
512 }
513
514
515 // no next row! Unset this array and return false to stop while loop
516 unset( $GLOBALS['acf_field'][$depth] );
517 $GLOBALS['acf_field'] = array_values($GLOBALS['acf_field']);
518
519 return false;
520
521 }
522
523
524 /*
525 * has_sub_fields()
526 *
527 * This function is a replica of 'has_sub_field'
528 *
529 * @type function
530 * @since 4.0.0
531 * @date 29/01/13
532 *
533 * @param string $field_name: the name of the field - 'sub_heading'
534 * @param mixed $post_id: the post_id of which the value is saved against
535 *
536 * @return bool
537 */
538
539 function has_sub_fields( $field_name, $post_id = false )
540 {
541 return has_sub_field( $field_name, $post_id );
542 }
543
544
545 /*
546 * get_sub_field()
547 *
548 * This function is used inside a 'has_sub_field' while loop to return a sub field value
549 *
550 * @type function
551 * @since 1.0.3
552 * @date 29/01/13
553 *
554 * @param string $field_name: the name of the field - 'sub_heading'
555 *
556 * @return mixed $value
557 */
558
559 function get_sub_field( $field_name )
560 {
561
562 // no field?
563 if( empty($GLOBALS['acf_field']) )
564 {
565 return false;
566 }
567
568
569 // vars
570 $depth = count( $GLOBALS['acf_field'] ) - 1;
571 $value = $GLOBALS['acf_field'][$depth]['value'];
572 $field = $GLOBALS['acf_field'][$depth]['field'];
573 $row = $GLOBALS['acf_field'][$depth]['row'];
574
575
576 // no value at i
577 if( !isset($value[ $row ][ $field_name ]) )
578 {
579 return false;
580 }
581
582
583 return $value[ $row ][ $field_name ];
584 }
585
586
587 /*
588 * get_sub_field()
589 *
590 * This function is the same as echo get_sub_field
591 *
592 * @type function
593 * @since 1.0.3
594 * @date 29/01/13
595 *
596 * @param string $field_name: the name of the field - 'sub_heading'
597 *
598 * @return string $value
599 */
600
601 function the_sub_field($field_name)
602 {
603 $value = get_sub_field($field_name);
604
605 if(is_array($value))
606 {
607 $value = implode(', ',$value);
608 }
609
610 echo $value;
611 }
612
613
614 /*
615 * get_sub_field_object()
616 *
617 * This function is used inside a 'has_sub_field' while loop to return a sub field object
618 *
619 * @type function
620 * @since 3.5.8.1
621 * @date 29/01/13
622 *
623 * @param string $field_name: the name of the field - 'sub_heading'
624 *
625 * @return array $sub_field
626 */
627
628 function get_sub_field_object( $child_name )
629 {
630 // no field?
631 if( empty($GLOBALS['acf_field']) )
632 {
633 return false;
634 }
635
636
637 // vars
638 $depth = count( $GLOBALS['acf_field'] ) - 1;
639 $parent = $GLOBALS['acf_field'][$depth]['field'];
640
641
642 // return
643 return acf_get_child_field_from_parent_field( $child_name, $parent );
644
645 }
646
647
648 /*
649 * acf_get_sub_field_from_parent_field()
650 *
651 * This function is used by the get_sub_field_object to find a sub field within a parent field
652 *
653 * @type function
654 * @since 3.5.8.1
655 * @date 29/01/13
656 *
657 * @param string $child_name: the name of the field - 'sub_heading'
658 * @param array $parent: the parent field object
659 *
660 * @return array $sub_field
661 */
662
663 function acf_get_child_field_from_parent_field( $child_name, $parent )
664 {
665 // vars
666 $return = false;
667
668
669 // find child
670 if( isset($parent['sub_fields']) && is_array($parent['sub_fields']) )
671 {
672 foreach( $parent['sub_fields'] as $child )
673 {
674 if( $child['name'] == $child_name || $child['key'] == $child_name )
675 {
676 $return = $child;
677 break;
678 }
679 }
680 }
681 elseif( isset($parent['layouts']) && is_array($parent['layouts']) )
682 {
683 foreach( $parent['layouts'] as $layout )
684 {
685 if( isset($layout['sub_fields']) && is_array($layout['sub_fields']) )
686 {
687 foreach( $layout['sub_fields'] as $child )
688 {
689 if( $child['name'] == $child_name || $child['key'] == $child_name )
690 {
691 $return = $child;
692 break;
693 }
694 }
695 }
696 }
697 }
698
699
700 // return
701 return $return;
702
703 }
704
705
706 /*
707 * register_field_group()
708 *
709 * This function is used to register a field group via code. It acceps 1 array containing
710 * all the field group data. This data can be obtained by using teh export tool within ACF
711 *
712 * @type function
713 * @since 3.0.6
714 * @date 29/01/13
715 *
716 * @param array $array: an array holding all the field group data
717 *
718 * @return
719 */
720
721 $GLOBALS['acf_register_field_group'] = array();
722
723 function register_field_group( $array )
724 {
725 // add id
726 if( !isset($array['id']) )
727 {
728 $array['id'] = uniqid();
729 }
730
731
732 // 3.2.5 - changed show_on_page option
733 if( !isset($array['options']['hide_on_screen']) && isset($array['options']['show_on_page']) )
734 {
735 $show_all = array('the_content', 'discussion', 'custom_fields', 'comments', 'slug', 'author');
736 $array['options']['hide_on_screen'] = array_diff($show_all, $array['options']['show_on_page']);
737 unset( $array['options']['show_on_page'] );
738 }
739
740
741 $GLOBALS['acf_register_field_group'][] = $array;
742 }
743
744
745 add_filter('acf/get_field_groups', 'api_acf_get_field_groups', 2, 1);
746 function api_acf_get_field_groups( $return )
747 {
748 // validate
749 if( empty($GLOBALS['acf_register_field_group']) )
750 {
751 return $return;
752 }
753
754
755 foreach( $GLOBALS['acf_register_field_group'] as $acf )
756 {
757 $return[] = array(
758 'id' => $acf['id'],
759 'title' => $acf['title'],
760 'menu_order' => $acf['menu_order'],
761 );
762 }
763
764
765 // order field groups based on menu_order, title
766 // Obtain a list of columns
767 foreach( $return as $key => $row )
768 {
769 $menu_order[ $key ] = $row['menu_order'];
770 $title[ $key ] = $row['title'];
771 }
772
773 // Sort the array with menu_order ascending
774 // Add $array as the last parameter, to sort by the common key
775 if(isset($menu_order))
776 {
777 array_multisort($menu_order, SORT_ASC, $title, SORT_ASC, $return);
778 }
779
780 return $return;
781 }
782
783
784 add_filter('acf/field_group/get_fields', 'api_acf_field_group_get_fields', 1, 2);
785 function api_acf_field_group_get_fields( $fields, $post_id )
786 {
787 // validate
788 if( !empty($GLOBALS['acf_register_field_group']) )
789 {
790 foreach( $GLOBALS['acf_register_field_group'] as $acf )
791 {
792 if( $acf['id'] == $post_id )
793 {
794 foreach( $acf['fields'] as $f )
795 {
796 $fields[] = apply_filters('acf/load_field', $f, $f['key']);
797 }
798
799 break;
800 }
801 }
802 }
803
804 return $fields;
805
806 }
807
808
809 add_filter('acf/load_field', 'api_acf_load_field', 1, 2);
810 function api_acf_load_field( $field, $field_key )
811 {
812 // validate
813 if( !empty($GLOBALS['acf_register_field_group']) )
814 {
815 foreach( $GLOBALS['acf_register_field_group'] as $acf )
816 {
817 if( !empty($acf['fields']) )
818 {
819 foreach( $acf['fields'] as $f )
820 {
821 if( $f['key'] == $field_key )
822 {
823 $field = $f;
824 break;
825 }
826 }
827 }
828 }
829 }
830
831 return $field;
832 }
833
834
835 add_filter('acf/field_group/get_location', 'api_acf_field_group_get_location', 1, 2);
836 function api_acf_field_group_get_location( $location, $post_id )
837 {
838 // validate
839 if( !empty($GLOBALS['acf_register_field_group']) )
840 {
841 foreach( $GLOBALS['acf_register_field_group'] as $acf )
842 {
843 if( $acf['id'] == $post_id )
844 {
845 $location = $acf['location'];
846 break;
847 }
848 }
849 }
850
851 return $location;
852 }
853
854
855
856 add_filter('acf/field_group/get_options', 'api_acf_field_group_get_options', 1, 2);
857 function api_acf_field_group_get_options( $options, $post_id )
858 {
859 // validate
860 if( !empty($GLOBALS['acf_register_field_group']) )
861 {
862 foreach( $GLOBALS['acf_register_field_group'] as $acf )
863 {
864 if( $acf['id'] == $post_id )
865 {
866 $options = $acf['options'];
867 break;
868 }
869 }
870 }
871
872 return $options;
873 }
874
875
876 /*
877 * get_row_layout()
878 *
879 * This function will return a string representation of the current row layout within a 'has_sub_field' loop
880 *
881 * @type function
882 * @since 3.0.6
883 * @date 29/01/13
884 *
885 * @return $value - string containing the layout
886 */
887
888 function get_row_layout()
889 {
890 // vars
891 $value = get_sub_field('acf_fc_layout');
892
893
894 return $value;
895 }
896
897
898 /*
899 * acf_shortcode()
900 *
901 * This function is used to add basic shortcode support for the ACF plugin
902 *
903 * @type function
904 * @since 1.1.1
905 * @date 29/01/13
906 *
907 * @param array $atts: an array holding the shortcode options
908 * string + field: the field name
909 * mixed + post_id: the post_id to load from
910 *
911 * @return string $value: the value found by get_field
912 */
913
914 function acf_shortcode( $atts )
915 {
916 // extract attributs
917 extract( shortcode_atts( array(
918 'field' => "",
919 'post_id' => false,
920 ), $atts ) );
921
922
923 // $field is requird
924 if( !$field || $field == "" )
925 {
926 return "";
927 }
928
929
930 // get value and return it
931 $value = get_field( $field, $post_id );
932
933
934 if( is_array($value) )
935 {
936 $value = @implode( ', ',$value );
937 }
938
939 return $value;
940 }
941 add_shortcode( 'acf', 'acf_shortcode' );
942
943
944 /*
945 * acf_form_head()
946 *
947 * 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.
948 *
949 * @type function
950 * @since 1.1.4
951 * @date 29/01/13
952 *
953 * @param N/A
954 *
955 * @return N/A
956 */
957
958 function acf_form_head()
959 {
960 // global vars
961 global $post_id;
962
963
964 // verify nonce
965 if( isset($_POST['acf_nonce']) && wp_verify_nonce($_POST['acf_nonce'], 'input') )
966 {
967 // $post_id to save against
968 $post_id = $_POST['post_id'];
969
970
971 // allow for custom save
972 $post_id = apply_filters('acf/pre_save_post', $post_id);
973
974
975 // save the data
976 do_action('acf/save_post', $post_id);
977
978
979 // redirect
980 if(isset($_POST['return']))
981 {
982 wp_redirect($_POST['return']);
983 exit;
984 }
985 }
986
987
988 // need wp styling
989 wp_enqueue_style(array(
990 'colors-fresh'
991 ));
992
993
994 // actions
995 do_action('acf/input/admin_enqueue_scripts');
996
997 add_action('wp_head', 'acf_form_wp_head');
998
999 }
1000
1001 function acf_form_wp_head()
1002 {
1003 do_action('acf/input/admin_head');
1004 }
1005
1006
1007 /*
1008 * acf_form()
1009 *
1010 * This function is used to create an ACF form.
1011 *
1012 * @type function
1013 * @since 1.1.4
1014 * @date 29/01/13
1015 *
1016 * @param array $options: an array containing many options to customize the form
1017 * string + post_id: post id to get field groups from and save data to. Default is false
1018 * array + field_groups: an array containing field group ID's. If this option is set,
1019 * the post_id will not be used to dynamically find the field groups
1020 * boolean + form: display the form tag or not. Defaults to true
1021 * array + form_attributes: an array containg attributes which will be added into the form tag
1022 * string + return: the return URL
1023 * string + html_before_fields: html inside form before fields
1024 * string + html_after_fields: html inside form after fields
1025 * string + submit_value: value of submit button
1026 * string + updated_message: default updated message. Can be false
1027 *
1028 * @return N/A
1029 */
1030
1031 function acf_form( $options = false )
1032 {
1033 global $post;
1034
1035
1036 // defaults
1037 $defaults = array(
1038 'post_id' => false,
1039 'field_groups' => array(),
1040 'form' => true,
1041 'form_attributes' => array(
1042 'class' => ''
1043 ),
1044 'return' => add_query_arg( 'updated', 'true', get_permalink() ),
1045 'html_before_fields' => '',
1046 'html_after_fields' => '',
1047 'submit_value' => 'Update',
1048 'updated_message' => 'Post updated.',
1049 );
1050
1051
1052 // merge defaults with options
1053 if( $options && is_array($options) )
1054 {
1055 $options = array_merge($defaults, $options);
1056 }
1057 else
1058 {
1059 $options = $defaults;
1060 }
1061
1062
1063 // filter post_id
1064 $options['post_id'] = acf_filter_post_id( $options['post_id'] );
1065
1066
1067 // register post box
1068 if( empty($options['field_groups']) )
1069 {
1070 // get field groups
1071 $filter = array(
1072 'post_id' => $options['post_id']
1073 );
1074
1075
1076 if( strpos($options['post_id'], 'user_') !== false )
1077 {
1078 $user_id = str_replace('user_', '', $options['post_id']);
1079 $filter = array(
1080 'ef_user' => $user_id
1081 );
1082 }
1083 elseif( strpos($options['post_id'], 'taxonomy_') !== false )
1084 {
1085 $taxonomy_id = str_replace('taxonomy_', '', $options['post_id']);
1086 $filter = array(
1087 'ef_taxonomy' => $taxonomy_id
1088 );
1089 }
1090
1091
1092 $options['field_groups'] = array();
1093 $options['field_groups'] = apply_filters( 'acf/location/match_field_groups', $options['field_groups'], $filter );
1094 }
1095
1096
1097 // updated message
1098 if(isset($_GET['updated']) && $_GET['updated'] == 'true' && $options['updated_message'])
1099 {
1100 echo '<div id="message" class="updated"><p>' . $options['updated_message'] . '</p></div>';
1101 }
1102
1103
1104 // Javascript
1105 $script_post_id = is_numeric($options['post_id']) ? $options['post_id'] : 0;
1106 echo '<script type="text/javascript">acf.post_id = ' . $script_post_id . '; </script>';
1107
1108
1109 // display form
1110 if( $options['form'] ): ?>
1111 <form action="" id="post" method="post" <?php if($options['form_attributes']){foreach($options['form_attributes'] as $k => $v){echo $k . '="' . $v .'" '; }} ?>>
1112 <?php endif; ?>
1113
1114 <div style="display:none">
1115 <input type="hidden" name="acf_nonce" value="<?php echo wp_create_nonce( 'input' ); ?>" />
1116 <input type="hidden" name="post_id" value="<?php echo $options['post_id']; ?>" />
1117 <input type="hidden" name="return" value="<?php echo $options['return']; ?>" />
1118 <?php wp_editor('', 'acf_settings'); ?>
1119 </div>
1120
1121 <div id="poststuff">
1122 <?php
1123
1124 // html before fields
1125 echo $options['html_before_fields'];
1126
1127
1128 $acfs = apply_filters('acf/get_field_groups', array());
1129
1130 if( is_array($acfs) ){ foreach( $acfs as $acf ){
1131
1132 // only add the chosen field groups
1133 if( !in_array( $acf['id'], $options['field_groups'] ) )
1134 {
1135 continue;
1136 }
1137
1138
1139 // load options
1140 $acf['options'] = apply_filters('acf/field_group/get_options', array(), $acf['id']);
1141
1142
1143 // load fields
1144 $fields = apply_filters('acf/field_group/get_fields', array(), $acf['id']);
1145
1146
1147 echo '<div id="acf_' . $acf['id'] . '" class="postbox acf_postbox">';
1148 echo '<h3 class="hndle"><span>' . $acf['title'] . '</span></h3>';
1149 echo '<div class="inside">';
1150 echo '<div class="options" data-layout="' . $acf['options']['layout'] . '" data-show="1"></div>';
1151
1152 do_action('acf/create_fields', $fields, $options['post_id']);
1153
1154 echo '</div></div>';
1155
1156 }}
1157
1158
1159 // html after fields
1160 echo $options['html_after_fields'];
1161
1162 ?>
1163
1164 <?php if( $options['form'] ): ?>
1165 <!-- Submit -->
1166 <div class="field">
1167 <input type="submit" value="<?php echo $options['submit_value']; ?>" />
1168 </div>
1169 <!-- / Submit -->
1170 <?php endif; ?>
1171
1172 </div><!-- <div id="poststuff"> -->
1173
1174 <?php if( $options['form'] ): ?>
1175 </form>
1176 <?php endif;
1177 }
1178
1179
1180 /*
1181 * update_field()
1182 *
1183 * This function will update a value in the database
1184 *
1185 * @type function
1186 * @since 3.1.9
1187 * @date 29/01/13
1188 *
1189 * @param mixed $field_name: the name of the field - 'sub_heading'
1190 * @param mixed $value: the value to save in the database. The variable type is dependant on the field type
1191 * @param mixed $post_id: the post_id of which the value is saved against
1192 *
1193 * @return N/A
1194 */
1195
1196 function update_field( $field_key, $value, $post_id = false )
1197 {
1198 // filter post_id
1199 $post_id = acf_filter_post_id( $post_id );
1200
1201
1202 // vars
1203 $options = array(
1204 'load_value' => false,
1205 'format_value' => false
1206 );
1207
1208 $field = get_field_object( $field_key, $post_id, $options);
1209
1210
1211 if( !is_array($field) )
1212 {
1213 $field = array(
1214 'type' => 'none',
1215 'name' => $field_key
1216 );
1217 }
1218
1219
1220 // sub fields? They need formatted data
1221 if( $field['type'] == 'repeater' )
1222 {
1223 $value = acf_convert_field_names_to_keys( $value, $field );
1224 }
1225 elseif( $field['type'] == 'flexible_content' )
1226 {
1227 if( $field['layouts'] )
1228 {
1229 foreach( $field['layouts'] as $layout )
1230 {
1231 $value = acf_convert_field_names_to_keys( $value, $layout );
1232 }
1233 }
1234 }
1235
1236
1237 // save
1238 do_action('acf/update_value', $value, $post_id, $field );
1239
1240
1241 return true;
1242
1243 }
1244
1245
1246 /*
1247 * delete_field()
1248 *
1249 * This function will remove a value from the database
1250 *
1251 * @type function
1252 * @since 3.1.9
1253 * @date 29/01/13
1254 *
1255 * @param mixed $field_name: the name of the field - 'sub_heading'
1256 * @param mixed $post_id: the post_id of which the value is saved against
1257 *
1258 * @return N/A
1259 */
1260
1261 function delete_field( $field_name, $post_id )
1262 {
1263 do_action('acf/delete_value', $post_id, $field_name );
1264 }
1265
1266
1267 /*
1268 * create_field()
1269 *
1270 * This function will creat the HTML for a field
1271 *
1272 * @type function
1273 * @since 4.0.0
1274 * @date 17/03/13
1275 *
1276 * @param array $field - an array containing all the field attributes
1277 *
1278 * @return N/A
1279 */
1280
1281 function create_field( $field )
1282 {
1283 do_action('acf/create_field', $field );
1284 }
1285
1286
1287 /*
1288 * acf_convert_field_names_to_keys()
1289 *
1290 * Helper for the update_field function
1291 *
1292 * @type function
1293 * @since 4.0.0
1294 * @date 17/03/13
1295 *
1296 * @param array $value: the value returned via get_field
1297 * @param array $field: the field or layout to find sub fields from
1298 *
1299 * @return N/A
1300 */
1301
1302 function acf_convert_field_names_to_keys( $value, $field )
1303 {
1304 // only if $field has sub fields
1305 if( !isset($field['sub_fields']) )
1306 {
1307 return $value;
1308 }
1309
1310
1311 // define sub field keys
1312 $sub_fields = array();
1313 if( $field['sub_fields'] )
1314 {
1315 foreach( $field['sub_fields'] as $sub_field )
1316 {
1317 $sub_fields[ $sub_field['name'] ] = $sub_field;
1318 }
1319 }
1320
1321
1322 // loop through the values and format the array to use sub field keys
1323 if( is_array($value) )
1324 {
1325 foreach( $value as $row_i => $row)
1326 {
1327 if( $row )
1328 {
1329 foreach( $row as $sub_field_name => $sub_field_value )
1330 {
1331 // sub field must exist!
1332 if( !isset($sub_fields[ $sub_field_name ]) )
1333 {
1334 continue;
1335 }
1336
1337
1338 // vars
1339 $sub_field = $sub_fields[ $sub_field_name ];
1340 $sub_field_value = acf_convert_field_names_to_keys( $sub_field_value, $sub_field );
1341
1342
1343 // set new value
1344 $value[$row_i][ $sub_field['key'] ] = $sub_field_value;
1345
1346
1347 // unset old value
1348 unset( $value[$row_i][$sub_field_name] );
1349
1350
1351 }
1352 // foreach( $row as $sub_field_name => $sub_field_value )
1353 }
1354 // if( $row )
1355 }
1356 // foreach( $value as $row_i => $row)
1357 }
1358 // if( $value )
1359
1360
1361 return $value;
1362
1363 }
1364
1365
1366
1367 /*
1368 * Depreceated Functions
1369 *
1370 * @description:
1371 * @created: 23/07/12
1372 */
1373
1374
1375 /*--------------------------------------------------------------------------------------
1376 *
1377 * reset_the_repeater_field
1378 *
1379 * @author Elliot Condon
1380 * @depreciated: 3.3.4 - now use has_sub_field
1381 * @since 1.0.3
1382 *
1383 *-------------------------------------------------------------------------------------*/
1384
1385 function reset_the_repeater_field()
1386 {
1387 // do nothing
1388 }
1389
1390
1391 /*--------------------------------------------------------------------------------------
1392 *
1393 * the_repeater_field
1394 *
1395 * @author Elliot Condon
1396 * @depreciated: 3.3.4 - now use has_sub_field
1397 * @since 1.0.3
1398 *
1399 *-------------------------------------------------------------------------------------*/
1400
1401 function the_repeater_field($field_name, $post_id = false)
1402 {
1403 return has_sub_field($field_name, $post_id);
1404 }
1405
1406
1407 /*--------------------------------------------------------------------------------------
1408 *
1409 * the_flexible_field
1410 *
1411 * @author Elliot Condon
1412 * @depreciated: 3.3.4 - now use has_sub_field
1413 * @since 3.?.?
1414 *
1415 *-------------------------------------------------------------------------------------*/
1416
1417 function the_flexible_field($field_name, $post_id = false)
1418 {
1419 return has_sub_field($field_name, $post_id);
1420 }
1421
1422
1423 ?>