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