* @link * @example * @version: 1.6 * * @license GNU General Public License */ /* *Changes: 1.6: -Added date-select, embed, taxonomy and parent -Added nesting of fields to have them on the same line -Moved calls to show_field_begin and show_field_end to accomedate nesting -Added get_meta_field system to allow custom retrieval of meta data on a type basis -Added load_scripts and load_styles functions for addition of custom scripts and styles. -Most scripts now relegated to seperate class-advanced-meta-box.js file -Added get_field_name and get_field_id functions for custom names and id's for fields -Changed imaging system to match closer to Rilwis's original code. Clicking images now leads to edit page -Option Ajax updating added -multiple textboxes via multiple tag added -Add new terms to taxonomies */ /** * Advanced Meta Box class */ require_once("meta-box.php"); class Advanced_Meta_Box extends RW_Meta_Box { function __construct($metabox) { if (!is_admin()) return; parent::__construct($metabox); add_action('admin_print_styles', array(__CLASS__, 'js_css')); add_action('wp_ajax_'.$this->_meta_box['id'].'_update', array(&$this, 'update'),5, 1); $this->check_field_embed(); $this->check_field_taxonomy(); } function check_field_taxonomy() { add_action('wp_ajax_'.$this->_meta_box['id'].'_new_term', array(&$this, 'add_term'),5, 1); } function add_term() { if (!isset($_POST['data'])) die(1); //check_admin_referer('rw_add_term'); $post_id = $_POST['post_id']; $tax = $_POST['tax']; $term = $_POST['data']; $parent = $_POST['parent']; wp_insert_term($term, $tax, array('parent'=>$parent)); $field = false; foreach($this->_fields as $f) { if($f['type'] === 'taxonomy' && $f['options']['taxonomy'] === $tax) { $field = $f; break; } } if(!$field) die(1); $meta = wp_get_object_terms($post_id, $tax); if(is_wp_error($meta)) die(1); if (!is_array($meta)) $meta = (array) $meta; $this->walk_taxonomy($field,$meta,$post_id, false); die(0); } /******************** BEGIN EMBED **********************/ function check_field_embed() { if (!$this->has_field('embed')) return; //AJAX calls add_action('wp_ajax_advanced_show_embed', array(&$this, 'show_embed')); add_action('wp_ajax_advanced_update_images', array(&$this, 'update_images')); } function is_embedible($url) { //Include oEmbed class require_once( ABSPATH . WPINC . '/class-oembed.php' ); //Init $oembed = _wp_oembed_get_object(); $providers = $oembed->providers; //Check if provider foreach ( $providers as $matchmask => $data ) { list( $providerurl, $regex ) = $data; // Turn the asterisk-type provider URLs into regex if ( !$regex ) $matchmask = '#' . str_replace( '___wildcard___', '(.+)', preg_quote( str_replace( '*', '___wildcard___', $matchmask ), '#' ) ) . '#i'; if ( preg_match( $matchmask, $url ) ) { return true; } } return false; } function get_embed_html($url) { require_once( ABSPATH . WPINC . '/class-oembed.php' ); $oembed = _wp_oembed_get_object(); return $oembed->get_html($url); } //EMBED AJAX CALL function show_embed() { if (!isset($_POST['data'])) die(1); $result = $this->get_embed_html($_POST['data']); if(!empty($result)){ echo $result; } else { die("Stream not embedible"); } die(); } function check_embedible() { if (!isset($_POST['data'])) die(1); if($this->is_embedible($_POST['data'])) { echo ""; } else { } } /******************** END EMBED **********************/ /******************** BEGIN SCRIPTS AND STYLE**********************/ function js_css() { parent::js_css(); // change '\' to '/' in case using Windows $content_dir = str_replace('\\', '/', WP_CONTENT_DIR); $script_dir = str_replace('\\', '/', dirname(__FILE__)); // get URL of the directory of current file, this works in both theme or plugin $base_url = str_replace($content_dir, WP_CONTENT_URL, $script_dir); wp_enqueue_script('advanced-metabox',$base_url .'/class-advanced-meta-box.js'); wp_enqueue_style('advanced-meta-box', $base_url . '/class-advanced-meta-box.css'); } function insert_images() { if (!isset($_POST['rw-insert']) || empty($_POST['attachments'])) return; check_admin_referer('media-form'); $nonce = wp_create_nonce('rw_ajax_delete'); $post_id = $_POST['post_id']; $id = $_POST['field_id']; // modify the insertion string $html = ''; foreach ($_POST['attachments'] as $attachment_id => $attachment) { if (empty($attachment['selected']) || empty($attachment['url'])) continue; $src = wp_get_attachment_image_src($attachment_id,'thumbnail'); $attachment_url = $src[0]; $post_link = get_edit_post_link($attachment_id); $li = "
  • "; $li .= ""; $li .= ""; $li .= ""; $li .= "" . __('Delete') . ""; $li .= ""; $li .= "
  • "; $html .= $li; } media_send_to_editor($html); } /******************** END SCRIPTS AND STYLE**********************/ /******************** BEGIN META BOX PAGE **********************/ // Add meta box for multiple post types. Extended to remove taxonomy metaboxes function add() { //collect taxonomies $tax_boxes = $this->collect_tax_boxes($this->_fields); foreach ($this->_meta_box['pages'] as $page) { add_meta_box($this->_meta_box['id'], $this->_meta_box['title'], array(&$this, 'show'), $page, $this->_meta_box['context'], $this->_meta_box['priority']); foreach ((array)$tax_boxes as $box) { remove_meta_box('tagsdiv-'.$box,$page,'side'); remove_meta_box($box.'div' ,$page,'side'); } } } // Callback function to show fields in meta box function show() { global $post; $nonce = wp_create_nonce( 'advanced_meta_box_nonce' ); wp_nonce_field(basename(__FILE__), 'advanced_meta_box_nonce'); echo ''; foreach ($this->_fields as $field) { echo ""; $meta = $this->get_meta($post->ID, $field, !$field['multiple']); // call separated methods for displaying each type of field $this->show_field_begin($field, $meta, $post->ID); $this->show_field($field, $meta, $post->ID); if(isset($field['fields'])) { foreach ($field['fields'] as $f) { $meta = get_post_meta($post->ID, $f['id'], !$f['multiple']); echo ''; $this->show_field($f, $meta, $post->ID); echo "\t"; } } $this->show_field_end($field, $meta); echo ""; } if($this->_meta_box['update']) { echo ""; } echo '
    "; echo ''.__('Update').''; echo ''.__('Clear').''; echo "
    '; } /******************** END META BOX PAGE **********************/ /******************** BEGIN GET FIELD NAME AND ID **********************/ function get_field_name($field, $post_id) { $name = $field['id'] . (($field['multiple'] || $field['type'] === 'taxonomy') ? "[]" : ""); return $name; } function get_field_id($field, $post_id) { return $field['id']; } /******************** END GET FIELD NAME AND ID **********************/ /******************** BEGIN GET META **********************/ //Generic meta retrieval function get_meta($post_id, $field, $single = true) { $meta_func = 'get_meta_'.$field['type']; if (method_exists($this, $meta_func)) { $meta = call_user_func(array(&$this, 'get_meta_' . $field['type']), $post_id, $field); } else { $meta = get_post_meta($post_id, $field['id'], $single); } $meta = !empty($meta) ? $meta : $field['std']; return $meta; } //Custom meta retrieval for taxonomies function get_meta_taxonomy($post_id, $field) { $meta = wp_get_object_terms($post_id, $field['options']['taxonomy']); if(is_wp_error($meta)){ return; } else { return $meta; } } //Custom meta retrieval for images /*function get_meta_image($post_id, $field) { global $wpdb; $query = "SELECT ID FROM {$wpdb->posts} WHERE post_type = 'attachment' AND post_parent = %d ORDER BY menu_order; "; return $wpdb->get_col($wpdb->prepare($query,$post_id)); } //Custom meta retrieval for files function get_meta_file ($post_id,$field) { return get_meta_image($post_id, $field); }*/ /******************** END GET META **********************/ /******************** BEGIN META BOX FIELDS **********************/ function show_field($field, $meta, $post_id='') { echo ""; call_user_func(array(&$this, 'show_field_' . $field['type']), $field, $meta, $post_id); } function show_field_begin($field, $meta, $post_id) { echo ""; } function show_field_end($field, $meta) { echo "
    {$field['desc']}
    "; } function show_field_text($field, $meta, $post_id='') { $id = $this->get_field_id($field, $post_id); $name = $this->get_field_name($field, $post_id); $size = (isset($field['length']) ? $field['length'] : "30' style='width:97%"); if($field['multiple']) { if (!is_array($meta)) $meta = (array) $meta; echo ""; echo "Add"; } else { echo ""; } } function show_field_textarea($field, $meta, $post_id='') { echo ""; } function show_field_select($field, $meta, $post_id='') { if (!is_array($meta)) $meta = (array) $meta; echo ""; } function show_field_radio($field, $meta, $post_id='') { foreach ($field['options'] as $key => $value) { echo " $value "; } } function show_field_checkbox($field, $meta, $post_id='') { echo ""; } function show_field_wysiwyg($field, $meta, $post_id='') { echo ""; } function show_field_file($field, $meta, $post_id='') { if (!is_array($meta)) $meta = (array) $meta; echo "{$field['desc']}
    "; if (!empty($meta)) { $nonce = wp_create_nonce('rw_ajax_delete'); echo '
    ' . __('Uploaded files') . '
    '; echo '
      '; foreach ($meta as $att) { // if (wp_attachment_is_image($att)) continue; // what's image uploader for? echo "
    1. " . wp_get_attachment_link($att, '' , false, false, ' ') . " (" . __('Delete') . ")
    2. "; } echo '
    '; } // show form upload echo "
    " . __('Upload new files') . "
    " . __('Add more file') . "
    "; } function show_field_image($field, $meta, $post_id='') { global $wpdb; if (!is_array($meta)) $meta = (array) $meta; $name = $this->get_field_name($field, $post_id); $nonce_delete = wp_create_nonce('rw_ajax_delete'); $nonce_sort = wp_create_nonce('rw_ajax_reorder'); echo " '; echo "" . __('Add more images') . ""; } function show_field_color($field, $meta, $post_id='') { if (empty($meta)) $meta = '#'; echo " " . __('Select a color') . " "; } function show_field_checkbox_list($field, $meta, $post_id='') { if (!is_array($meta)) $meta = (array) $meta; $html = array(); foreach ($field['options'] as $key => $value) { $html[] = " $value"; } echo implode('
    ', $html); } //Show date_select function show_field_date_select($field, $meta, $post_id='') { echo ""; echo ""; echo ""; if($meta) { $meta_month = date('n', $meta); $meta_day = date("j", $meta); $meta_year = date("Y", $meta); } else { $meta_month = $meta_day = $meta_year = NULL; } $years = range(isset($field['year_range']['max']) ? $field['year_range']['max'] :(int) date('Y'), isset($field['year_range']['min']) ? $field['year_range']['min'] : 1950); $months = array(1 => 'Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'); $days = range(1,31); echo ''; echo ''; echo ''; } // show taxonomy list function show_field_taxonomy($field, $meta, $post_id='') { if (!is_array($meta)) $meta = (array) $meta; echo "
    "; $this->walk_taxonomy($field,$meta,$post_id, false); echo "
    "; $action = $this->_meta_box['id'] . '_new_term'; $nonce = wp_create_nonce('rw_add_term'); if($field['options']['add_new']) { echo ""; echo "". __('Add New Color', 'wp-ada'). ""; } } function walk_taxonomy($field, $meta, $post_id='', $disabled = false) { $options = $field['options']; $terms = get_terms($options['taxonomy'], $options['args']); $selected_child = null; // checkbox_list if ('checkbox_list' == $options['type']) { foreach ($terms as $term) { echo "slug, $name->slug)) { echo 'checked="checked"'; $selected_child = true; continue; } } } if($disabled) { echo ' disabled="disabled"'; } echo " /> $term->name
    "; if(isset($field['options']['child'])) { $f = $field; $child = $field['options']['child']; $f['desc'] = isset($child['desc']) ? $child['desc'] : '' ; if(isset($child['child'])) { $f['options']['child'] = $child['child']; } else { unset($f['options']['child']); } if(isset($child['type'])) { $f['options']['type'] = $child['type']; } else { $f['options']['type'] = $field['type']; } $f['options']['args']['parent'] = $term->term_id; echo '
    '; $this->walk_taxonomy($f,$meta, $post_id, ($selected_child ? false : true)); echo '
    '; } } } // select else { echo ""; if(isset($field['options']['child'])) { $f = $field; $child = $field['options']['child']; $f['desc'] = isset($child['desc']) ? $child['desc'] : '' ; if(isset($child['child'])) { $f['options']['child'] = $child['child']; } else { unset($f['options']['child']); } if(isset($child['type'])) { $f['options']['type'] = $child['type']; } else { $f['options']['type'] = $field['type']; } foreach($terms as $term) { $f['options']['args']['parent'] = $term->term_id; echo '
    '; $this->walk_taxonomy($f,$meta, $post_id, ((!strcmp($term->slug, $selected_child))? false : true)); echo '
    '; } } } } function walk_taxonomy_option($taxonomy, $parent = 0, $level = 0) { $tabs = ''; for($i = 0; $i < $level; $i++) { $tabs .= '   '; } $terms = get_terms($taxonomy, array('parent'=>$parent, 'orderby' => 'slug', 'hide_empty' => false)); if(!is_wp_error($terms) && !empty($terms)) { foreach($terms as $term) { echo "" ; $this->walk_taxonomy_option($taxonomy,$term->term_id,$level+1); } } } //Creates a select box to choose a parent of a particular post type function show_field_parent($field, $meta, $post_id='') { //regular meta data only. Do not use for an attachment metabox global $post; global $wpdb; $query = "SELECT ID, post_title FROM $wpdb->posts WHERE post_type = '{$field['parent_type']}' AND post_status = 'publish' ORDER BY post_title"; $results = $wpdb->get_results($query, OBJECT); echo ''; } function show_field_date($field, $meta) { echo ""; } function show_field_time($field, $meta) { echo ""; } function show_field_embed($field, $meta, $post_id='') { $nonce = wp_create_nonce('veda_show_embed'); echo ""; echo ""; echo "
    "; echo "View Embed "; echo "Hide Embed "; echo "
    "; echo "
    "; echo "
    "; } /******************** END META BOX FIELDS **********************/ /******************** BEGIN META BOX SAVE **********************/ // Save data from meta box function save($post_id) { $post_type_object = get_post_type_object($_POST['post_type']); if ((defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) // check autosave || (!isset($_POST['post_ID']) || $post_id != $_POST['post_ID']) // check revision || (!in_array($_POST['post_type'], $this->_meta_box['pages'])) // check if current post type is supported || (!check_admin_referer(basename(__FILE__), 'advanced_meta_box_nonce')) // verify nonce || (!current_user_can($post_type_object->cap->edit_post, $post_id))) { // check permission return $post_id; } foreach ($this->_fields as $field) { $name = $field['id']; $type = $field['type']; $old = $this->get_meta($post->ID, $field); $new = isset($_POST[$name]) ? $_POST[$name] : ($field['multiple'] ? array() : ''); // validate meta value if (class_exists('RW_Meta_Box_Validate') && method_exists('RW_Meta_Box_Validate', $field['validate_func'])) { $new = call_user_func(array('RW_Meta_Box_Validate', $field['validate_func']), $new); } // call defined method to save meta value, if there's no methods, call common one $save_func = 'save_field_' . $type; if (method_exists($this, $save_func)) { call_user_func(array(&$this, 'save_field_' . $type), $post_id, $field, $old, $new); } else { $this->save_field($post_id, $field, $old, $new); } if(isset($field['fields'])) { foreach ($field['fields'] as $f) { $name = $f['id']; $type = $f['type']; $old = $this->get_meta($post->ID, $f); $new = isset($_POST[$name]) ? $_POST[$name] : ($f['multiple'] ? array() : ''); // validate meta value if (class_exists('RW_Meta_Box_Validate') && method_exists('RW_Meta_Box_Validate', $f['validate_func'])) { $new = call_user_func(array('RW_Meta_Box_Validate', $f['validate_func']), $new); } // call defined method to save meta value, if there's no methods, call common one $save_func = 'save_field_' . $type; if (method_exists($this, $save_func)) { call_user_func(array(&$this, 'save_field_' . $type), $post_id, $f, $old, $new); } else { $this->save_field($post_id, $f, $old, $new); } } } } } function update() { $post_type_object = get_post_type_object($_POST['post_type']); if ((defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) // check autosave || (!isset($_POST['post_ID'])) // check revision || (!in_array($_POST['post_type'], $this->_meta_box['pages'])) // check if current post type is supported || (!wp_verify_nonce($_POST['nonce'], 'advanced_meta_box_nonce')) // verify nonce || (!current_user_can($post_type_object->cap->edit_post, $_POST['post_ID'])) || (empty($_POST['data']))) { // check permission exit(-1); } $post_id = $_POST['post_ID']; $data = $_POST['data'][0]; print_r($data); foreach ($this->_fields as $field) { $name = $field['id']; $type = $field['type']; $old = $this->get_meta($post_id, $field); $new = isset($data[$name]) ? $data[$name] : ($field['multiple'] ? array() : ''); // validate meta value if (class_exists('RW_Meta_Box_Validate') && method_exists('RW_Meta_Box_Validate', $field['validate_func'])) { $new = call_user_func(array('RW_Meta_Box_Validate', $field['validate_func']), $new); } // call defined method to save meta value, if there's no methods, call common one $save_func = 'save_field_' . $type; if (method_exists($this, $save_func)) { call_user_func(array(&$this, 'save_field_' . $type), $post_id, $field, $old, $new); } else { $this->save_field($post_id, $field, $old, $new); } if(isset($field['fields'])) { foreach ($field['fields'] as $f) { $name = $f['id']; $type = $f['type']; $old = $this->get_meta($post_id, $f); $new = isset($data[$name]) ? $data[$name] : ($f['multiple'] ? array() : ''); // validate meta value if (class_exists('RW_Meta_Box_Validate') && method_exists('RW_Meta_Box_Validate', $f['validate_func'])) { $new = call_user_func(array('RW_Meta_Box_Validate', $f['validate_func']), $new); } // call defined method to save meta value, if there's no methods, call common one $save_func = 'save_field_' . $type; if (method_exists($this, $save_func)) { call_user_func(array(&$this, 'save_field_' . $type), $post_id, $f, $old, $new); } else { $this->save_field($post_id, $f, $old, $new); } } } } echo __('Updated.'); die(0); } function save_field_taxonomy($post_id, $field, $old, $new) { wp_set_object_terms( $post_id, $new, $field['options']['taxonomy']); } function save_field_date_select($post_id, $field, $old, $new) { if(!is_null($new['month']) || !is_null($new['day']) || !is_null($new['year'])) { $new = strtotime($new['month'].'/'.$new['day'].'/'.$new['year']); } else { $new = null; } $this->save_field($post_id,$field,$old,$new); } /******************** END META BOX SAVE **********************/ /******************** BEGIN HELPER FUNCTIONS **********************/ //Add Taxonomy extension function add_missed_values() { parent::add_missed_values(); // add 'multiple' option to taxonomy field with checkbox_list type foreach ($this->_fields as $key => $field) { if ('taxonomy' === $field['type'] && 'checkbox_list' === $field['options']['type']) { $this->_fields[$key]['multiple'] = true; } } } //Helper functions to remove taxonomy boxes function collect_tax_boxes($fields = array()) { $tax_boxes = array(); foreach($fields as $field) { if($field['type'] == 'taxonomy' && $field['options']['remove_box']) { $tax_boxes[] = $field['options']['taxonomy']; } if (isset($field['fields'])) { $tax_boxes = array_merge($this->collect_tax_boxes($field['fields']),$tax_boxes); } } return $tax_boxes; } /******************** END HELPER FUNCTIONS **********************/ } ?>