PluginProbe
Advanced Custom Fields (ACF®) / 4.1.4
Advanced Custom Fields (ACF®) v4.1.4
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
1,464 lines 29.2 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 // perhaps child has grand children?
681 $grand_child = acf_get_child_field_from_parent_field( $child_name, $child );
682 if( $grand_child )
683 {
684 $return = $grand_child;
685 break;
686 }
687 }
688 }
689 elseif( isset($parent['layouts']) && is_array($parent['layouts']) )
690 {
691 foreach( $parent['layouts'] as $layout )
692 {
693 $child = acf_get_child_field_from_parent_field( $child_name, $layout );
694 if( $child )
695 {
696 $return = $child;
697 break;
698 }
699 }
700 }
701
702
703 // return
704 return $return;
705
706 }
707
708
709 /*
710 * register_field_group()
711 *
712 * This function is used to register a field group via code. It acceps 1 array containing
713 * all the field group data. This data can be obtained by using teh export tool within ACF
714 *
715 * @type function
716 * @since 3.0.6
717 * @date 29/01/13
718 *
719 * @param array $array: an array holding all the field group data
720 *
721 * @return
722 */
723
724 $GLOBALS['acf_register_field_group'] = array();
725
726 function register_field_group( $array )
727 {
728 // add id
729 if( !isset($array['id']) )
730 {
731 $array['id'] = uniqid();
732 }
733
734
735 // 3.2.5 - changed show_on_page option
736 if( !isset($array['options']['hide_on_screen']) && isset($array['options']['show_on_page']) )
737 {
738 $show_all = array('the_content', 'discussion', 'custom_fields', 'comments', 'slug', 'author');
739 $array['options']['hide_on_screen'] = array_diff($show_all, $array['options']['show_on_page']);
740 unset( $array['options']['show_on_page'] );
741 }
742
743
744 // 4.0.4 - changed location rules architecture
745 if( isset($array['location']['rules']) )
746 {
747 // vars
748 $groups = array();
749 $group_no = 0;
750
751
752 if( is_array($array['location']['rules']) )
753 {
754 foreach( $array['location']['rules'] as $rule )
755 {
756 $rule['group_no'] = $group_no;
757
758 // sperate groups?
759 if( $array['location']['allorany'] == 'any' )
760 {
761 $group_no++;
762 }
763
764
765 // add to group
766 $groups[ $rule['group_no'] ][ $rule['order_no'] ] = $rule;
767
768
769 // sort rules
770 ksort( $groups[ $rule['group_no'] ] );
771
772 }
773
774 // sort groups
775 ksort( $groups );
776 }
777
778 $array['location'] = $groups;
779 }
780
781
782 $GLOBALS['acf_register_field_group'][] = $array;
783 }
784
785
786 add_filter('acf/get_field_groups', 'api_acf_get_field_groups', 2, 1);
787 function api_acf_get_field_groups( $return )
788 {
789 // validate
790 if( empty($GLOBALS['acf_register_field_group']) )
791 {
792 return $return;
793 }
794
795
796 foreach( $GLOBALS['acf_register_field_group'] as $acf )
797 {
798 $return[] = array(
799 'id' => $acf['id'],
800 'title' => $acf['title'],
801 'menu_order' => $acf['menu_order'],
802 );
803 }
804
805
806 // order field groups based on menu_order, title
807 // Obtain a list of columns
808 foreach( $return as $key => $row )
809 {
810 $menu_order[ $key ] = $row['menu_order'];
811 $title[ $key ] = $row['title'];
812 }
813
814 // Sort the array with menu_order ascending
815 // Add $array as the last parameter, to sort by the common key
816 if(isset($menu_order))
817 {
818 array_multisort($menu_order, SORT_ASC, $title, SORT_ASC, $return);
819 }
820
821 return $return;
822 }
823
824
825 add_filter('acf/field_group/get_fields', 'api_acf_field_group_get_fields', 1, 2);
826 function api_acf_field_group_get_fields( $fields, $post_id )
827 {
828 // validate
829 if( !empty($GLOBALS['acf_register_field_group']) )
830 {
831 foreach( $GLOBALS['acf_register_field_group'] as $acf )
832 {
833 if( $acf['id'] == $post_id )
834 {
835 foreach( $acf['fields'] as $f )
836 {
837 $fields[] = apply_filters('acf/load_field', $f, $f['key']);
838 }
839
840 break;
841 }
842 }
843 }
844
845 return $fields;
846
847 }
848
849
850 add_filter('acf/load_field', 'api_acf_load_field', 1, 2);
851 function api_acf_load_field( $field, $field_key )
852 {
853 // validate
854 if( !empty($GLOBALS['acf_register_field_group']) )
855 {
856 foreach( $GLOBALS['acf_register_field_group'] as $acf )
857 {
858 if( !empty($acf['fields']) )
859 {
860 foreach( $acf['fields'] as $f )
861 {
862 if( $f['key'] == $field_key )
863 {
864 $field = $f;
865 break;
866 }
867 }
868 }
869 }
870 }
871
872 return $field;
873 }
874
875
876 add_filter('acf/field_group/get_location', 'api_acf_field_group_get_location', 1, 2);
877 function api_acf_field_group_get_location( $location, $post_id )
878 {
879 // validate
880 if( !empty($GLOBALS['acf_register_field_group']) )
881 {
882 foreach( $GLOBALS['acf_register_field_group'] as $acf )
883 {
884 if( $acf['id'] == $post_id )
885 {
886 $location = $acf['location'];
887 break;
888 }
889 }
890 }
891
892 return $location;
893 }
894
895
896
897 add_filter('acf/field_group/get_options', 'api_acf_field_group_get_options', 1, 2);
898 function api_acf_field_group_get_options( $options, $post_id )
899 {
900 // validate
901 if( !empty($GLOBALS['acf_register_field_group']) )
902 {
903 foreach( $GLOBALS['acf_register_field_group'] as $acf )
904 {
905 if( $acf['id'] == $post_id )
906 {
907 $options = $acf['options'];
908 break;
909 }
910 }
911 }
912
913 return $options;
914 }
915
916
917 /*
918 * get_row_layout()
919 *
920 * This function will return a string representation of the current row layout within a 'has_sub_field' loop
921 *
922 * @type function
923 * @since 3.0.6
924 * @date 29/01/13
925 *
926 * @return $value - string containing the layout
927 */
928
929 function get_row_layout()
930 {
931 // vars
932 $value = get_sub_field('acf_fc_layout');
933
934
935 return $value;
936 }
937
938
939 /*
940 * acf_shortcode()
941 *
942 * This function is used to add basic shortcode support for the ACF plugin
943 *
944 * @type function
945 * @since 1.1.1
946 * @date 29/01/13
947 *
948 * @param array $atts: an array holding the shortcode options
949 * string + field: the field name
950 * mixed + post_id: the post_id to load from
951 *
952 * @return string $value: the value found by get_field
953 */
954
955 function acf_shortcode( $atts )
956 {
957 // extract attributs
958 extract( shortcode_atts( array(
959 'field' => "",
960 'post_id' => false,
961 ), $atts ) );
962
963
964 // $field is requird
965 if( !$field || $field == "" )
966 {
967 return "";
968 }
969
970
971 // get value and return it
972 $value = get_field( $field, $post_id );
973
974
975 if( is_array($value) )
976 {
977 $value = @implode( ', ',$value );
978 }
979
980 return $value;
981 }
982 add_shortcode( 'acf', 'acf_shortcode' );
983
984
985 /*
986 * acf_form_head()
987 *
988 * 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.
989 *
990 * @type function
991 * @since 1.1.4
992 * @date 29/01/13
993 *
994 * @param N/A
995 *
996 * @return N/A
997 */
998
999 function acf_form_head()
1000 {
1001 // global vars
1002 global $post_id;
1003
1004
1005 // verify nonce
1006 if( isset($_POST['acf_nonce']) && wp_verify_nonce($_POST['acf_nonce'], 'input') )
1007 {
1008 // $post_id to save against
1009 $post_id = $_POST['post_id'];
1010
1011
1012 // allow for custom save
1013 $post_id = apply_filters('acf/pre_save_post', $post_id);
1014
1015
1016 // save the data
1017 do_action('acf/save_post', $post_id);
1018
1019
1020 // redirect
1021 if(isset($_POST['return']))
1022 {
1023 wp_redirect($_POST['return']);
1024 exit;
1025 }
1026 }
1027
1028
1029 // need wp styling
1030 wp_enqueue_style(array(
1031 'colors-fresh'
1032 ));
1033
1034
1035 // actions
1036 do_action('acf/input/admin_enqueue_scripts');
1037
1038 add_action('wp_head', 'acf_form_wp_head');
1039
1040 }
1041
1042 function acf_form_wp_head()
1043 {
1044 do_action('acf/input/admin_head');
1045 }
1046
1047
1048 /*
1049 * acf_form()
1050 *
1051 * This function is used to create an ACF form.
1052 *
1053 * @type function
1054 * @since 1.1.4
1055 * @date 29/01/13
1056 *
1057 * @param array $options: an array containing many options to customize the form
1058 * string + post_id: post id to get field groups from and save data to. Default is false
1059 * array + field_groups: an array containing field group ID's. If this option is set,
1060 * the post_id will not be used to dynamically find the field groups
1061 * boolean + form: display the form tag or not. Defaults to true
1062 * array + form_attributes: an array containg attributes which will be added into the form tag
1063 * string + return: the return URL
1064 * string + html_before_fields: html inside form before fields
1065 * string + html_after_fields: html inside form after fields
1066 * string + submit_value: value of submit button
1067 * string + updated_message: default updated message. Can be false
1068 *
1069 * @return N/A
1070 */
1071
1072 function acf_form( $options = false )
1073 {
1074 global $post;
1075
1076
1077 // defaults
1078 $defaults = array(
1079 'post_id' => false,
1080 'field_groups' => array(),
1081 'form' => true,
1082 'form_attributes' => array(
1083 'class' => ''
1084 ),
1085 'return' => add_query_arg( 'updated', 'true', get_permalink() ),
1086 'html_before_fields' => '',
1087 'html_after_fields' => '',
1088 'submit_value' => 'Update',
1089 'updated_message' => 'Post updated.',
1090 );
1091
1092
1093 // merge defaults with options
1094 if( $options && is_array($options) )
1095 {
1096 $options = array_merge($defaults, $options);
1097 }
1098 else
1099 {
1100 $options = $defaults;
1101 }
1102
1103
1104 // filter post_id
1105 $options['post_id'] = acf_filter_post_id( $options['post_id'] );
1106
1107
1108 // register post box
1109 if( empty($options['field_groups']) )
1110 {
1111 // get field groups
1112 $filter = array(
1113 'post_id' => $options['post_id']
1114 );
1115
1116
1117 if( strpos($options['post_id'], 'user_') !== false )
1118 {
1119 $user_id = str_replace('user_', '', $options['post_id']);
1120 $filter = array(
1121 'ef_user' => $user_id
1122 );
1123 }
1124 elseif( strpos($options['post_id'], 'taxonomy_') !== false )
1125 {
1126 $taxonomy_id = str_replace('taxonomy_', '', $options['post_id']);
1127 $filter = array(
1128 'ef_taxonomy' => $taxonomy_id
1129 );
1130 }
1131
1132
1133 $options['field_groups'] = array();
1134 $options['field_groups'] = apply_filters( 'acf/location/match_field_groups', $options['field_groups'], $filter );
1135 }
1136
1137
1138 // updated message
1139 if(isset($_GET['updated']) && $_GET['updated'] == 'true' && $options['updated_message'])
1140 {
1141 echo '<div id="message" class="updated"><p>' . $options['updated_message'] . '</p></div>';
1142 }
1143
1144
1145 // Javascript
1146 $script_post_id = is_numeric($options['post_id']) ? $options['post_id'] : 0;
1147 echo '<script type="text/javascript">acf.post_id = ' . $script_post_id . '; </script>';
1148
1149
1150 // display form
1151 if( $options['form'] ): ?>
1152 <form action="" id="post" method="post" <?php if($options['form_attributes']){foreach($options['form_attributes'] as $k => $v){echo $k . '="' . $v .'" '; }} ?>>
1153 <?php endif; ?>
1154
1155 <div style="display:none">
1156 <input type="hidden" name="acf_nonce" value="<?php echo wp_create_nonce( 'input' ); ?>" />
1157 <input type="hidden" name="post_id" value="<?php echo $options['post_id']; ?>" />
1158 <input type="hidden" name="return" value="<?php echo $options['return']; ?>" />
1159 <?php wp_editor('', 'acf_settings'); ?>
1160 </div>
1161
1162 <div id="poststuff">
1163 <?php
1164
1165 // html before fields
1166 echo $options['html_before_fields'];
1167
1168
1169 $acfs = apply_filters('acf/get_field_groups', array());
1170
1171 if( is_array($acfs) ){ foreach( $acfs as $acf ){
1172
1173 // only add the chosen field groups
1174 if( !in_array( $acf['id'], $options['field_groups'] ) )
1175 {
1176 continue;
1177 }
1178
1179
1180 // load options
1181 $acf['options'] = apply_filters('acf/field_group/get_options', array(), $acf['id']);
1182
1183
1184 // load fields
1185 $fields = apply_filters('acf/field_group/get_fields', array(), $acf['id']);
1186
1187
1188 echo '<div id="acf_' . $acf['id'] . '" class="postbox acf_postbox">';
1189 echo '<h3 class="hndle"><span>' . $acf['title'] . '</span></h3>';
1190 echo '<div class="inside">';
1191 echo '<div class="options" data-layout="' . $acf['options']['layout'] . '" data-show="1"></div>';
1192
1193 do_action('acf/create_fields', $fields, $options['post_id']);
1194
1195 echo '</div></div>';
1196
1197 }}
1198
1199
1200 // html after fields
1201 echo $options['html_after_fields'];
1202
1203 ?>
1204
1205 <?php if( $options['form'] ): ?>
1206 <!-- Submit -->
1207 <div class="field">
1208 <input type="submit" value="<?php echo $options['submit_value']; ?>" />
1209 </div>
1210 <!-- / Submit -->
1211 <?php endif; ?>
1212
1213 </div><!-- <div id="poststuff"> -->
1214
1215 <?php if( $options['form'] ): ?>
1216 </form>
1217 <?php endif;
1218 }
1219
1220
1221 /*
1222 * update_field()
1223 *
1224 * This function will update a value in the database
1225 *
1226 * @type function
1227 * @since 3.1.9
1228 * @date 29/01/13
1229 *
1230 * @param mixed $field_name: the name of the field - 'sub_heading'
1231 * @param mixed $value: the value to save in the database. The variable type is dependant on the field type
1232 * @param mixed $post_id: the post_id of which the value is saved against
1233 *
1234 * @return N/A
1235 */
1236
1237 function update_field( $field_key, $value, $post_id = false )
1238 {
1239 // filter post_id
1240 $post_id = acf_filter_post_id( $post_id );
1241
1242
1243 // vars
1244 $options = array(
1245 'load_value' => false,
1246 'format_value' => false
1247 );
1248
1249 $field = get_field_object( $field_key, $post_id, $options);
1250
1251
1252 if( !is_array($field) )
1253 {
1254 $field = array(
1255 'type' => 'none',
1256 'name' => $field_key
1257 );
1258 }
1259
1260
1261 // sub fields? They need formatted data
1262 if( $field['type'] == 'repeater' )
1263 {
1264 $value = acf_convert_field_names_to_keys( $value, $field );
1265 }
1266 elseif( $field['type'] == 'flexible_content' )
1267 {
1268 if( $field['layouts'] )
1269 {
1270 foreach( $field['layouts'] as $layout )
1271 {
1272 $value = acf_convert_field_names_to_keys( $value, $layout );
1273 }
1274 }
1275 }
1276
1277
1278 // save
1279 do_action('acf/update_value', $value, $post_id, $field );
1280
1281
1282 return true;
1283
1284 }
1285
1286
1287 /*
1288 * delete_field()
1289 *
1290 * This function will remove a value from the database
1291 *
1292 * @type function
1293 * @since 3.1.9
1294 * @date 29/01/13
1295 *
1296 * @param mixed $field_name: the name of the field - 'sub_heading'
1297 * @param mixed $post_id: the post_id of which the value is saved against
1298 *
1299 * @return N/A
1300 */
1301
1302 function delete_field( $field_name, $post_id )
1303 {
1304 do_action('acf/delete_value', $post_id, $field_name );
1305 }
1306
1307
1308 /*
1309 * create_field()
1310 *
1311 * This function will creat the HTML for a field
1312 *
1313 * @type function
1314 * @since 4.0.0
1315 * @date 17/03/13
1316 *
1317 * @param array $field - an array containing all the field attributes
1318 *
1319 * @return N/A
1320 */
1321
1322 function create_field( $field )
1323 {
1324 do_action('acf/create_field', $field );
1325 }
1326
1327
1328 /*
1329 * acf_convert_field_names_to_keys()
1330 *
1331 * Helper for the update_field function
1332 *
1333 * @type function
1334 * @since 4.0.0
1335 * @date 17/03/13
1336 *
1337 * @param array $value: the value returned via get_field
1338 * @param array $field: the field or layout to find sub fields from
1339 *
1340 * @return N/A
1341 */
1342
1343 function acf_convert_field_names_to_keys( $value, $field )
1344 {
1345 // only if $field has sub fields
1346 if( !isset($field['sub_fields']) )
1347 {
1348 return $value;
1349 }
1350
1351
1352 // define sub field keys
1353 $sub_fields = array();
1354 if( $field['sub_fields'] )
1355 {
1356 foreach( $field['sub_fields'] as $sub_field )
1357 {
1358 $sub_fields[ $sub_field['name'] ] = $sub_field;
1359 }
1360 }
1361
1362
1363 // loop through the values and format the array to use sub field keys
1364 if( is_array($value) )
1365 {
1366 foreach( $value as $row_i => $row)
1367 {
1368 if( $row )
1369 {
1370 foreach( $row as $sub_field_name => $sub_field_value )
1371 {
1372 // sub field must exist!
1373 if( !isset($sub_fields[ $sub_field_name ]) )
1374 {
1375 continue;
1376 }
1377
1378
1379 // vars
1380 $sub_field = $sub_fields[ $sub_field_name ];
1381 $sub_field_value = acf_convert_field_names_to_keys( $sub_field_value, $sub_field );
1382
1383
1384 // set new value
1385 $value[$row_i][ $sub_field['key'] ] = $sub_field_value;
1386
1387
1388 // unset old value
1389 unset( $value[$row_i][$sub_field_name] );
1390
1391
1392 }
1393 // foreach( $row as $sub_field_name => $sub_field_value )
1394 }
1395 // if( $row )
1396 }
1397 // foreach( $value as $row_i => $row)
1398 }
1399 // if( $value )
1400
1401
1402 return $value;
1403
1404 }
1405
1406
1407
1408 /*
1409 * Depreceated Functions
1410 *
1411 * @description:
1412 * @created: 23/07/12
1413 */
1414
1415
1416 /*--------------------------------------------------------------------------------------
1417 *
1418 * reset_the_repeater_field
1419 *
1420 * @author Elliot Condon
1421 * @depreciated: 3.3.4 - now use has_sub_field
1422 * @since 1.0.3
1423 *
1424 *-------------------------------------------------------------------------------------*/
1425
1426 function reset_the_repeater_field()
1427 {
1428 // do nothing
1429 }
1430
1431
1432 /*--------------------------------------------------------------------------------------
1433 *
1434 * the_repeater_field
1435 *
1436 * @author Elliot Condon
1437 * @depreciated: 3.3.4 - now use has_sub_field
1438 * @since 1.0.3
1439 *
1440 *-------------------------------------------------------------------------------------*/
1441
1442 function the_repeater_field($field_name, $post_id = false)
1443 {
1444 return has_sub_field($field_name, $post_id);
1445 }
1446
1447
1448 /*--------------------------------------------------------------------------------------
1449 *
1450 * the_flexible_field
1451 *
1452 * @author Elliot Condon
1453 * @depreciated: 3.3.4 - now use has_sub_field
1454 * @since 3.?.?
1455 *
1456 *-------------------------------------------------------------------------------------*/
1457
1458 function the_flexible_field($field_name, $post_id = false)
1459 {
1460 return has_sub_field($field_name, $post_id);
1461 }
1462
1463
1464 ?>