PageRenderTime 75ms CodeModel.GetById 41ms RepoModel.GetById 1ms app.codeStats 0ms

/pwrblog/wp-content/plugins/advanced-custom-fields/acf.php

https://bitbucket.org/theshipswakecreative/powersportswraps
PHP | 1618 lines | 820 code | 381 blank | 417 comment | 81 complexity | 54b98c869f2759a1b26e8e175c3fb07d MD5 | raw file
Possible License(s): GPL-2.0, AGPL-1.0, LGPL-2.1
  1. <?php
  2. /*
  3. Plugin Name: Advanced Custom Fields
  4. Plugin URI: http://www.advancedcustomfields.com/
  5. Description: Fully customise WordPress edit screens with powerful fields. Boasting a professional interface and a powerfull API, itâ&#x20AC;&#x2122;s a must have for any web developer working with WordPress. Field types include: Wysiwyg, text, textarea, image, file, select, checkbox, page link, post object, date picker, color picker, repeater, flexible content, gallery and more!
  6. Version: 3.5.8.1
  7. Author: Elliot Condon
  8. Author URI: http://www.elliotcondon.com/
  9. License: GPL
  10. Copyright: Elliot Condon
  11. */
  12. include('core/api.php');
  13. $acf = new Acf();
  14. class Acf
  15. {
  16. var $dir,
  17. $path,
  18. $version,
  19. $upgrade_version,
  20. $fields,
  21. $cache,
  22. $defaults,
  23. // controllers
  24. $upgrade,
  25. $settings,
  26. $field_groups,
  27. $field_group,
  28. $input,
  29. $options_page,
  30. $everything_fields,
  31. $third_party,
  32. $location;
  33. /*
  34. * Constructor
  35. *
  36. * @description:
  37. * @since 1.0.0
  38. * @created: 23/06/12
  39. */
  40. function __construct()
  41. {
  42. // vars
  43. $this->path = plugin_dir_path(__FILE__);
  44. $this->dir = plugins_url('',__FILE__);
  45. $this->version = '3.5.8.1';
  46. $this->upgrade_version = '3.4.1'; // this is the latest version which requires an upgrade
  47. $this->cache = array(); // basic array cache to hold data throughout the page load
  48. $this->defaults = array(
  49. 'options_page' => array(
  50. 'capability' => 'edit_posts', // capability to view options page
  51. 'title' => __('Options','acf'), // title / menu name ('Site Options')
  52. 'pages' => array(), // an array of sub pages ('Header, Footer, Home, etc')
  53. ),
  54. 'activation_codes' => array(
  55. 'repeater' => '', // activation code for the repeater add-on (XXXX-XXXX-XXXX-XXXX)
  56. 'options_page' => '', // activation code for the options page add-on (XXXX-XXXX-XXXX-XXXX)
  57. 'flexible_content' => '', // activation code for the flexible content add-on (XXXX-XXXX-XXXX-XXXX)
  58. 'gallery' => '', // activation code for the gallery add-on (XXXX-XXXX-XXXX-XXXX)
  59. ),
  60. );
  61. // set text domain
  62. load_plugin_textdomain('acf', false, basename(dirname(__FILE__)).'/lang' );
  63. // controllers
  64. $this->setup_controllers();
  65. // actions
  66. add_action('init', array($this, 'init'));
  67. add_action('admin_menu', array($this,'admin_menu'));
  68. add_action('admin_head', array($this,'admin_head'));
  69. add_action('acf_save_post', array($this, 'acf_save_post'), 10); // save post, called from many places (api, input, everything, options)
  70. // action functions
  71. add_action('acf/create_field', array($this, 'create_field'), 1, 1);
  72. add_filter('acf/get_field_groups', array($this, 'get_field_groups'), 1, 1);
  73. //add_filter('acf/get_field', array($this, 'get_field'), 10, 1);
  74. // filters
  75. add_filter('acf_load_field', array($this, 'acf_load_field'), 1, 1);
  76. add_filter('post_updated_messages', array($this, 'post_updated_messages'));
  77. add_filter('acf_parse_value', array($this, 'acf_parse_value'));
  78. return true;
  79. }
  80. /*
  81. * Init
  82. *
  83. * @description:
  84. * @since 1.0.0
  85. * @created: 23/06/12
  86. */
  87. function init()
  88. {
  89. // setup defaults
  90. $this->defaults = apply_filters('acf_settings', $this->defaults);
  91. // allow for older filters
  92. $this->defaults['options_page']['title'] = apply_filters('acf_options_page_title', $this->defaults['options_page']['title']);
  93. // setup fields
  94. $this->setup_fields();
  95. // Create ACF post type
  96. $labels = array(
  97. 'name' => __( 'Field&nbsp;Groups', 'acf' ),
  98. 'singular_name' => __( 'Advanced Custom Fields', 'acf' ),
  99. 'add_new' => __( 'Add New' , 'acf' ),
  100. 'add_new_item' => __( 'Add New Field Group' , 'acf' ),
  101. 'edit_item' => __( 'Edit Field Group' , 'acf' ),
  102. 'new_item' => __( 'New Field Group' , 'acf' ),
  103. 'view_item' => __('View Field Group', 'acf'),
  104. 'search_items' => __('Search Field Groups', 'acf'),
  105. 'not_found' => __('No Field Groups found', 'acf'),
  106. 'not_found_in_trash' => __('No Field Groups found in Trash', 'acf'),
  107. );
  108. register_post_type('acf', array(
  109. 'labels' => $labels,
  110. 'public' => false,
  111. 'show_ui' => true,
  112. '_builtin' => false,
  113. 'capability_type' => 'page',
  114. 'hierarchical' => true,
  115. 'rewrite' => false,
  116. 'query_var' => "acf",
  117. 'supports' => array(
  118. 'title',
  119. ),
  120. 'show_in_menu' => false,
  121. ));
  122. // register acf scripts
  123. $scripts = array(
  124. 'acf-field-group' => $this->dir . '/js/field-group.js',
  125. 'acf-input' => $this->dir . '/js/input.php',
  126. 'acf-input-ajax' => $this->dir . '/js/input/ajax.js',
  127. 'acf-datepicker' => $this->dir . '/core/fields/date_picker/jquery.ui.datepicker.js',
  128. );
  129. foreach( $scripts as $k => $v )
  130. {
  131. wp_register_script( $k, $v, array('jquery'), $this->version );
  132. }
  133. // register acf styles
  134. $styles = array(
  135. 'acf' => $this->dir . '/css/acf.css',
  136. 'acf-field-group' => $this->dir . '/css/field-group.css',
  137. 'acf-global' => $this->dir . '/css/global.css',
  138. 'acf-input' => $this->dir . '/css/input.css',
  139. 'acf-datepicker' => $this->dir . '/core/fields/date_picker/style.date_picker.css',
  140. );
  141. foreach( $styles as $k => $v )
  142. {
  143. wp_register_style( $k, $v, false, $this->version );
  144. }
  145. }
  146. /*
  147. * get_cache
  148. *
  149. * @description: Simple ACF (once per page) cache
  150. * @since 3.1.9
  151. * @created: 23/06/12
  152. */
  153. function get_cache($key = false)
  154. {
  155. // key is required
  156. if( !$key )
  157. return false;
  158. // does cache at key exist?
  159. if( !isset($this->cache[$key]) )
  160. return false;
  161. // return cahced item
  162. return $this->cache[$key];
  163. }
  164. /*
  165. * set_cache
  166. *
  167. * @description: Simple ACF (once per page) cache
  168. * @since 3.1.9
  169. * @created: 23/06/12
  170. */
  171. function set_cache($key = false, $value = null)
  172. {
  173. // key is required
  174. if( !$key )
  175. return false;
  176. // update the cache array
  177. $this->cache[$key] = $value;
  178. // return true. Probably not needed
  179. return true;
  180. }
  181. /*
  182. * setup_fields
  183. *
  184. * @description: Create an array of field objects, including custom registered field types
  185. * @since 1.0.0
  186. * @created: 23/06/12
  187. */
  188. function setup_fields()
  189. {
  190. // include parent field
  191. include_once('core/fields/acf_field.php');
  192. // include child fields
  193. include_once('core/fields/acf_field.php');
  194. include_once('core/fields/tab.php');
  195. include_once('core/fields/text.php');
  196. include_once('core/fields/textarea.php');
  197. include_once('core/fields/wysiwyg.php');
  198. include_once('core/fields/image.php');
  199. include_once('core/fields/file.php');
  200. include_once('core/fields/number.php');
  201. include_once('core/fields/select.php');
  202. include_once('core/fields/checkbox.php');
  203. include_once('core/fields/radio.php');
  204. include_once('core/fields/true_false.php');
  205. include_once('core/fields/page_link.php');
  206. include_once('core/fields/post_object.php');
  207. include_once('core/fields/relationship.php');
  208. include_once('core/fields/date_picker/date_picker.php');
  209. include_once('core/fields/color_picker.php');
  210. // add child fields
  211. $this->fields['none'] = new acf_Field($this);
  212. $this->fields['tab'] = new acf_Tab($this);
  213. $this->fields['text'] = new acf_Text($this);
  214. $this->fields['textarea'] = new acf_Textarea($this);
  215. $this->fields['wysiwyg'] = new acf_Wysiwyg($this);
  216. $this->fields['image'] = new acf_Image($this);
  217. $this->fields['file'] = new acf_File($this);
  218. $this->fields['number'] = new acf_Number($this);
  219. $this->fields['select'] = new acf_Select($this);
  220. $this->fields['checkbox'] = new acf_Checkbox($this);
  221. $this->fields['radio'] = new acf_Radio($this);
  222. $this->fields['true_false'] = new acf_True_false($this);
  223. $this->fields['page_link'] = new acf_Page_link($this);
  224. $this->fields['post_object'] = new acf_Post_object($this);
  225. $this->fields['relationship'] = new acf_Relationship($this);
  226. $this->fields['date_picker'] = new acf_Date_picker($this);
  227. $this->fields['color_picker'] = new acf_Color_picker($this);
  228. // add repeater
  229. if($this->is_field_unlocked('repeater'))
  230. {
  231. include_once('core/fields/repeater.php');
  232. $this->fields['repeater'] = new acf_Repeater($this);
  233. }
  234. // add flexible content
  235. if($this->is_field_unlocked('flexible_content'))
  236. {
  237. include_once('core/fields/flexible_content.php');
  238. $this->fields['flexible_content'] = new acf_Flexible_content($this);
  239. }
  240. // add gallery
  241. if($this->is_field_unlocked('gallery'))
  242. {
  243. include_once('core/fields/gallery.php');
  244. $this->fields['gallery'] = new acf_Gallery($this);
  245. }
  246. // hook to load in third party fields
  247. $custom = apply_filters('acf_register_field',array());
  248. if(!empty($custom))
  249. {
  250. foreach($custom as $v)
  251. {
  252. //var_dump($v['url']);
  253. include($v['url']);
  254. $name = $v['class'];
  255. $custom_field = new $name($this);
  256. $this->fields[$custom_field->name] = $custom_field;
  257. }
  258. }
  259. }
  260. /*
  261. * setup_fields
  262. *
  263. * @description:
  264. * @since 3.2.6
  265. * @created: 23/06/12
  266. */
  267. function setup_controllers()
  268. {
  269. // Settings
  270. include_once('core/controllers/settings.php');
  271. $this->settings = new acf_settings($this);
  272. // upgrade
  273. include_once('core/controllers/upgrade.php');
  274. $this->upgrade = new acf_upgrade($this);
  275. // field_groups
  276. include_once('core/controllers/field_groups.php');
  277. $this->field_groups = new acf_field_groups($this);
  278. // field_group
  279. include_once('core/controllers/field_group.php');
  280. $this->field_group = new acf_field_group($this);
  281. // input
  282. include_once('core/controllers/input.php');
  283. $this->input = new acf_input($this);
  284. // options page
  285. include_once('core/controllers/options_page.php');
  286. $this->options_page = new acf_options_page($this);
  287. // everthing fields
  288. include_once('core/controllers/everything_fields.php');
  289. $this->everything_fields = new acf_everything_fields($this);
  290. // Third Party Compatibility
  291. include_once('core/controllers/third_party.php');
  292. $this->third_party = new acf_third_party($this);
  293. // Location
  294. include_once('core/controllers/location.php');
  295. $this->location = new acf_location($this);
  296. }
  297. /*
  298. * admin_menu
  299. *
  300. * @description:
  301. * @since 1.0.0
  302. * @created: 23/06/12
  303. */
  304. function admin_menu() {
  305. // add acf page to options menu
  306. add_utility_page(__("Custom Fields",'acf'), __("Custom Fields",'acf'), 'manage_options', 'edit.php?post_type=acf');
  307. }
  308. /*
  309. * post_updated_messages
  310. *
  311. * @description: messages for saving a field group
  312. * @since 1.0.0
  313. * @created: 23/06/12
  314. */
  315. function post_updated_messages( $messages )
  316. {
  317. global $post, $post_ID;
  318. $messages['acf'] = array(
  319. 0 => '', // Unused. Messages start at index 1.
  320. 1 => __('Field group updated.', 'acf'),
  321. 2 => __('Custom field updated.', 'acf'),
  322. 3 => __('Custom field deleted.', 'acf'),
  323. 4 => __('Field group updated.', 'acf'),
  324. /* translators: %s: date and time of the revision */
  325. 5 => isset($_GET['revision']) ? sprintf( __('Field group restored to revision from %s', 'acf'), wp_post_revision_title( (int) $_GET['revision'], false ) ) : false,
  326. 6 => __('Field group published.', 'acf'),
  327. 7 => __('Field group saved.', 'acf'),
  328. 8 => __('Field group submitted.', 'acf'),
  329. 9 => __('Field group scheduled for.', 'acf'),
  330. 10 => __('Field group draft updated.', 'acf'),
  331. );
  332. return $messages;
  333. }
  334. /*--------------------------------------------------------------------------------------
  335. *
  336. * admin_head
  337. *
  338. * @author Elliot Condon
  339. * @since 1.0.0
  340. *
  341. *-------------------------------------------------------------------------------------*/
  342. function admin_head()
  343. {
  344. // hide upgrade page from nav
  345. echo '<style type="text/css">
  346. #adminmenu #toplevel_page_edit-post_type-acf a[href="edit.php?post_type=acf&page=acf-upgrade"]{ display:none; }
  347. #adminmenu #toplevel_page_edit-post_type-acf .wp-menu-image { background-position: 1px -33px; }
  348. #adminmenu #toplevel_page_edit-post_type-acf:hover .wp-menu-image,
  349. #adminmenu #toplevel_page_edit-post_type-acf.wp-menu-open .wp-menu-image { background-position: 1px -1px; }
  350. </style>';
  351. }
  352. /*
  353. * get_field_groups
  354. *
  355. * @description:
  356. * @since: 3.5.7
  357. * @created: 12/01/13
  358. */
  359. function get_field_groups( $return )
  360. {
  361. // return must be an array
  362. if( !is_array($return) )
  363. {
  364. $return = array();
  365. }
  366. // get acf's
  367. $result = get_posts(array(
  368. 'numberposts' => -1,
  369. 'post_type' => 'acf',
  370. 'orderby' => 'menu_order title',
  371. 'order' => 'asc',
  372. 'suppress_filters' => false,
  373. ));
  374. // populate acfs
  375. if($result)
  376. {
  377. foreach($result as $acf)
  378. {
  379. $return[] = array(
  380. 'id' => $acf->ID,
  381. 'title' => get_the_title($acf->ID),
  382. 'fields' => $this->get_acf_fields($acf->ID),
  383. 'location' => $this->get_acf_location($acf->ID),
  384. 'options' => $this->get_acf_options($acf->ID),
  385. 'menu_order' => $acf->menu_order,
  386. );
  387. }
  388. }
  389. // hook to load in registered field groups
  390. //$return = apply_filters('acf_register_field_group', $return);
  391. return $return;
  392. }
  393. /*--------------------------------------------------------------------------------------
  394. *
  395. * get_acf_fields
  396. * - returns an array of fields for a acf object
  397. *
  398. * @author Elliot Condon
  399. * @since 1.0.0
  400. *
  401. *-------------------------------------------------------------------------------------*/
  402. function get_acf_fields($post_id)
  403. {
  404. // vars
  405. global $wpdb;
  406. $return = array();
  407. // get field from postmeta
  408. $rows = $wpdb->get_results( $wpdb->prepare("SELECT meta_key FROM $wpdb->postmeta WHERE post_id = %d AND meta_key LIKE %s", $post_id, 'field\_%'), ARRAY_A);
  409. if( $rows )
  410. {
  411. foreach( $rows as $row )
  412. {
  413. $field = $this->get_acf_field( $row['meta_key'], $post_id );
  414. $return[ $field['order_no'] ] = $field;
  415. }
  416. ksort($return);
  417. }
  418. // return
  419. return $return;
  420. }
  421. /*--------------------------------------------------------------------------------------
  422. *
  423. * get_acf_field
  424. * - returns a field
  425. * - $post_id can be passed to make sure the correct field is loaded. Eg: a duplicated
  426. * field group may have the same field_key, but a different post_id
  427. *
  428. * @author Elliot Condon
  429. * @since 1.0.0
  430. *
  431. *-------------------------------------------------------------------------------------*/
  432. function get_acf_field( $field_key, $post_id = false )
  433. {
  434. // return cache
  435. $cache = $this->get_cache('acf_field_' . $field_key);
  436. if($cache != false)
  437. {
  438. return $cache;
  439. }
  440. // vars
  441. global $wpdb;
  442. // get field from postmeta
  443. $sql = $wpdb->prepare("SELECT post_id, meta_value FROM $wpdb->postmeta WHERE meta_key = %s", $field_key);
  444. if( $post_id )
  445. {
  446. $sql .= $wpdb->prepare("AND post_id = %d", $post_id);
  447. }
  448. $row = $wpdb->get_results( $sql, ARRAY_A );
  449. if( $row )
  450. {
  451. $row = $row[0];
  452. // return field if it is not in a trashed field group
  453. if( get_post_status( $row['post_id'] ) != "trash" )
  454. {
  455. $row['meta_value'] = maybe_unserialize( $row['meta_value'] );
  456. $row['meta_value'] = maybe_unserialize( $row['meta_value'] ); // run again for WPML
  457. // store field
  458. $field = $row['meta_value'];
  459. // apply filters
  460. $field = apply_filters('acf_load_field', $field);
  461. $keys = array('type', 'name', 'key');
  462. foreach( $keys as $key )
  463. {
  464. if( isset($field[ $key ]) )
  465. {
  466. $field = apply_filters('acf_load_field-' . $field[ $key ], $field);
  467. }
  468. }
  469. // set cache
  470. $this->set_cache('acf_field_' . $field_key, $field);
  471. return $field;
  472. }
  473. }
  474. // hook to load in registered field groups
  475. $acfs = apply_filters('acf/get_field_groups', false);
  476. if($acfs)
  477. {
  478. // loop through acfs
  479. foreach($acfs as $acf)
  480. {
  481. // loop through fields
  482. if($acf['fields'])
  483. {
  484. foreach($acf['fields'] as $field)
  485. {
  486. if($field['key'] == $field_key)
  487. {
  488. // apply filters
  489. $field = apply_filters('acf_load_field', $field);
  490. $keys = array('type', 'name', 'key');
  491. foreach( $keys as $key )
  492. {
  493. if( isset($field[ $key ]) )
  494. {
  495. $field = apply_filters('acf_load_field-' . $field[ $key ], $field);
  496. }
  497. }
  498. // set cache
  499. $this->set_cache('acf_field_' . $field_key, $field);
  500. return $field;
  501. }
  502. }
  503. }
  504. // if($acf['fields'])
  505. }
  506. // foreach($acfs as $acf)
  507. }
  508. // if($acfs)
  509. return null;
  510. }
  511. /*
  512. * acf_load_field
  513. *
  514. * @description:
  515. * @since 3.5.1
  516. * @created: 14/10/12
  517. */
  518. function acf_load_field( $field )
  519. {
  520. if( !is_array($field) )
  521. {
  522. return $field;
  523. }
  524. $defaults = array(
  525. 'key' => '',
  526. 'label' => '',
  527. 'name' => '',
  528. 'type' => 'text',
  529. 'order_no' => 1,
  530. 'instructions' => '',
  531. 'required' => 0,
  532. 'conditional_logic' => array(
  533. 'status' => 0,
  534. 'allorany' => 'all',
  535. 'rules' => 0
  536. ),
  537. );
  538. $field = array_merge($defaults, $field);
  539. // Parse Values
  540. $field = apply_filters( 'acf_parse_value', $field );
  541. // trim name
  542. $field['name'] = trim( $field['name'] );
  543. return $field;
  544. }
  545. /*
  546. * acf_parse_value
  547. *
  548. * @description:
  549. * @since: 2.0.4
  550. * @created: 9/12/12
  551. */
  552. function acf_parse_value( $value )
  553. {
  554. // is value another array?
  555. if( is_array($value) )
  556. {
  557. foreach( $value as $k => $v )
  558. {
  559. $value[ $k ] = apply_filters( 'acf_parse_value', $v );
  560. }
  561. }
  562. else
  563. {
  564. // numbers
  565. if( is_numeric($value) )
  566. {
  567. // float / int
  568. if( strpos($value,'.') !== false )
  569. {
  570. $value = floatval( $value );
  571. }
  572. else
  573. {
  574. $value = intval( $value );
  575. }
  576. }
  577. }
  578. // return
  579. return $value;
  580. }
  581. /*--------------------------------------------------------------------------------------
  582. *
  583. * create_field
  584. *
  585. * @author Elliot Condon
  586. * @since 1.0.0
  587. *
  588. *-------------------------------------------------------------------------------------*/
  589. function create_field($field)
  590. {
  591. if(!isset($this->fields[$field['type']]) || !is_object($this->fields[$field['type']]))
  592. {
  593. _e('Error: Field Type does not exist!','acf');
  594. return false;
  595. }
  596. // defaults - class
  597. if( ! isset($field['class']) )
  598. {
  599. $field['class'] = $field['type'];
  600. }
  601. // defaults - id
  602. if( ! isset($field['id']) )
  603. {
  604. $id = $field['name'];
  605. $id = str_replace('][', '_', $id);
  606. $id = str_replace('fields[', '', $id);
  607. $id = str_replace('[', '-', $id); // location rules (select) does'nt have "fields[" in it
  608. $id = str_replace(']', '', $id);
  609. $field['id'] = 'acf-' . $id;
  610. }
  611. $this->fields[ $field['type'] ]->create_field($field);
  612. // conditional logic
  613. // - isset is needed for the edit field group page where fields are created without many parameters
  614. if( isset($field['conditional_logic']['status']) && $field['conditional_logic']['status'] ):
  615. $join = ' && ';
  616. if( $field['conditional_logic']['allorany'] == "any" )
  617. {
  618. $join = ' || ';
  619. }
  620. ?>
  621. <script type="text/javascript">
  622. (function($){
  623. // create the conditional function
  624. $(document).live('acf/conditional_logic/<?php echo $field['key']; ?>', function(){
  625. var field = $('.field-<?php echo $field['key']; ?>');
  626. <?php
  627. $if = array();
  628. foreach( $field['conditional_logic']['rules'] as $rule )
  629. {
  630. $if[] = 'acf.conditional_logic.calculate({ field : "'. $field['key'] .'", toggle : "' . $rule['field'] . '", operator : "' . $rule['operator'] .'", value : "' . $rule['value'] . '"})' ;
  631. }
  632. ?>
  633. if(<?php echo implode( $join, $if ); ?>)
  634. {
  635. field.removeClass('acf-conditional_logic-hide').addClass('acf-conditional_logic-show');
  636. }
  637. else
  638. {
  639. field.removeClass('acf-conditional_logic-show').addClass('acf-conditional_logic-hide');
  640. }
  641. });
  642. // add change events to all fields
  643. <?php
  644. $already_added = array();
  645. foreach( $field['conditional_logic']['rules'] as $rule ):
  646. if( in_array( $rule['field'], $already_added) )
  647. {
  648. continue;
  649. }
  650. else
  651. {
  652. $already_added[] = $rule['field'];
  653. }
  654. ?>
  655. $('.field-<?php echo $rule['field']; ?> *[name]').live('change', function(){
  656. $(document).trigger('acf/conditional_logic/<?php echo $field['key']; ?>');
  657. });
  658. <?php endforeach; ?>
  659. $(document).live('acf/setup_fields', function(e, postbox){
  660. $(document).trigger('acf/conditional_logic/<?php echo $field['key']; ?>');
  661. });
  662. })(jQuery);
  663. </script>
  664. <?php
  665. endif;
  666. }
  667. /*--------------------------------------------------------------------------------------
  668. *
  669. * get_acf_location
  670. *
  671. * @author Elliot Condon
  672. * @since 1.0.0
  673. *
  674. *-------------------------------------------------------------------------------------*/
  675. function get_acf_location($post_id)
  676. {
  677. // defaults
  678. $return = array(
  679. 'rules' => array(),
  680. 'allorany' => 'all',
  681. );
  682. // vars
  683. $allorany = get_post_meta($post_id, 'allorany', true);
  684. if( $allorany )
  685. {
  686. $return['allorany'] = $allorany;
  687. }
  688. // get all fields
  689. $rules = get_post_meta($post_id, 'rule', false);
  690. if($rules)
  691. {
  692. foreach($rules as $rule)
  693. {
  694. // if field group was duplicated, it may now be a serialized string!
  695. $rule = maybe_unserialize($rule);
  696. $return['rules'][$rule['order_no']] = $rule;
  697. }
  698. }
  699. // sort
  700. ksort($return['rules']);
  701. // return fields
  702. return $return;
  703. }
  704. /*--------------------------------------------------------------------------------------
  705. *
  706. * get_acf_options
  707. *
  708. * @author Elliot Condon
  709. * @since 1.0.0
  710. *
  711. *-------------------------------------------------------------------------------------*/
  712. function get_acf_options($post_id)
  713. {
  714. // defaults
  715. $options = array(
  716. 'position' => 'normal',
  717. 'layout' => 'no_box',
  718. 'hide_on_screen' => array(),
  719. );
  720. // vars
  721. $position = get_post_meta($post_id, 'position', true);
  722. if( $position )
  723. {
  724. $options['position'] = $position;
  725. }
  726. $layout = get_post_meta($post_id, 'layout', true);
  727. if( $layout )
  728. {
  729. $options['layout'] = $layout;
  730. }
  731. $hide_on_screen = get_post_meta($post_id, 'hide_on_screen', true);
  732. if( $hide_on_screen )
  733. {
  734. $hide_on_screen = maybe_unserialize($hide_on_screen);
  735. $options['hide_on_screen'] = $hide_on_screen;
  736. }
  737. // return
  738. return $options;
  739. }
  740. /*--------------------------------------------------------------------------------------
  741. *
  742. * get_value
  743. *
  744. * @author Elliot Condon
  745. * @since 3.0.0
  746. *
  747. *-------------------------------------------------------------------------------------*/
  748. function get_value($post_id, $field)
  749. {
  750. if( empty($this->fields) )
  751. {
  752. $this->setup_fields();
  753. }
  754. if( !isset($field['type'], $this->fields[ $field['type'] ]) )
  755. {
  756. return false;
  757. }
  758. return $this->fields[$field['type']]->get_value($post_id, $field);
  759. }
  760. /*--------------------------------------------------------------------------------------
  761. *
  762. * get_value_for_api
  763. *
  764. * @author Elliot Condon
  765. * @since 3.0.0
  766. *
  767. *-------------------------------------------------------------------------------------*/
  768. function get_value_for_api($post_id, $field)
  769. {
  770. if( empty($this->fields) )
  771. {
  772. $this->setup_fields();
  773. }
  774. if( !isset($field['type'], $this->fields[ $field['type'] ]) )
  775. {
  776. return false;
  777. }
  778. return $this->fields[$field['type']]->get_value_for_api($post_id, $field);
  779. }
  780. /*--------------------------------------------------------------------------------------
  781. *
  782. * update_value
  783. *
  784. * @author Elliot Condon
  785. * @since 3.0.0
  786. *
  787. *-------------------------------------------------------------------------------------*/
  788. function update_value($post_id, $field, $value)
  789. {
  790. if( isset($field['type'], $this->fields[ $field['type'] ]) )
  791. {
  792. $this->fields[$field['type']]->update_value($post_id, $field, $value);
  793. }
  794. }
  795. /*--------------------------------------------------------------------------------------
  796. *
  797. * update_field
  798. *
  799. * @author Elliot Condon
  800. * @since 3.0.0
  801. *
  802. *-------------------------------------------------------------------------------------*/
  803. function update_field($post_id, $field)
  804. {
  805. // apply filters
  806. $field = apply_filters('acf_save_field', $field );
  807. $field = apply_filters('acf_save_field-' . $field['type'], $field );
  808. // save
  809. update_post_meta($post_id, $field['key'], $field);
  810. }
  811. /*--------------------------------------------------------------------------------------
  812. *
  813. * format_value_for_api
  814. *
  815. * @author Elliot Condon
  816. * @since 3.0.0
  817. *
  818. *-------------------------------------------------------------------------------------*/
  819. function format_value_for_api($value, $field)
  820. {
  821. return $this->fields[$field['type']]->format_value_for_api($value, $field);
  822. }
  823. /*--------------------------------------------------------------------------------------
  824. *
  825. * create_format_data
  826. *
  827. * @author Elliot Condon
  828. * @since 3.0.0
  829. *
  830. *-------------------------------------------------------------------------------------*/
  831. function create_format_data($field)
  832. {
  833. return $this->fields[$field['type']]->create_format_data($field);
  834. }
  835. /*
  836. * render_fields_for_input
  837. *
  838. * @description:
  839. * @since 3.1.6
  840. * @created: 23/06/12
  841. */
  842. function render_fields_for_input($fields, $post_id)
  843. {
  844. // create fields
  845. if($fields)
  846. {
  847. foreach($fields as $field)
  848. {
  849. // if they didn't select a type, skip this field
  850. if(!$field['type'] || $field['type'] == 'null') continue;
  851. // set value
  852. if( ! isset($field['value']) )
  853. {
  854. $field['value'] = $this->get_value($post_id, $field);
  855. }
  856. $required_class = "";
  857. $required_label = "";
  858. if( $field['required'] )
  859. {
  860. $required_class = ' required';
  861. $required_label = ' <span class="required">*</span>';
  862. }
  863. echo '<div id="acf-' . $field['name'] . '" class="field field-' . $field['type'] . ' field-' . $field['key'] . $required_class . '" data-field_name="' . $field['name'] . '" data-field_key="' . $field['key'] . '">';
  864. echo '<p class="label">';
  865. echo '<label for="fields[' . $field['key'] . ']">' . $field['label'] . $required_label . '</label>';
  866. echo $field['instructions'];
  867. echo '</p>';
  868. $field['name'] = 'fields[' . $field['key'] . ']';
  869. $this->create_field($field);
  870. echo '</div>';
  871. }
  872. // foreach($fields as $field)
  873. }
  874. // if($fields)
  875. }
  876. /*--------------------------------------------------------------------------------------
  877. *
  878. * get_input_metabox_ids
  879. * - called by function.fields to hide / show metaboxes
  880. *
  881. * @author Elliot Condon
  882. * @since 2.0.5
  883. *
  884. *-------------------------------------------------------------------------------------*/
  885. function get_input_metabox_ids( $options = array() )
  886. {
  887. // vars
  888. $defaults = array(
  889. 'post_id' => 0,
  890. 'post_type' => 0,
  891. 'page_template' => 0,
  892. 'page_parent' => 0,
  893. 'page_type' => 0,
  894. 'page' => 0,
  895. 'post' => 0,
  896. 'post_category' => 0,
  897. 'post_format' => 0,
  898. 'taxonomy' => 0,
  899. 'lang' => 0,
  900. 'return' => 'php'
  901. );
  902. // merge in $options
  903. $options = array_merge($defaults, $options);
  904. // merge in $_POST
  905. if( isset($_POST) )
  906. {
  907. $options = array_merge($options, $_POST);
  908. }
  909. // Parse values
  910. $options = apply_filters( 'acf_parse_value', $options );
  911. // WPML
  912. if( $options['lang'] )
  913. {
  914. global $sitepress;
  915. $sitepress->switch_lang( $options['lang'] );
  916. }
  917. // find all acf objects
  918. $acfs = apply_filters('acf/get_field_groups', false);
  919. // blank array to hold acfs
  920. $return = array();
  921. if( $acfs )
  922. {
  923. foreach( $acfs as $acf )
  924. {
  925. // vars
  926. $add_box = false;
  927. // if all of the rules are required to match, start at true and let any !$match set $add_box to false
  928. if( $acf['location']['allorany'] == 'all' )
  929. {
  930. $add_box = true;
  931. }
  932. if( $acf['location']['rules'] )
  933. {
  934. // defaults
  935. $rule_defaults = array(
  936. 'param' => '',
  937. 'operator' => '==',
  938. 'value' => ''
  939. );
  940. foreach($acf['location']['rules'] as $rule)
  941. {
  942. // make sure rule has all 3 keys
  943. $rule = array_merge( $rule_defaults, $rule );
  944. // $match = true / false
  945. $match = false;
  946. $match = apply_filters( 'acf/location_rules/match/' . $rule['param'] , $match, $rule, $options );
  947. if( $acf['location']['allorany'] == 'all' && !$match )
  948. {
  949. // if all of the rules are required to match and this rule did not, don't add this box!
  950. $add_box = false;
  951. }
  952. elseif($acf['location']['allorany'] == 'any' && $match )
  953. {
  954. // if any of the rules are required to match and this rule did, add this box!
  955. $add_box = true;
  956. }
  957. }
  958. }
  959. // add ID to array
  960. if( $add_box )
  961. {
  962. $return[] = $acf['id'];
  963. }
  964. }
  965. }
  966. // if json
  967. if( $options['return'] == 'json' )
  968. {
  969. echo json_encode($return);
  970. die;
  971. }
  972. // not json, normal return
  973. return $return;
  974. }
  975. /*--------------------------------------------------------------------------------------
  976. *
  977. * is_field_unlocked
  978. *
  979. * @author Elliot Condon
  980. * @since 3.0.0
  981. *
  982. *-------------------------------------------------------------------------------------*/
  983. function is_field_unlocked($field_name)
  984. {
  985. $hashes = array(
  986. 'repeater' => 'bbefed143f1ec106ff3a11437bd73432',
  987. 'options_page' => '1fc8b993548891dc2b9a63ac057935d8',
  988. 'flexible_content' => 'd067e06c2b4b32b1c1f5b6f00e0d61d6',
  989. 'gallery' => '69f4adc9883195bd206a868ffa954b49',
  990. );
  991. $hash = md5( $this->get_license_key($field_name) );
  992. if( $hashes[$field_name] == $hash )
  993. {
  994. return true;
  995. }
  996. return false;
  997. }
  998. /*--------------------------------------------------------------------------------------
  999. *
  1000. * is_field_unlocked
  1001. *
  1002. * @author Elliot Condon
  1003. * @since 3.0.0
  1004. *
  1005. *-------------------------------------------------------------------------------------*/
  1006. function get_license_key($field_name)
  1007. {
  1008. $value = '';
  1009. if( isset( $this->defaults['activation_codes'][ $field_name ] ) )
  1010. {
  1011. $value = $this->defaults['activation_codes'][ $field_name ];
  1012. }
  1013. if( !$value )
  1014. {
  1015. $value = get_option('acf_' . $field_name . '_ac');
  1016. }
  1017. return $value;
  1018. }
  1019. /*--------------------------------------------------------------------------------------
  1020. *
  1021. * admin_message
  1022. *
  1023. * @author Elliot Condon
  1024. * @since 2.0.5
  1025. *
  1026. *-------------------------------------------------------------------------------------*/
  1027. function admin_message($message = "", $type = 'updated')
  1028. {
  1029. $GLOBALS['acf_mesage'] = $message;
  1030. $GLOBALS['acf_mesage_type'] = $type;
  1031. add_action('admin_notices', array($this, 'acf_admin_notice'));
  1032. }
  1033. function acf_admin_notice()
  1034. {
  1035. echo '<div class="' . $GLOBALS['acf_mesage_type'] . '" id="message">'.$GLOBALS['acf_mesage'].'</div>';
  1036. }
  1037. /*--------------------------------------------------------------------------------------
  1038. *
  1039. * get_taxonomies_for_select
  1040. *
  1041. *---------------------------------------------------------------------------------------
  1042. *
  1043. * returns a multidimentional array of taxonomies grouped by the post type / taxonomy
  1044. *
  1045. * @author Elliot Condon
  1046. * @since 3.0.2
  1047. *
  1048. *-------------------------------------------------------------------------------------*/
  1049. function get_taxonomies_for_select( $args = array() )
  1050. {
  1051. // vars
  1052. $post_types = get_post_types();
  1053. $choices = array();
  1054. $defaults = array(
  1055. 'simple_value' => false,
  1056. );
  1057. $options = array_merge($defaults, $args);
  1058. if($post_types)
  1059. {
  1060. foreach($post_types as $post_type)
  1061. {
  1062. $post_type_object = get_post_type_object($post_type);
  1063. $taxonomies = get_object_taxonomies($post_type);
  1064. if($taxonomies)
  1065. {
  1066. foreach($taxonomies as $taxonomy)
  1067. {
  1068. if(!is_taxonomy_hierarchical($taxonomy)) continue;
  1069. $terms = get_terms($taxonomy, array('hide_empty' => false));
  1070. if($terms)
  1071. {
  1072. foreach($terms as $term)
  1073. {
  1074. $value = $taxonomy . ':' . $term->term_id;
  1075. if( $options['simple_value'] )
  1076. {
  1077. $value = $term->term_id;
  1078. }
  1079. $choices[$post_type_object->label . ': ' . $taxonomy][$value] = $term->name;
  1080. }
  1081. }
  1082. }
  1083. }
  1084. }
  1085. }
  1086. return $choices;
  1087. }
  1088. /*
  1089. * get_all_image_sizes
  1090. *
  1091. * @description: returns an array holding all the image sizes
  1092. * @since 3.2.8
  1093. * @created: 6/07/12
  1094. */
  1095. function get_all_image_sizes()
  1096. {
  1097. // find all sizes
  1098. $all_sizes = get_intermediate_image_sizes();
  1099. // define default sizes
  1100. $image_sizes = array(
  1101. 'thumbnail' => __("Thumbnail",'acf'),
  1102. 'medium' => __("Medium",'acf'),
  1103. 'large' => __("Large",'acf'),
  1104. 'full' => __("Full",'acf')
  1105. );
  1106. // add extra registered sizes
  1107. foreach($all_sizes as $size)
  1108. {
  1109. if (!isset($image_sizes[$size]))
  1110. {
  1111. $image_sizes[$size] = ucwords( str_replace('-', ' ', $size) );
  1112. }
  1113. }
  1114. // return array
  1115. return $image_sizes;
  1116. }
  1117. /*
  1118. * acf_save_post
  1119. *
  1120. * @description:
  1121. * @created: 4/09/12
  1122. */
  1123. function acf_save_post( $post_id )
  1124. {
  1125. // load from post
  1126. if( !isset($_POST['fields']) )
  1127. {
  1128. return false;
  1129. }
  1130. // loop through and save
  1131. if( $_POST['fields'] )
  1132. {
  1133. foreach( $_POST['fields'] as $key => $value )
  1134. {
  1135. // get field
  1136. $field = $this->get_acf_field($key);
  1137. $this->update_value($post_id, $field, $value);
  1138. }
  1139. // foreach($fields as $key => $value)
  1140. }
  1141. // if($fields)
  1142. return true;
  1143. }
  1144. /*
  1145. * get_post_language
  1146. *
  1147. * @description: finds the translation code for a post
  1148. * @since 3.3.9
  1149. * @created: 17/08/12
  1150. */
  1151. /*function get_post_language( $post )
  1152. {
  1153. // global
  1154. global $wpdb;
  1155. // vars
  1156. $table = $wpdb->prefix.'icl_translations';
  1157. $element_type = 'post_' . $post->post_type;
  1158. $element_id = $post->ID;
  1159. $lang = $wpdb->get_var("SELECT language_code FROM $table WHERE element_type = '$element_type' AND element_id = '$element_id'");
  1160. return ' (' . $lang . ')';
  1161. }*/
  1162. /*
  1163. * get_post_types
  1164. *
  1165. * @description:
  1166. * @since: 3.5.5
  1167. * @created: 16/12/12
  1168. */
  1169. function get_post_types( $exclude = array(), $include = array() )
  1170. {
  1171. // get all custom post types
  1172. $post_types = get_post_types();
  1173. // core include / exclude
  1174. $acf_includes = array_merge( array(), $include );
  1175. $acf_excludes = array_merge( array( 'acf', 'revision', 'nav_menu_item' ), $exclude );
  1176. // include
  1177. foreach( $acf_includes as $p )
  1178. {
  1179. if( post_type_exists($p) )
  1180. {
  1181. $post_types[ $p ] = $p;
  1182. }
  1183. }
  1184. // exclude
  1185. foreach( $acf_excludes as $p )
  1186. {
  1187. unset( $post_types[ $p ] );
  1188. }
  1189. return $post_types;
  1190. }
  1191. /*
  1192. * get_next_field_id
  1193. *
  1194. * @description:
  1195. * @since: 3.5.5
  1196. * @created: 31/12/12
  1197. */
  1198. function get_next_field_id()
  1199. {
  1200. // vars
  1201. global $wpdb;
  1202. $exists = true;
  1203. // get next id
  1204. $next_id = intval( get_option('acf_next_field_id', 1) );
  1205. // while doesnt exist
  1206. while( $exists == true )
  1207. {
  1208. // get field from postmeta
  1209. $row = $wpdb->get_row($wpdb->prepare(
  1210. "
  1211. SELECT meta_id
  1212. FROM $wpdb->postmeta
  1213. WHERE meta_key = %s
  1214. ",
  1215. 'field_' . $next_id
  1216. ), ARRAY_A );
  1217. // loop again or break through?
  1218. if( ! $row )
  1219. {
  1220. $exists = false;
  1221. }
  1222. else
  1223. {
  1224. $next_id++;
  1225. }
  1226. }
  1227. // update the acf_next_field_id
  1228. update_option('acf_next_field_id', ($next_id + 1) );
  1229. // return
  1230. return $next_id;
  1231. }
  1232. }
  1233. ?>