/core/controllers/field_group.php

  1. <?php  
  2.  
  3. /** 
  4. * acf_field_group 
  5. * 
  6. * @description: controller for editing a field group 
  7. * @since: 3.6 
  8. * @created: 25/01/13 
  9. */ 
  10.  
  11. class acf_field_group 
  12.  
  13. var $settings; 
  14.  
  15.  
  16. /** 
  17. * __construct 
  18. * 
  19. * @description:  
  20. * @since 3.1.8 
  21. * @created: 23/06/12 
  22. */ 
  23.  
  24. function __construct() 
  25. // actions 
  26. add_action('admin_enqueue_scripts', array($this, 'admin_enqueue_scripts')); 
  27.  
  28.  
  29. // filters 
  30. add_filter('acf/get_field_groups', array($this, 'get_field_groups'), 1, 1); 
  31. add_filter('acf/field_group/get_fields', array($this, 'get_fields'), 5, 2); 
  32. add_filter('acf/field_group/get_location', array($this, 'get_location'), 5, 2); 
  33. add_filter('acf/field_group/get_options', array($this, 'get_options'), 5, 2); 
  34. add_filter('acf/field_group/get_next_field_id', array($this, 'get_next_field_id'), 5, 1); 
  35.  
  36.  
  37. // save 
  38. add_filter('name_save_pre', array($this, 'name_save_pre')); 
  39. add_action('save_post', array($this, 'save_post')); 
  40.  
  41.  
  42. // ajax 
  43. add_action('wp_ajax_acf/field_group/render_options', array($this, 'ajax_render_options')); 
  44. add_action('wp_ajax_acf/field_group/render_location', array($this, 'ajax_render_location')); 
  45.  
  46.  
  47.  
  48. /** 
  49. * get_field_groups 
  50. * 
  51. * @description:  
  52. * @since: 3.6 
  53. * @created: 27/01/13 
  54. */ 
  55.  
  56. function get_field_groups( $array ) 
  57. // cache 
  58. $found = false; 
  59. $cache = wp_cache_get( 'field_groups', 'acf', false, $found ); 
  60.  
  61. if( $found ) 
  62. return $cache; 
  63.  
  64.  
  65. // get acf's 
  66. $posts = get_posts(array( 
  67. 'numberposts' => -1,  
  68. 'post_type' => 'acf',  
  69. 'orderby' => 'menu_order title',  
  70. 'order' => 'asc',  
  71. 'suppress_filters' => false,  
  72. )); 
  73.  
  74.  
  75. // populate acfs 
  76. if( $posts ) { foreach( $posts as $post ) { 
  77.  
  78. $array[] = array( 
  79. 'id' => $post->ID,  
  80. 'title' => $post->post_title,  
  81. 'menu_order' => $post->menu_order,  
  82. ); 
  83.  
  84. }} 
  85.  
  86.  
  87. // set cache 
  88. wp_cache_set( 'field_groups', $array, 'acf' ); 
  89.  
  90.  
  91. return $array; 
  92.  
  93.  
  94. /** 
  95. * get_fields 
  96. * 
  97. * @description: returns all fields for a field group 
  98. * @since: 3.6 
  99. * @created: 26/01/13 
  100. */ 
  101.  
  102. function get_fields( $fields, $post_id ) 
  103. // global 
  104. global $wpdb; 
  105.  
  106.  
  107. // loaded by PHP already? 
  108. if( !empty($fields) ) 
  109. return $fields;  
  110.  
  111.  
  112. // get field from postmeta 
  113. $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); 
  114.  
  115.  
  116. if( $rows ) 
  117. foreach( $rows as $row ) 
  118. $field = apply_filters('acf/load_field', false, $row['meta_key'], $post_id ); 
  119.  
  120. $fields[ $field['order_no'] ] = $field; 
  121.  
  122. // sort 
  123. ksort( $fields ); 
  124.  
  125.  
  126.  
  127. // return 
  128. return $fields; 
  129.  
  130.  
  131.  
  132. /** 
  133. * get_location 
  134. * 
  135. * @description:  
  136. * @since: 3.6 
  137. * @created: 26/01/13 
  138. */ 
  139.  
  140. function get_location( $location, $post_id ) 
  141. // loaded by PHP already? 
  142. if( !empty($location) ) 
  143. return $location;  
  144.  
  145.  
  146. // vars 
  147. $groups = array(); 
  148. $group_no = 0; 
  149.  
  150.  
  151. // get all rules 
  152. $rules = get_post_meta($post_id, 'rule', false); 
  153.  
  154.  
  155. if( is_array($rules) ) 
  156. foreach( $rules as $rule ) 
  157. // if field group was duplicated, it may now be a serialized string! 
  158. $rule = maybe_unserialize($rule); 
  159.  
  160.  
  161. // does this rule have a group? 
  162. // + groups were added in 4.0.4 
  163. if( !isset($rule['group_no']) ) 
  164. $rule['group_no'] = $group_no; 
  165.  
  166. // sperate groups? 
  167. if( get_post_meta($post_id, 'allorany', true) == 'any' ) 
  168. $group_no++; 
  169.  
  170.  
  171. // add to group 
  172. $groups[ $rule['group_no'] ][ $rule['order_no'] ] = $rule; 
  173.  
  174.  
  175. // sort rules 
  176. ksort( $groups[ $rule['group_no'] ] ); 
  177.  
  178.  
  179. // sort groups 
  180. ksort( $groups ); 
  181.  
  182.  
  183. // return fields 
  184. return $groups; 
  185.  
  186.  
  187. /** 
  188. * get_options 
  189. * 
  190. * @description:  
  191. * @since: 3.6 
  192. * @created: 26/01/13 
  193. */ 
  194.  
  195. function get_options( $options, $post_id ) 
  196. // loaded by PHP already? 
  197. if( !empty($options) ) 
  198. return $options;  
  199.  
  200.  
  201. // defaults 
  202. $options = array( 
  203. 'position' => 'normal',  
  204. 'layout' => 'no_box',  
  205. 'hide_on_screen' => array(),  
  206. ); 
  207.  
  208.  
  209. // vars 
  210. $position = get_post_meta($post_id, 'position', true); 
  211. if( $position ) 
  212. $options['position'] = $position; 
  213.  
  214. $layout = get_post_meta($post_id, 'layout', true); 
  215. if( $layout ) 
  216. $options['layout'] = $layout; 
  217.  
  218. $hide_on_screen = get_post_meta($post_id, 'hide_on_screen', true); 
  219. if( $hide_on_screen ) 
  220. $hide_on_screen = maybe_unserialize($hide_on_screen); 
  221. $options['hide_on_screen'] = $hide_on_screen; 
  222.  
  223.  
  224. // return 
  225. return $options; 
  226.  
  227.  
  228. /** 
  229. * validate_page 
  230. * 
  231. * @description:  
  232. * @since 3.2.6 
  233. * @created: 23/06/12 
  234. */ 
  235.  
  236. function validate_page() 
  237. // global 
  238. global $pagenow, $typenow; 
  239.  
  240.  
  241. // vars 
  242. $return = false; 
  243.  
  244.  
  245. // validate page 
  246. if( in_array( $pagenow, array('post.php', 'post-new.php') ) ) 
  247.  
  248. // validate post type 
  249. if( $typenow == "acf" ) 
  250. $return = true; 
  251.  
  252.  
  253.  
  254. // return 
  255. return $return; 
  256.  
  257.  
  258. /** 
  259. * admin_enqueue_scripts 
  260. * 
  261. * @description: run after post query but before any admin script / head actions. A good place to register all actions. 
  262. * @since: 3.6 
  263. * @created: 26/01/13 
  264. */ 
  265.  
  266. function admin_enqueue_scripts() 
  267. // validate page 
  268. if( ! $this->validate_page() ) { return; } 
  269.  
  270.  
  271. // settings 
  272. $this->settings = apply_filters('acf/get_info', 'all'); 
  273.  
  274.  
  275. // no autosave 
  276. wp_dequeue_script( 'autosave' ); 
  277.  
  278.  
  279. // custom scripts 
  280. wp_enqueue_script(array( 
  281. 'acf-field-group',  
  282. )); 
  283.  
  284.  
  285. // custom styles 
  286. wp_enqueue_style(array( 
  287. 'acf-global',  
  288. 'acf-field-group',  
  289. )); 
  290.  
  291.  
  292. // actions 
  293. do_action('acf/field_group/admin_enqueue_scripts'); 
  294. add_action('admin_head', array($this, 'admin_head')); 
  295.  
  296.  
  297.  
  298. /** 
  299. * admin_head 
  300. * 
  301. * @description:  
  302. * @since 3.1.8 
  303. * @created: 23/06/12 
  304. */ 
  305.  
  306. function admin_head() 
  307. // global 
  308. global $wp_version, $post; 
  309.  
  310.  
  311. // l10n 
  312. $l10n = array( 
  313. 'move_to_trash' => __("Move to trash. Are you sure?", 'acf'),  
  314. 'checked' => __("checked", 'acf'),  
  315. 'no_fields' => __("No toggle fields available", 'acf'),  
  316. 'title' => __("Field group title is required", 'acf'),  
  317. 'copy' => __("copy", 'acf'),  
  318. 'or' => __("or", 'acf'),  
  319. 'fields' => __("Fields", 'acf'),  
  320. 'parent_fields' => __("Parent fields", 'acf'),  
  321. 'sibling_fields' => __("Sibling fields", 'acf'),  
  322. 'hide_show_all' => __("Hide / Show All", 'acf') 
  323. ); 
  324.  
  325.  
  326.  
  327. ?> 
  328. <script type="text/javascript"> 
  329. (function($) { 
  330.  
  331. // vars 
  332. acf.post_id = <?php echo $post->ID; ?>; 
  333. acf.nonce = "<?php echo wp_create_nonce( 'acf_nonce' ); ?>"; 
  334. acf.admin_url = "<?php echo admin_url(); ?>"; 
  335. acf.ajaxurl = "<?php echo admin_url( 'admin-ajax.php' ); ?>"; 
  336. acf.wp_version = "<?php echo $wp_version; ?>"; 
  337.  
  338.  
  339. // l10n 
  340. acf.l10n = <?php echo json_encode( $l10n ); ?>; 
  341.  
  342. })(jQuery);  
  343. </script> 
  344. <?php 
  345.  
  346. // new action 
  347. do_action('acf/field_group/admin_head'); 
  348.  
  349.  
  350. // add metaboxes 
  351. add_meta_box('acf_fields', __("Fields", 'acf'), array($this, 'html_fields'), 'acf', 'normal', 'high'); 
  352. add_meta_box('acf_location', __("Location", 'acf'), array($this, 'html_location'), 'acf', 'normal', 'high'); 
  353. add_meta_box('acf_options', __("Options", 'acf'), array($this, 'html_options'), 'acf', 'normal', 'high'); 
  354.  
  355.  
  356. // add screen settings 
  357. add_filter('screen_settings', array($this, 'screen_settings'), 10, 1); 
  358.  
  359.  
  360. /** 
  361. * html_fields 
  362. * 
  363. * @description:  
  364. * @since 1.0.0 
  365. * @created: 23/06/12 
  366. */ 
  367.  
  368. function html_fields() 
  369. include( $this->settings['path'] . 'core/views/meta_box_fields.php' ); 
  370.  
  371.  
  372. /** 
  373. * html_location 
  374. * 
  375. * @description:  
  376. * @since 1.0.0 
  377. * @created: 23/06/12 
  378. */ 
  379.  
  380. function html_location() 
  381. include( $this->settings['path'] . 'core/views/meta_box_location.php' ); 
  382.  
  383.  
  384. /** 
  385. * html_options 
  386. * 
  387. * @description:  
  388. * @since 1.0.0 
  389. * @created: 23/06/12 
  390. */ 
  391.  
  392. function html_options() 
  393. include( $this->settings['path'] . 'core/views/meta_box_options.php' ); 
  394.  
  395.  
  396. /** 
  397. * screen_settings 
  398. * 
  399. * @description:  
  400. * @since: 3.6 
  401. * @created: 26/01/13 
  402. */ 
  403.  
  404. function screen_settings( $current ) 
  405. $current .= '<h5>' . __("Fields", 'acf') . '</h5>'; 
  406.  
  407. $current .= '<div class="show-field_key">' . __("Show Field Key:", 'acf'); 
  408. $current .= '<label class="show-field_key-no"><input checked="checked" type="radio" value="0" name="show-field_key" />' . __("No", 'acf') . '</label>'; 
  409. $current .= '<label class="show-field_key-yes"><input type="radio" value="1" name="show-field_key" />' . __("Yes", 'acf') . '</label>'; 
  410. $current .= '</div>'; 
  411.  
  412. return $current; 
  413.  
  414.  
  415. /** 
  416. * ajax_render_options 
  417. * 
  418. * @description: creates the HTML for a field's options (field group edit page) 
  419. * @since 3.1.6 
  420. * @created: 23/06/12 
  421. */ 
  422.  
  423. function ajax_render_options() 
  424. // vars 
  425. $options = array( 
  426. 'field_key' => '',  
  427. 'field_type' => '',  
  428. 'post_id' => 0,  
  429. 'nonce' => '' 
  430. ); 
  431.  
  432. // load post options 
  433. $options = array_merge($options, $_POST); 
  434.  
  435.  
  436. // verify nonce 
  437. if( ! wp_verify_nonce($options['nonce'], 'acf_nonce') ) 
  438. die(0); 
  439.  
  440.  
  441. // required 
  442. if( ! $options['field_type'] ) 
  443. die(0); 
  444.  
  445.  
  446. // find key (not actual field key, more the html attr name) 
  447. $options['field_key'] = str_replace("fields[", "", $options['field_key']); 
  448. $options['field_key'] = str_replace("][type]", "", $options['field_key']) ; 
  449.  
  450.  
  451. // render options 
  452. $field = array( 
  453. 'type' => $options['field_type'],  
  454. 'name' => $options['field_key'] 
  455. ); 
  456. do_action('acf/create_field_options', $field ); 
  457.  
  458.  
  459. die(); 
  460.  
  461.  
  462.  
  463. /** 
  464. * ajax_render_location 
  465. * 
  466. * @description: creates the HTML for the field group location metabox. Called from both Ajax and PHP 
  467. * @since 3.1.6 
  468. * @created: 23/06/12 
  469. */ 
  470.  
  471. function ajax_render_location( $options = array() ) 
  472. // defaults 
  473. $defaults = array( 
  474. 'group_id' => 0,  
  475. 'rule_id' => 0,  
  476. 'value' => null,  
  477. 'param' => null,  
  478. ); 
  479.  
  480. $is_ajax = false; 
  481. if( isset($_POST['nonce']) && wp_verify_nonce($_POST['nonce'], 'acf_nonce') ) 
  482. $is_ajax = true; 
  483.  
  484.  
  485. // Is AJAX call? 
  486. if( $is_ajax ) 
  487. $options = array_merge($defaults, $_POST); 
  488. else 
  489. $options = array_merge($defaults, $options); 
  490.  
  491. // vars 
  492. $choices = array(); 
  493.  
  494.  
  495. // some case's have the same outcome 
  496. if($options['param'] == "page_parent") 
  497. $options['param'] = "page"; 
  498.  
  499.  
  500. switch($options['param']) 
  501. case "post_type": 
  502.  
  503. // all post types except attachment 
  504. $choices = apply_filters('acf/get_post_types', array(), array('attachment')); 
  505.  
  506. break; 
  507.  
  508.  
  509. case "page": 
  510.  
  511. $post_type = 'page'; 
  512. $posts = get_posts(array( 
  513. 'posts_per_page' => -1,  
  514. 'post_type' => $post_type,  
  515. 'orderby' => 'menu_order title',  
  516. 'order' => 'ASC',  
  517. 'post_status' => 'any',  
  518. 'suppress_filters' => false,  
  519. 'update_post_meta_cache' => false,  
  520. )); 
  521.  
  522. if( $posts ) 
  523. // sort into hierachial order! 
  524. if( is_post_type_hierarchical( $post_type ) ) 
  525. $posts = get_page_children( 0, $posts ); 
  526.  
  527. foreach( $posts as $page ) 
  528. $title = ''; 
  529. $ancestors = get_ancestors($page->ID, 'page'); 
  530. if($ancestors) 
  531. foreach($ancestors as $a) 
  532. $title .= '- '; 
  533.  
  534. $title .= apply_filters( 'the_title', $page->post_title, $page->ID ); 
  535.  
  536.  
  537. // status 
  538. if($page->post_status != "publish") 
  539. $title .= " ($page->post_status)"; 
  540.  
  541. $choices[ $page->ID ] = $title; 
  542.  
  543. // foreach($pages as $page) 
  544.  
  545.  
  546. break; 
  547.  
  548.  
  549. case "page_type" : 
  550.  
  551. $choices = array( 
  552. 'front_page' => __("Front Page", 'acf'),  
  553. 'posts_page' => __("Posts Page", 'acf'),  
  554. 'top_level' => __("Top Level Page (parent of 0)", 'acf'),  
  555. 'parent' => __("Parent Page (has children)", 'acf'),  
  556. 'child' => __("Child Page (has parent)", 'acf'),  
  557. ); 
  558.  
  559. break; 
  560.  
  561. case "page_template" : 
  562.  
  563. $choices = array( 
  564. 'default' => __("Default Template", 'acf'),  
  565. ); 
  566.  
  567. $templates = get_page_templates(); 
  568. foreach($templates as $k => $v) 
  569. $choices[$v] = $k; 
  570.  
  571. break; 
  572.  
  573. case "post" : 
  574.  
  575. $post_types = get_post_types(); 
  576.  
  577. unset( $post_types['page'], $post_types['attachment'], $post_types['revision'] , $post_types['nav_menu_item'], $post_types['acf'] ); 
  578.  
  579. if( $post_types ) 
  580. foreach( $post_types as $post_type ) 
  581.  
  582. $posts = get_posts(array( 
  583. 'numberposts' => '-1',  
  584. 'post_type' => $post_type,  
  585. 'post_status' => array('publish', 'private', 'draft', 'inherit', 'future'),  
  586. 'suppress_filters' => false,  
  587. )); 
  588.  
  589. if( $posts) 
  590. $choices[$post_type] = array(); 
  591.  
  592. foreach($posts as $post) 
  593. $title = apply_filters( 'the_title', $post->post_title, $post->ID ); 
  594.  
  595. // status 
  596. if($post->post_status != "publish") 
  597. $title .= " ($post->post_status)"; 
  598.  
  599. $choices[$post_type][$post->ID] = $title; 
  600.  
  601. // foreach($posts as $post) 
  602. // if( $posts ) 
  603. // foreach( $post_types as $post_type ) 
  604. // if( $post_types ) 
  605.  
  606.  
  607. break; 
  608.  
  609. case "post_category" : 
  610.  
  611. $terms = get_terms( 'category', array( 'hide_empty' => false ) ); 
  612.  
  613. if( !empty($terms) ) { 
  614.  
  615. foreach( $terms as $term ) { 
  616.  
  617. $choices[ $term->term_id ] = $term->name; 
  618.  
  619.  
  620.  
  621. break; 
  622.  
  623. case "post_format" : 
  624.  
  625. $choices = get_post_format_strings(); 
  626.  
  627. break; 
  628.  
  629. case "post_status" : 
  630.  
  631. $choices = array( 
  632. 'publish' => __( 'Published', 'acf'),  
  633. 'pending' => __( 'Pending Review', 'acf'),  
  634. 'draft' => __( 'Draft', 'acf'),  
  635. 'future' => __( 'Future', 'acf'),  
  636. 'private' => __( 'Private', 'acf'),  
  637. 'inherit' => __( 'Revision', 'acf'),  
  638. 'trash' => __( 'Trash', 'acf'),  
  639. ); 
  640.  
  641. break; 
  642.  
  643. case "user_type" : 
  644.  
  645. global $wp_roles; 
  646.  
  647. $choices = $wp_roles->get_names(); 
  648.  
  649. if( is_multisite() ) 
  650. $choices['super_admin'] = __('Super Admin', 'acf'); 
  651.  
  652. break; 
  653.  
  654. case "taxonomy" : 
  655.  
  656. $choices = array(); 
  657. $simple_value = true; 
  658. $choices = apply_filters('acf/get_taxonomies_for_select', $choices, $simple_value); 
  659.  
  660. break; 
  661.  
  662. case "ef_taxonomy" : 
  663.  
  664. $choices = array('all' => __('All', 'acf')); 
  665. $taxonomies = get_taxonomies( array('public' => true), 'objects' ); 
  666.  
  667. foreach($taxonomies as $taxonomy) 
  668. $choices[ $taxonomy->name ] = $taxonomy->labels->name; 
  669.  
  670. // unset post_format (why is this a public taxonomy?) 
  671. if( isset($choices['post_format']) ) 
  672. unset( $choices['post_format']) ; 
  673.  
  674.  
  675. break; 
  676.  
  677. case "ef_user" : 
  678.  
  679. global $wp_roles; 
  680.  
  681. $choices = array_merge( array('all' => __('All', 'acf')), $wp_roles->get_names() ); 
  682.  
  683. break; 
  684.  
  685.  
  686. case "ef_media" : 
  687.  
  688. $choices = array('all' => __('All', 'acf')); 
  689.  
  690. break; 
  691.  
  692.  
  693.  
  694. // allow custom location rules 
  695. $choices = apply_filters( 'acf/location/rule_values/' . $options['param'], $choices ); 
  696.  
  697.  
  698. // create field 
  699. do_action('acf/create_field', array( 
  700. 'type' => 'select',  
  701. 'name' => 'location[' . $options['group_id'] . '][' . $options['rule_id'] . '][value]',  
  702. 'value' => $options['value'],  
  703. 'choices' => $choices,  
  704. )); 
  705.  
  706.  
  707. // ajax
  708. if( $is_ajax ) 
  709. die(); 
  710.  
  711. }  
  712.  
  713.  
  714. /** 
  715. * name_save_pre 
  716. * 
  717. * @description: intercepts the acf post obejct and adds an "acf_" to the start of  
  718. * it's name to stop conflicts between acf's and page's urls 
  719. * @since 1.0.0 
  720. * @created: 23/06/12 
  721. */ 
  722.  
  723. function name_save_pre($name) 
  724. // validate 
  725. if( !isset($_POST['post_type']) || $_POST['post_type'] != 'acf' )  
  726. return $name; 
  727.  
  728.  
  729. // need a title 
  730. if( !$_POST['post_title'] ) 
  731. $_POST['post_title'] = 'Unnamed Field Group'; 
  732.  
  733.  
  734. $name = 'acf_' . sanitize_title($_POST['post_title']); 
  735.  
  736.  
  737. return $name; 
  738.  
  739.  
  740. /** 
  741. * save_post 
  742. * 
  743. * @description: Saves the field / location / option data for a field group 
  744. * @since 1.0.0 
  745. * @created: 23/06/12 
  746. */ 
  747.  
  748. function save_post($post_id) 
  749. // do not save if this is an auto save routine 
  750. if( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ) 
  751. return $post_id; 
  752.  
  753.  
  754. // verify nonce 
  755. if( !isset($_POST['acf_nonce']) || !wp_verify_nonce($_POST['acf_nonce'], 'field_group') ) 
  756. return $post_id; 
  757.  
  758.  
  759. // only save once! WordPress save's a revision as well. 
  760. if( wp_is_post_revision($post_id) ) 
  761. return $post_id; 
  762.  
  763.  
  764. /** 
  765. * save fields 
  766. */ 
  767.  
  768. // vars 
  769. $dont_delete = array(); 
  770.  
  771. if( isset($_POST['fields']) && is_array($_POST['fields']) ) 
  772. $i = -1; 
  773.  
  774.  
  775. // remove clone field 
  776. unset( $_POST['fields']['field_clone'] ); 
  777.  
  778.  
  779.  
  780. // loop through and save fields 
  781. foreach( $_POST['fields'] as $key => $field ) 
  782. $i++; 
  783.  
  784.  
  785. // order + key 
  786. $field['order_no'] = $i; 
  787. $field['key'] = $key; 
  788.  
  789.  
  790. // save 
  791. do_action('acf/update_field', $field, $post_id ); 
  792.  
  793.  
  794. // add to dont delete array 
  795. $dont_delete[] = $field['key']; 
  796. unset( $_POST['fields'] ); 
  797.  
  798.  
  799. // delete all other field 
  800. $keys = get_post_custom_keys($post_id); 
  801. foreach( $keys as $key ) 
  802. if( strpos($key, 'field_') !== false && !in_array($key, $dont_delete) ) 
  803. // this is a field, and it wasn't found in the dont_delete array 
  804. do_action('acf/delete_field', $post_id, $key); 
  805.  
  806.  
  807. /** 
  808. * save location rules 
  809. */ 
  810.  
  811. if( isset($_POST['location']) && is_array($_POST['location']) ) 
  812. delete_post_meta( $post_id, 'rule' ); 
  813.  
  814.  
  815. // clean array keys 
  816. $_POST['location'] = array_values( $_POST['location'] ); 
  817. foreach( $_POST['location'] as $group_id => $group ) 
  818. if( is_array($group) ) 
  819. // clean array keys 
  820. $group = array_values( $group ); 
  821. foreach( $group as $rule_id => $rule ) 
  822. $rule['order_no'] = $rule_id; 
  823. $rule['group_no'] = $group_id; 
  824.  
  825.  
  826. add_post_meta( $post_id, 'rule', $rule ); 
  827.  
  828. unset( $_POST['location'] ); 
  829.  
  830.  
  831. /** 
  832. * save options 
  833. */ 
  834.  
  835. if( isset($_POST['options']) && is_array($_POST['options']) ) 
  836. update_post_meta($post_id, 'position', $_POST['options']['position']); 
  837. update_post_meta($post_id, 'layout', $_POST['options']['layout']); 
  838. update_post_meta($post_id, 'hide_on_screen', $_POST['options']['hide_on_screen']); 
  839.  
  840.  
  841. unset( $_POST['options'] ); 
  842.  
  843.  
  844.  
  845.  
  846.  
  847. new acf_field_group(); 
  848.  
  849. ?> 
.