'post|page' * EG: 'post_id' => '1|100|45' * EG: 'term_id' => '34&44' * EG: 'term_id:not' => '2or3' * EG: 'user_role' => 'administrator|author' */ class RsMetabox extends RsControl{ static $configs; public $default = array( 'name' => null, 'title' => 'Metabox', 'layout' => 'none', 'rules' => array(), 'context' => 'normal', 'priority' => 'default', 'controls' => array() ); public $rules_default = array( //POST 'post_type' => null, 'post_format' => null, 'post_id' => null, 'post_parent' => null, //POST AND TAXONOMY 'term_id' => null, 'taxonomy' => null, //PAGE 'page_id' => null, 'page_type' => null, //front_page | posts_page | parent_page | child_page | top_level 'page_parent' => null, 'page_template' => null, //USER 'user_role' => null, 'logged_user_role' => null, 'new_user_form_on_multisite' => null ); public function RsMetabox(){ $this->addControl('metabox'); } public function loadFiles(){ rs::loadStyle('rs-metabox', RS_LIB_URL . '/controls/metabox/metabox.min.css'); rs::loadScript('rs-metabox', RS_LIB_URL . '/controls/metabox/metabox.min.js'); } public function render($options = array()){ global $pagenow; //add custom page to render control by binmaocom $pages = array('profile.php', 'user-new.php', 'user-edit.php', 'edit-tags.php', 'post.php', 'post-new.php', 'term.php'); if(!in_array($pagenow, $pages)) return; if(!static::$configs) static::$configs = array(); if(!$options = $this->parseOptions($options)){ return rs::message('Add metabox error. Please check your options', 'RsMetabox'); } if(did_action('add_meta_boxes')){ return rs::message('Should be register outside any functions or by action "add_meta_boxes".', 'Add meta box: ' . $options['name']); } if(!is_array($options['rules'])){ return rs::message('Rules must be an array.', 'Add meta box: ' . $options['name']); } if(empty($options['controls']) || !is_array($options['controls'])){ return; } else{ foreach($options['controls'] as $key=>$control){ if(is_array($control)){ $options['controls'][$key] = $this->parseControl($control, $options['name_prefix']); } else{ unset($options['controls'][$key]); } } } if(!is_array(reset($options['rules']))){ $options['rules'] = array($this->convertRules($options['rules'])); } else{ foreach($options['rules'] as $key=>$rules){ $options['rules'][$key] = $this->convertRules($rules); } } if(empty($options['name'])){ $options['name'] = 'rs-metabox-' . (count(static::$configs) + 1); $options['wrap_id'] = 'rs-postbox-' . (count(static::$configs) + 1); $options['field_id'] = 'rs-metabox-' . (count(static::$configs) + 1); } $this->loadFiles(); static::$configs[] = $options; } public function mergeRules($key1, $key2, $rules){ if(isset($rules[$key1])){ if(isset($rules[$key2])){ $new = array(); $equal1 = isset($rules[$key1]['equal']) ? $rules[$key1]['equal'] : null; $equal2 = isset($rules[$key2]['equal']) ? $rules[$key2]['equal'] : null; if($equal1 || $equal2){ $new['equal'] = trim($equal1 . '|' . $equal2, '|'); } $not1 = isset($rules[$key1]['not']) ? $rules[$key1]['not'] : null; $not2 = isset($rules[$key2]['not']) ? $rules[$key2]['not'] : null; if($not1 || $not2){ $new['equal'] = trim($not1 . '$' . $not2, '$'); } return $new; } else{ return $rules[$key1]; } } return null; } public function convertRules($rules, $remove_null_rule = true){ if(!is_array($rules)){ $rule = $this->rules_default; } else{ $rules = array_merge($this->rules_default, $rules); } $rules = parent::convertRules($rules, $remove_null_rule); $rules = array_merge($this->rules_default, $rules); if(empty($rules['post_type'])){ if($rules['post_id'] || $rules['post_format'] || $rules['post_parent']){ $rules['post_type'] = array('equal' => 'post'); } if( $rules['page_template'] || $rules['page_id'] || $rules['page_parent'] || $rules['page_type']){ $rules['post_type'] = array('equal' => 'page'); } } if($rules['user_role'] && empty($rules['new_user_form_on_multisite'])){ $rules['new_user_form_on_multisite'] = array('equal' => ''); } if($post_id = $this->mergeRules('page_id', 'post_id', $rules)){ $rules['post_id'] = $post_id; unset($rules['page_id']); } if($page_parent = $this->mergeRules('page_parent', 'post_parent', $rules)){ $rules['page_parent'] = $page_parent; unset($rules['post_parent']); } return $rules; } public function checkRule($value, $rules, $required_rules = false){ if($rules == null) return !$required_rules; $equal = isset($rules['equal']) ? $rules['equal'] : null; $not = isset($rules['not']) ? $rules['not'] : null; $match = true; if($equal !== null){ if($value == $equal){ $match = true; } else if($equal == '' || $value == ''){ $match = false; } else{ $rule = explode('|', (string)$equal ); foreach($rule as $item){ $subrule = explode('&', $item); $submatch = true; foreach($subrule as $subitem){ $submatch = $submatch && strpos('&' . $value, '&' . $subitem) !== false; } $match = $submatch; if($match) break; } } } if($match && $not !== null){ if($value == $not){ $match = false; } else if($not == '' || $value == ''){ $match = true; } else{ $rule = explode('|', (string)$not ); foreach($rule as $item){ $subrule = explode('&', $item); $submatch = true; foreach($subrule as $subitem){ $submatch = $submatch && strpos('&' . $value, '&' . $subitem) === false; } $match = $submatch; if($match) break; } } } return $match; } public function serializeName($name, $name_prefix){ return str_replace(" ", "_", $name_prefix . $name); } public function parseControl($control, $name_prefix){ $control = array_merge(array( 'type' => null, 'label' => $control['name'], 'description' => null, 'name_prefix' => null ), $control); $control['name_prefix'] = $name_prefix ? $name_prefix : $control['name_prefix']; $conditional_logic_id = empty($control['name']) ? uniqid('c') : $control['name']; if(isset($control['field_id'])){ $control['conditional_logic_id'] = $control['field_id'] . '-field'; } else{ $control['conditional_logic_id'] = $control['name_prefix'] . $conditional_logic_id . '-field'; } if(empty($control['name']) && isset($control['controls']) && is_array($control['controls'])){ foreach($control['controls'] as $key=>$subcontrol){ $control['controls'][$key] = $this->parseControl($subcontrol, $name_prefix); } } return $control; } public function renderControl($control, $for = null, $id = null){ $control['render_by'] = 'metabox'; $control['render_for'] = $for; $control['render_object_id'] = $id; $return = rs::renderControl($control); if(rs::isMessage($return)){ $this->renderError($return['message']); } } public function getFieldsName($controls){ $names = array(); foreach($controls as $control){ if(!empty($control['name'])){ $names[] = "[" . strlen($control['name_prefix']) . "]" . $control['name_prefix'] . $control['name']; } elseif(isset($control['controls']) && is_array($control['controls'])){ $sub_names = $this->getFieldsName($control['controls']); $names = array_merge($names, $sub_names); } } return $names; } public function saveFieldsAjax($id){ if(isset($_REQUEST['rs_meta_names'])){ $rsnames = $_REQUEST['rs_meta_names']; $names = array(); foreach($rsnames as $fnames){ if($fnames){ $names = array_merge($names, explode(',', $fnames)); } } foreach($names as $name){ $index = preg_replace('/\D/', '', $name); $field = preg_replace('/.+]/', '', $name); $name = substr($field, (int)$index); if(isset($_REQUEST[$field])){ rs::updateField($name, $_REQUEST[$field], $id); } } } } public function Bin_saveFieldsAjax($id){ if(isset($_REQUEST['rs_meta_names'])){ $rsnames = $_REQUEST['rs_meta_names']; $names = array(); foreach($rsnames as $fnames){ if($fnames){ $names = array_merge($names, explode(',', $fnames)); } } foreach($names as $name){ $index = preg_replace('/\D/', '', $name); $field = preg_replace('/.+]/', '', $name); $name = $field;//substr($field, (int)$index); if(isset($_REQUEST[$field])){ rs::updateField($name, $_REQUEST[$field], $id); } } } } public function saveFields($controls, $prefix, $id){ foreach($controls as $control){ if(is_array($control)){ $control['name_prefix'] = (string)$prefix; $name = $this->serializeName($control['name'], $control['name_prefix']); if(isset($_POST[$name])){ rs::updateField($control['name'], $_POST[$name], $id, $control['type']); } elseif(isset($control['controls']) && is_array($control['controls'])){ $this->saveFields($control['controls'], $prefix, $id); } } } } public function addMetaBox($current_post_type, $post){ global $current_user; if(static::$configs){ foreach(static::$configs as $options){ $match = false; $client_rules = array(); foreach($options['rules'] as $rules){ $okey = $this->checkRule(implode('&', $current_user->roles), $rules['logged_user_role']) && $this->checkRule($current_post_type, $rules['post_type'], true) && $this->checkRule($post->ID, $rules['post_id']); $client_rule = array(); if($okey && $rules['page_type'] && is_post_type_hierarchical($current_post_type)){ $current_page_type = 'top_level&child_page'; if(get_pages(array('number' => 1, 'post_type' => $current_post_type, 'parent' => $post->ID))){ $current_page_type .= '&parent'; } if(get_option('page_on_front') == $post->ID){ $current_page_type .= '&page_on_front'; } if(get_option('page_for_posts') == $post->ID){ $current_page_type .= '&page_for_posts'; } $okey = $this->checkRule($current_page_type, $rules['page_type']); } if($okey){ foreach(array('page_type', 'page_template', 'post_format', 'page_parent', 'term_id') as $clientkey){ if($rules[$clientkey]) $client_rule[$clientkey] = $rules[$clientkey]; } if($client_rule) $client_rules[] = $client_rule; $match = $match || $okey; } } if($match){ if($client_rules){ $metabox_logic = rs::getJSData('metabox-logic'); $metabox_logic[$options['wrap_id']] = $client_rules; rs::setJSData('metabox-logic', $metabox_logic); } $this->addConditionalLogic($options); add_meta_box( $options['wrap_id'], $options['title'], array($this, 'renderMetaBox'), $current_post_type, $options['context'], $options['priority'], $options ); } else{ } } } } public function renderMetaBox($post, $args){ $options = $args['args']; ?>
getPostField($control['name'], $post->ID); if($options['name_prefix']) $control['name_prefix'] = $options['name_prefix']; $this->renderControl($control, 'post', $post->ID); } else{ $control['render_by'] = 'metabox'; $control['render_for'] = 'post'; $control['render_object_id'] = $post->ID; rs::renderControl($control); } } public function renderRowLayout($post, $options){ ?>| renderControl($control, 'post', $post->ID); ?> |
renderControl($control, 'post', $post->ID); ?> |
renderControl($control, 'post', $post->ID); ?>
| renderControl($control, 'term', $term_id) ?> | |
| renderScripts($options); ?> | |