/acf.php

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