acf_field_group

Acf_field_group.

Defined (1)

The class is defined in the following location(s).

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