'', 'post_type' => 'post', 'data_type' => 'serialize', 'context' => 'advanced', 'priority' => 'default', 'exclude_post_types' => array(), 'page_templates' => '', 'post_formats' => '', 'show_reset' => false, 'show_restore' => false, 'enqueue_webfont' => true, 'async_webfont' => false, 'output_css' => true, 'nav' => 'normal', 'theme' => 'dark', 'class' => '', 'defaults' => array(), ); // run metabox construct public function __construct($key, $params = array()) { $this->unique = $key; $this->args = apply_filters("csf_{$this->unique}_args", wp_parse_args($params['args'], $this->args), $this); $this->sections = apply_filters("csf_{$this->unique}_sections", $params['sections'], $this); $this->post_type = (is_array($this->args['post_type'])) ? $this->args['post_type'] : array_filter((array) $this->args['post_type']); $this->post_formats = (is_array($this->args['post_formats'])) ? $this->args['post_formats'] : array_filter((array) $this->args['post_formats']); $this->page_templates = (is_array($this->args['page_templates'])) ? $this->args['page_templates'] : array_filter((array) $this->args['page_templates']); $this->pre_fields = $this->pre_fields($this->sections); add_action('add_meta_boxes', array($this, 'add_meta_box')); add_action('save_post', array($this, 'save_meta_box')); add_action('edit_attachment', array($this, 'save_meta_box')); if (!empty($this->page_templates) || !empty($this->post_formats) || !empty($this->args['class'])) { foreach ($this->post_type as $post_type) { add_filter('postbox_classes_' . $post_type . '_' . $this->unique, array($this, 'add_metabox_classes')); } } // wp enqeueu for typography and output css parent::__construct(); } // instance public static function instance($key, $params = array()) { return new self($key, $params); } public function pre_fields($sections) { $result = array(); foreach ($sections as $key => $section) { if (!empty($section['fields'])) { foreach ($section['fields'] as $field) { $result[] = $field; } } } return $result; } public function add_metabox_classes($classes) { global $post; if (!empty($this->post_formats)) { $saved_post_format = (is_object($post)) ? get_post_format($post) : false; $saved_post_format = (!empty($saved_post_format)) ? $saved_post_format : 'default'; $classes[] = 'csf-post-formats'; // Sanitize post format for standard to default if (($key = array_search('standard', $this->post_formats)) !== false) { $this->post_formats[$key] = 'default'; } foreach ($this->post_formats as $format) { $classes[] = 'csf-post-format-' . $format; } if (!in_array($saved_post_format, $this->post_formats)) { $classes[] = 'csf-metabox-hide'; } else { $classes[] = 'csf-metabox-show'; } } if (!empty($this->page_templates)) { $saved_template = (is_object($post) && !empty($post->page_template)) ? $post->page_template : 'default'; $classes[] = 'csf-page-templates'; foreach ($this->page_templates as $template) { $classes[] = 'csf-page-' . preg_replace('/[^a-zA-Z0-9]+/', '-', strtolower($template)); } if (!in_array($saved_template, $this->page_templates)) { $classes[] = 'csf-metabox-hide'; } else { $classes[] = 'csf-metabox-show'; } } if (!empty($this->args['class'])) { $classes[] = $this->args['class']; } return $classes; } // add metabox public function add_meta_box($post_type) { if (!in_array($post_type, $this->args['exclude_post_types'])) { add_meta_box($this->unique, $this->args['title'], array($this, 'add_meta_box_content'), $this->post_type, $this->args['context'], $this->args['priority'], $this->args); } } // get default value public function get_default($field) { $default = (isset($field['default'])) ? $field['default'] : ''; $default = (isset($this->args['defaults'][$field['id']])) ? $this->args['defaults'][$field['id']] : $default; return $default; } // get meta value public function get_meta_value($field) { global $post; $value = null; if (is_object($post) && !empty($field['id'])) { if ($this->args['data_type'] !== 'serialize') { $meta = get_post_meta($post->ID, $field['id']); $value = (isset($meta[0])) ? $meta[0] : null; } else { $meta = get_post_meta($post->ID, $this->unique, true); $value = (isset($meta[$field['id']])) ? $meta[$field['id']] : null; } } $default = (isset($field['id'])) ? $this->get_default($field) : ''; $value = (isset($value)) ? $value : $default; return $value; } // add metabox content public function add_meta_box_content($post, $callback) { global $post; $has_nav = (count($this->sections) > 1 && $this->args['context'] !== 'side') ? true : false; $show_all = (!$has_nav) ? ' csf-show-all' : ''; $post_type = (is_object($post)) ? $post->post_type : ''; $errors = (is_object($post)) ? get_post_meta($post->ID, '_csf_errors_' . $this->unique, true) : array(); $errors = (!empty($errors)) ? $errors : array(); $theme = ($this->args['theme']) ? ' csf-theme-' . $this->args['theme'] : ''; $nav_type = ($this->args['nav'] === 'inline') ? 'inline' : 'normal'; if (is_object($post) && !empty($errors)) { delete_post_meta($post->ID, '_csf_errors_' . $this->unique); } wp_nonce_field('csf_metabox_nonce', 'csf_metabox_nonce' . $this->unique); echo '
'; } // save metabox public function save_meta_box($post_id) { $count = 1; $data = array(); $errors = array(); $noncekey = 'csf_metabox_nonce' . $this->unique; $nonce = (!empty($_POST[$noncekey])) ? sanitize_text_field(wp_unslash($_POST[$noncekey])) : ''; if ((defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) || !wp_verify_nonce($nonce, 'csf_metabox_nonce')) { return $post_id; } // XSS ok. // No worries, This "POST" requests is sanitizing in the below foreach. $request = (!empty($_POST[$this->unique])) ? $_POST[$this->unique] : array(); if (!empty($request)) { foreach ($this->sections as $section) { if (!empty($section['fields'])) { foreach ($section['fields'] as $field) { if (!empty($field['id'])) { $field_id = $field['id']; $field_value = isset($request[$field_id]) ? $request[$field_id] : ''; // Sanitize "post" request of field. if (!isset($field['sanitize'])) { if (is_array($field_value)) { $data[$field_id] = wp_kses_post_deep($field_value); } else { $data[$field_id] = wp_kses_post($field_value); } } else if (isset($field['sanitize']) && is_callable($field['sanitize'])) { $data[$field_id] = call_user_func($field['sanitize'], $field_value); } else { $data[$field_id] = $field_value; } // Validate "post" request of field. if (isset($field['validate']) && is_callable($field['validate'])) { $has_validated = call_user_func($field['validate'], $field_value); if (!empty($has_validated)) { $errors['sections'][$count] = true; $errors['fields'][$field_id] = $has_validated; $data[$field_id] = $this->get_meta_value($field); } } } } } $count++; } } $data = apply_filters("csf_{$this->unique}_save", $data, $post_id, $this); do_action("csf_{$this->unique}_save_before", $data, $post_id, $this); if (empty($data) || !empty($request['_reset'])) { if ($this->args['data_type'] !== 'serialize') { foreach ($data as $key => $value) { delete_post_meta($post_id, $key); } } else { delete_post_meta($post_id, $this->unique); } } else { if ($this->args['data_type'] !== 'serialize') { foreach ($data as $key => $value) { update_post_meta($post_id, $key, $value); } } else { update_post_meta($post_id, $this->unique, $data); } if (!empty($errors)) { update_post_meta($post_id, '_csf_errors_' . $this->unique, $errors); } } do_action("csf_{$this->unique}_saved", $data, $post_id, $this); do_action("csf_{$this->unique}_save_after", $data, $post_id, $this); } } }