PluginProbe
Advanced Custom Fields (ACF®) / 4.4.12
Advanced Custom Fields (ACF®) v4.4.12
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 / acf.php
acf.php
984 lines 20.6 KB
No matching file
Up and down to move Enter to open Esc to close
Raw Download Zip
1 <?php
2 /*
3 Plugin Name: Advanced Custom Fields
4 Plugin URI: http://www.advancedcustomfields.com/
5 Description: Customise WordPress with powerful, professional and intuitive fields
6 Version: 4.4.12
7 Author: Elliot Condon
8 Author URI: http://www.elliotcondon.com/
9 License: GPL
10 Copyright: Elliot Condon
11 Text Domain: acf
12 Domain Path: /lang
13 */
14
15 if( !class_exists('acf') ):
16
17 class acf {
18
19 /** @var string The plugin version number */
20 var $version = '4.4.12';
21
22
23 /** @var array The plugin settings array */
24 var $settings = array();
25
26
27 /*
28 * Constructor
29 *
30 * This function will construct all the neccessary actions, filters and functions for the ACF plugin to work
31 *
32 * @type function
33 * @date 23/06/12
34 * @since 1.0.0
35 *
36 * @param N/A
37 * @return N/A
38 */
39
40 function __construct() {
41
42 // helpers
43 add_filter('acf/helpers/get_path', array($this, 'helpers_get_path'), 1, 1);
44 add_filter('acf/helpers/get_dir', array($this, 'helpers_get_dir'), 1, 1);
45
46
47 // vars
48 $this->settings = array(
49
50 // basic
51 'name' => __('Advanced Custom Fields', 'acf'),
52 'version' => $this->version,
53
54 // urls
55 'file' => __FILE__,
56 'path' => apply_filters('acf/helpers/get_path', __FILE__),
57 'dir' => apply_filters('acf/helpers/get_dir', __FILE__),
58 'basename' => plugin_basename( __FILE__ ),
59
60 // options
61 'include_3rd_party' => false
62 );
63
64
65 // set text domain
66 load_textdomain('acf', $this->settings['path'] . 'lang/acf-' . get_locale() . '.mo');
67
68
69 // actions
70 add_action('init', array($this, 'init'), 1);
71 add_action('acf/pre_save_post', array($this, 'save_post_lock'), 0);
72 add_action('acf/pre_save_post', array($this, 'save_post_unlock'), 999);
73 add_action('acf/save_post', array($this, 'save_post_lock'), 0);
74 add_action('acf/save_post', array($this, 'save_post'), 10);
75 add_action('acf/save_post', array($this, 'save_post_unlock'), 999);
76 add_action('acf/create_fields', array($this, 'create_fields'), 1, 2);
77
78
79 // filters
80 add_filter('acf/get_info', array($this, 'get_info'), 1, 1);
81 add_filter('acf/parse_types', array($this, 'parse_types'), 1, 1);
82 add_filter('acf/get_post_types', array($this, 'get_post_types'), 1, 3);
83 add_filter('acf/get_taxonomies_for_select', array($this, 'get_taxonomies_for_select'), 1, 2);
84 add_filter('acf/get_image_sizes', array($this, 'get_image_sizes'), 1, 1);
85 add_filter('acf/get_post_id', array($this, 'get_post_id'), 1, 1);
86
87
88 // includes
89 $this->include_before_theme();
90 add_action('after_setup_theme', array($this, 'include_after_theme'), 1);
91 add_action('after_setup_theme', array($this, 'include_3rd_party'), 1);
92
93 }
94
95
96 /*
97 * helpers_get_path
98 *
99 * This function will calculate the path to a file
100 *
101 * @type function
102 * @date 30/01/13
103 * @since 3.6.0
104 *
105 * @param $file (file) a reference to the file
106 * @return (string)
107 */
108
109 function helpers_get_path( $file )
110 {
111 return trailingslashit(dirname($file));
112 }
113
114
115 /*
116 * helpers_get_dir
117 *
118 * This function will calculate the directory (URL) to a file
119 *
120 * @type function
121 * @date 30/01/13
122 * @since 3.6.0
123 *
124 * @param $file (file) a reference to the file
125 * @return (string)
126 */
127
128 function helpers_get_dir( $file )
129 {
130 $dir = trailingslashit(dirname($file));
131 $count = 0;
132
133
134 // sanitize for Win32 installs
135 $dir = str_replace('\\' ,'/', $dir);
136
137
138 // if file is in plugins folder
139 $wp_plugin_dir = str_replace('\\' ,'/', WP_PLUGIN_DIR);
140 $dir = str_replace($wp_plugin_dir, plugins_url(), $dir, $count);
141
142
143 if( $count < 1 )
144 {
145 // if file is in wp-content folder
146 $wp_content_dir = str_replace('\\' ,'/', WP_CONTENT_DIR);
147 $dir = str_replace($wp_content_dir, content_url(), $dir, $count);
148 }
149
150
151 if( $count < 1 )
152 {
153 // if file is in ??? folder
154 $wp_dir = str_replace('\\' ,'/', ABSPATH);
155 $dir = str_replace($wp_dir, site_url('/'), $dir);
156 }
157
158
159 return $dir;
160 }
161
162
163 /*
164 * acf/get_post_id
165 *
166 * A helper function to filter the post_id variable.
167 *
168 * @type filter
169 * @date 27/05/13
170 *
171 * @param {mixed} $post_id
172 * @return {mixed} $post_id
173 */
174
175 function get_post_id( $post_id ) {
176
177 // if not $post_id, load queried object
178 if( !$post_id ) {
179
180 // try for global post (needed for setup_postdata)
181 $post_id = (int) get_the_ID();
182
183
184 // try for current screen
185 if( !$post_id ) {
186
187 $post_id = get_queried_object();
188
189 }
190
191 }
192
193
194 // $post_id may be an object
195 if( is_object($post_id) ) {
196
197 // user
198 if( isset($post_id->roles, $post_id->ID) ) {
199
200 $post_id = 'user_' . $post_id->ID;
201
202 // term
203 } elseif( isset($post_id->taxonomy, $post_id->term_id) ) {
204
205 $post_id = $post_id->taxonomy . '_' . $post_id->term_id;
206
207 // comment
208 } elseif( isset($post_id->comment_ID) ) {
209
210 $post_id = 'comment_' . $post_id->comment_ID;
211
212 // post
213 } elseif( isset($post_id->ID) ) {
214
215 $post_id = $post_id->ID;
216
217 // default
218 } else {
219
220 $post_id = 0;
221
222 }
223
224 }
225
226
227 // allow for option == options
228 if( $post_id === 'option' ) {
229
230 $post_id = 'options';
231
232 }
233
234
235 /*
236 * Override for preview
237 *
238 * If the $_GET['preview_id'] is set, then the user wants to see the preview data.
239 * There is also the case of previewing a page with post_id = 1, but using get_field
240 * to load data from another post_id.
241 * In this case, we need to make sure that the autosave revision is actually related
242 * to the $post_id variable. If they match, then the autosave data will be used, otherwise,
243 * the user wants to load data from a completely different post_id
244 */
245
246 if( isset($_GET['preview_id']) ) {
247
248 $autosave = wp_get_post_autosave( $_GET['preview_id'] );
249
250 if( $autosave && $autosave->post_parent == $post_id ) {
251
252 $post_id = (int) $autosave->ID;
253
254 }
255
256 }
257
258
259 // return
260 return $post_id;
261 }
262
263
264 /*
265 * get_info
266 *
267 * This function will return a setting from the settings array
268 *
269 * @type function
270 * @date 24/01/13
271 * @since 3.6.0
272 *
273 * @param $i (string) the setting to get
274 * @return (mixed)
275 */
276
277 function get_info( $i )
278 {
279 // vars
280 $return = false;
281
282
283 // specific
284 if( isset($this->settings[ $i ]) )
285 {
286 $return = $this->settings[ $i ];
287 }
288
289
290 // all
291 if( $i == 'all' )
292 {
293 $return = $this->settings;
294 }
295
296
297 // return
298 return $return;
299 }
300
301
302 /*
303 * parse_types
304 *
305 * @description: helper function to set the 'types' of variables
306 * @since: 2.0.4
307 * @created: 9/12/12
308 */
309
310 function parse_types( $value )
311 {
312 // vars
313 $restricted = array(
314 'label',
315 'name',
316 '_name',
317 'value',
318 'instructions'
319 );
320
321
322 // is value another array?
323 if( is_array($value) )
324 {
325 foreach( $value as $k => $v )
326 {
327 // bail early for restricted pieces
328 if( in_array($k, $restricted, true) )
329 {
330 continue;
331 }
332
333
334 // filter piece
335 $value[ $k ] = apply_filters( 'acf/parse_types', $v );
336 }
337 }
338 else
339 {
340 // string
341 if( is_string($value) )
342 {
343 $value = trim( $value );
344 }
345
346
347 // numbers
348 if( is_numeric($value) )
349 {
350 // check for non numeric characters
351 if( preg_match('/[^0-9]/', $value) )
352 {
353 // leave value if it contains such characters: . + - e
354 //$value = floatval( $value );
355 }
356 else
357 {
358 $value = intval( $value );
359 }
360 }
361 }
362
363
364 // return
365 return $value;
366 }
367
368
369 /*
370 * include_before_theme
371 *
372 * This function will include core files before the theme's functions.php file has been excecuted.
373 *
374 * @type action (plugins_loaded)
375 * @date 3/09/13
376 * @since 4.3.0
377 *
378 * @param N/A
379 * @return N/A
380 */
381
382 function include_before_theme()
383 {
384 // incudes
385 include_once('core/api.php');
386
387 include_once('core/controllers/input.php');
388 include_once('core/controllers/location.php');
389 include_once('core/controllers/field_group.php');
390
391
392 // admin only includes
393 if( is_admin() )
394 {
395 include_once('core/controllers/post.php');
396 include_once('core/controllers/revisions.php');
397 include_once('core/controllers/everything_fields.php');
398 include_once('core/controllers/field_groups.php');
399 }
400
401
402 // register fields
403 include_once('core/fields/_functions.php');
404 include_once('core/fields/_base.php');
405
406 include_once('core/fields/text.php');
407 include_once('core/fields/textarea.php');
408 include_once('core/fields/number.php');
409 include_once('core/fields/email.php');
410 include_once('core/fields/password.php');
411
412 include_once('core/fields/wysiwyg.php');
413 include_once('core/fields/image.php');
414 include_once('core/fields/file.php');
415
416 include_once('core/fields/select.php');
417 include_once('core/fields/checkbox.php');
418 include_once('core/fields/radio.php');
419 include_once('core/fields/true_false.php');
420
421 include_once('core/fields/page_link.php');
422 include_once('core/fields/post_object.php');
423 include_once('core/fields/relationship.php');
424 include_once('core/fields/taxonomy.php');
425 include_once('core/fields/user.php');
426
427 include_once('core/fields/google-map.php');
428 include_once('core/fields/date_picker/date_picker.php');
429 include_once('core/fields/color_picker.php');
430
431 include_once('core/fields/message.php');
432 include_once('core/fields/tab.php');
433
434 }
435
436
437 /*
438 * include_3rd_party
439 *
440 * This function will include 3rd party add-ons
441 *
442 * @type function
443 * @date 29/01/2014
444 * @since 5.0.0
445 *
446 * @param N/A
447 * @return N/A
448 */
449
450 function include_3rd_party() {
451
452 // run only once
453 if( $this->settings['include_3rd_party'] )
454 {
455 return false;
456 }
457
458
459 // update setting
460 $this->settings['include_3rd_party'] = true;
461
462
463 // include 3rd party fields
464 do_action('acf/register_fields');
465
466 }
467
468
469 /*
470 * include_after_theme
471 *
472 * This function will include core files after the theme's functions.php file has been excecuted.
473 *
474 * @type action (after_setup_theme)
475 * @date 3/09/13
476 * @since 4.3.0
477 *
478 * @param N/A
479 * @return N/A
480 */
481
482 function include_after_theme() {
483
484 // early access
485 if( defined('ACF_EARLY_ACCESS') ) {
486 include_once('core/early-access.php');
487 }
488
489
490
491 // bail early if user has defined LITE_MODE as true
492 if( defined('ACF_LITE') && ACF_LITE )
493 {
494 return;
495 }
496
497
498 // admin only includes
499 if( is_admin() )
500 {
501 include_once('core/controllers/export.php');
502 include_once('core/controllers/addons.php');
503 include_once('core/controllers/third_party.php');
504 include_once('core/controllers/upgrade.php');
505 }
506
507 }
508
509
510 /*
511 * init
512 *
513 * This function is called during the 'init' action and will do things such as:
514 * create post_type, register scripts, add actions / filters
515 *
516 * @type action (init)
517 * @date 23/06/12
518 * @since 1.0.0
519 *
520 * @param N/A
521 * @return N/A
522 */
523
524 function init()
525 {
526
527 // Create ACF post type
528 $labels = array(
529 'name' => __( 'Field&nbsp;Groups', 'acf' ),
530 'singular_name' => __( 'Advanced Custom Fields', 'acf' ),
531 'add_new' => __( 'Add New' , 'acf' ),
532 'add_new_item' => __( 'Add New Field Group' , 'acf' ),
533 'edit_item' => __( 'Edit Field Group' , 'acf' ),
534 'new_item' => __( 'New Field Group' , 'acf' ),
535 'view_item' => __('View Field Group', 'acf'),
536 'search_items' => __('Search Field Groups', 'acf'),
537 'not_found' => __('No Field Groups found', 'acf'),
538 'not_found_in_trash' => __('No Field Groups found in Trash', 'acf'),
539 );
540
541 register_post_type('acf', array(
542 'labels' => $labels,
543 'public' => false,
544 'show_ui' => true,
545 '_builtin' => false,
546 'capability_type' => 'page',
547 'hierarchical' => true,
548 'rewrite' => false,
549 'query_var' => "acf",
550 'supports' => array(
551 'title',
552 ),
553 'show_in_menu' => false,
554 ));
555
556
557 // min
558 $min = defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ? '' : '.min';
559
560
561 // register acf scripts
562 $scripts = array();
563 $scripts[] = array(
564 'handle' => 'acf-field-group',
565 'src' => $this->settings['dir'] . "js/field-group{$min}.js",
566 'deps' => array('jquery')
567 );
568 $scripts[] = array(
569 'handle' => 'acf-input',
570 'src' => $this->settings['dir'] . "js/input{$min}.js",
571 'deps' => array('jquery', 'jquery-ui-core', 'jquery-ui-datepicker')
572 );
573
574
575 foreach( $scripts as $script )
576 {
577 wp_register_script( $script['handle'], $script['src'], $script['deps'], $this->settings['version'] );
578 }
579
580
581 // register acf styles
582 $styles = array(
583 'acf' => $this->settings['dir'] . 'css/acf.css',
584 'acf-field-group' => $this->settings['dir'] . 'css/field-group.css',
585 'acf-global' => $this->settings['dir'] . 'css/global.css',
586 'acf-input' => $this->settings['dir'] . 'css/input.css',
587 'acf-datepicker' => $this->settings['dir'] . 'core/fields/date_picker/style.date_picker.css',
588 );
589
590 foreach( $styles as $k => $v )
591 {
592 wp_register_style( $k, $v, false, $this->settings['version'] );
593 }
594
595
596 // bail early if user has defined LITE_MODE as true
597 if( defined('ACF_LITE') && ACF_LITE )
598 {
599 return;
600 }
601
602
603 // admin only
604 if( is_admin() )
605 {
606 add_action('admin_menu', array($this,'admin_menu'));
607 add_action('admin_head', array($this,'admin_head'));
608 add_filter('post_updated_messages', array($this, 'post_updated_messages'));
609 }
610 }
611
612
613 /*
614 * admin_menu
615 *
616 * @description:
617 * @since 1.0.0
618 * @created: 23/06/12
619 */
620
621 function admin_menu()
622 {
623 add_menu_page(__("Custom Fields",'acf'), __("Custom Fields",'acf'), 'manage_options', 'edit.php?post_type=acf', false, false, '80.025');
624 }
625
626
627 /*
628 * post_updated_messages
629 *
630 * @description: messages for saving a field group
631 * @since 1.0.0
632 * @created: 23/06/12
633 */
634
635 function post_updated_messages( $messages )
636 {
637 global $post, $post_ID;
638
639 $messages['acf'] = array(
640 0 => '', // Unused. Messages start at index 1.
641 1 => __('Field group updated.', 'acf'),
642 2 => __('Custom field updated.', 'acf'),
643 3 => __('Custom field deleted.', 'acf'),
644 4 => __('Field group updated.', 'acf'),
645 /* translators: %s: date and time of the revision */
646 5 => isset($_GET['revision']) ? sprintf( __('Field group restored to revision from %s', 'acf'), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
647 6 => __('Field group published.', 'acf'),
648 7 => __('Field group saved.', 'acf'),
649 8 => __('Field group submitted.', 'acf'),
650 9 => __('Field group scheduled for.', 'acf'),
651 10 => __('Field group draft updated.', 'acf'),
652 );
653
654 return $messages;
655 }
656
657
658 /*--------------------------------------------------------------------------------------
659 *
660 * admin_head
661 *
662 * @author Elliot Condon
663 * @since 1.0.0
664 *
665 *-------------------------------------------------------------------------------------*/
666
667 function admin_head()
668 {
669 ?>
670 <style type="text/css">
671 #adminmenu #toplevel_page_edit-post_type-acf a[href="edit.php?post_type=acf&page=acf-upgrade"]{ display: none; }
672 #adminmenu #toplevel_page_edit-post_type-acf .wp-menu-image { background-position: 1px -33px; }
673 #adminmenu #toplevel_page_edit-post_type-acf:hover .wp-menu-image,
674 #adminmenu #toplevel_page_edit-post_type-acf.wp-menu-open .wp-menu-image { background-position: 1px -1px; }
675 </style>
676 <?php
677 }
678
679
680 /*
681 * get_taxonomies_for_select
682 *
683 * @description:
684 * @since: 3.6
685 * @created: 27/01/13
686 */
687
688 function get_taxonomies_for_select( $choices, $simple_value = false )
689 {
690 // vars
691 $post_types = get_post_types();
692
693
694 if($post_types)
695 {
696 foreach($post_types as $post_type)
697 {
698 $post_type_object = get_post_type_object($post_type);
699 $taxonomies = get_object_taxonomies($post_type);
700 if($taxonomies)
701 {
702 foreach($taxonomies as $taxonomy)
703 {
704 if(!is_taxonomy_hierarchical($taxonomy)) continue;
705 $terms = get_terms($taxonomy, array('hide_empty' => false));
706 if($terms)
707 {
708 foreach($terms as $term)
709 {
710 $value = $taxonomy . ':' . $term->term_id;
711
712 if( $simple_value )
713 {
714 $value = $term->term_id;
715 }
716
717 $choices[$post_type_object->label . ': ' . $taxonomy][$value] = $term->name;
718 }
719 }
720 }
721 }
722 }
723 }
724
725 return $choices;
726 }
727
728
729 /*
730 * get_post_types
731 *
732 * @description:
733 * @since: 3.5.5
734 * @created: 16/12/12
735 */
736
737 function get_post_types( $post_types, $exclude = array(), $include = array() )
738 {
739 // get all custom post types
740 $post_types = array_merge($post_types, get_post_types());
741
742
743 // core include / exclude
744 $acf_includes = array_merge( array(), $include );
745 $acf_excludes = array_merge( array( 'acf', 'revision', 'nav_menu_item' ), $exclude );
746
747
748 // include
749 foreach( $acf_includes as $p )
750 {
751 if( post_type_exists($p) )
752 {
753 $post_types[ $p ] = $p;
754 }
755 }
756
757
758 // exclude
759 foreach( $acf_excludes as $p )
760 {
761 unset( $post_types[ $p ] );
762 }
763
764
765 return $post_types;
766
767 }
768
769
770 /*
771 * get_image_sizes
772 *
773 * @description: returns an array holding all the image sizes
774 * @since 3.2.8
775 * @created: 6/07/12
776 */
777
778 function get_image_sizes( $sizes )
779 {
780 // find all sizes
781 $all_sizes = get_intermediate_image_sizes();
782
783
784 // define default sizes
785 $sizes = array_merge($sizes, array(
786 'thumbnail' => __("Thumbnail",'acf'),
787 'medium' => __("Medium",'acf'),
788 'large' => __("Large",'acf'),
789 'full' => __("Full",'acf')
790 ));
791
792
793 // add extra registered sizes
794 foreach( $all_sizes as $size )
795 {
796 if( !isset($sizes[ $size ]) )
797 {
798 $sizes[ $size ] = ucwords( str_replace('-', ' ', $size) );
799 }
800 }
801
802
803 // return array
804 return $sizes;
805 }
806
807
808 /*
809 * render_fields_for_input
810 *
811 * @description:
812 * @since 3.1.6
813 * @created: 23/06/12
814 */
815
816 function create_fields( $fields, $post_id )
817 {
818 if( is_array($fields) ){ foreach( $fields as $field ){
819
820 // if they didn't select a type, skip this field
821 if( !$field || !$field['type'] || $field['type'] == 'null' )
822 {
823 continue;
824 }
825
826
827 // set value
828 if( !isset($field['value']) )
829 {
830 $field['value'] = apply_filters('acf/load_value', false, $post_id, $field);
831 $field['value'] = apply_filters('acf/format_value', $field['value'], $post_id, $field);
832 }
833
834
835 // required
836 $required_class = "";
837 $required_label = "";
838
839 if( $field['required'] )
840 {
841 $required_class = ' required';
842 $required_label = ' <span class="required">*</span>';
843 }
844
845
846 echo '<div id="acf-' . $field['name'] . '" class="field field_type-' . $field['type'] . ' field_key-' . $field['key'] . $required_class . '" data-field_name="' . $field['name'] . '" data-field_key="' . $field['key'] . '" data-field_type="' . $field['type'] . '">';
847
848 echo '<p class="label">';
849 echo '<label for="' . $field['id'] . '">' . $field['label'] . $required_label . '</label>';
850 echo $field['instructions'];
851 echo '</p>';
852
853 $field['name'] = 'fields[' . $field['key'] . ']';
854 do_action('acf/create_field', $field, $post_id);
855
856 echo '</div>';
857
858 }}
859
860 }
861
862
863 /*
864 * save_post_lock
865 *
866 * This action sets a global variable which locks the ACF save functions to this ID.
867 * This prevents an inifinite loop if a user was to hook into the save and create a new post
868 *
869 * @type function
870 * @date 16/07/13
871 *
872 * @param {int} $post_id
873 * @return {int} $post_id
874 */
875
876 function save_post_lock( $post_id )
877 {
878 $GLOBALS['acf_save_lock'] = $post_id;
879
880 return $post_id;
881 }
882
883
884 /*
885 * save_post_unlock
886 *
887 * This action sets a global variable which unlocks the ACF save functions to this ID.
888 * This prevents an inifinite loop if a user was to hook into the save and create a new post
889 *
890 * @type function
891 * @date 16/07/13
892 *
893 * @param {int} $post_id
894 * @return {int} $post_id
895 */
896
897 function save_post_unlock( $post_id )
898 {
899 $GLOBALS['acf_save_lock'] = false;
900
901 return $post_id;
902 }
903
904
905 /*
906 * save_post
907 *
908 * @description:
909 * @since: 3.6
910 * @created: 28/01/13
911 */
912
913 function save_post( $post_id )
914 {
915
916 // load from post
917 if( !isset($_POST['fields']) )
918 {
919 return $post_id;
920 }
921
922
923 // loop through and save
924 if( !empty($_POST['fields']) )
925 {
926 // loop through and save $_POST data
927 foreach( $_POST['fields'] as $k => $v )
928 {
929 // get field
930 $f = apply_filters('acf/load_field', false, $k );
931
932 // update field
933 do_action('acf/update_value', $v, $post_id, $f );
934
935 }
936 // foreach($fields as $key => $value)
937 }
938 // if($fields)
939
940
941 return $post_id;
942 }
943
944
945 }
946
947
948 /*
949 * acf
950 *
951 * The main function responsible for returning the one true acf Instance to functions everywhere.
952 * Use this function like you would a global variable, except without needing to declare the global.
953 *
954 * Example: <?php $acf = acf(); ?>
955 *
956 * @type function
957 * @date 4/09/13
958 * @since 4.3.0
959 *
960 * @param N/A
961 * @return (object)
962 */
963
964 function acf()
965 {
966 global $acf;
967
968 if( !isset($acf) )
969 {
970 $acf = new acf();
971 }
972
973 return $acf;
974 }
975
976
977 // initialize
978 acf();
979
980
981 endif; // class_exists check
982
983 ?>
984