id = $id; $this->title = $title; $this->options = $options; $this->fields = array(); } function tab( $title ) { $this->add( array( 'title' => $title, 'type' => 'tab' ) ); return $this; } function add( $options ) { $this->fields[] = $options; } function end() { $tabs = array(); foreach( $this->fields as $field ) { if( $field['type'] === 'tab' ) { $tabs[] = array( 'title' => $field['title'], 'fields' => array() ); } else { $tabs[count( $tabs ) - 1]['fields'][] = $field; } } $final = array( 'id' => $this->id, 'title' => $this->title, 'pages' => $this->options['pages'], 'tabs' => $tabs ); new RW_Meta_Box_Taxonomy( $final ); } /** * Helper Functions */ function image( $id, $name, $desc, $options = array() ) { $this->add( $options + array( 'type' => 'image', 'id' => $id, 'name' => $name, 'desc' => $desc ) ); return $this; } function text( $id, $name, $desc, $options = array() ) { $this->add( $options + array( 'type' => 'text', 'id' => $id, 'name' => $name, 'desc' => $desc ) ); return $this; } function checkbox( $id, $name, $desc, $options = array() ) { $this->add( $options + array( 'type' => 'checkbox', 'id' => $id, 'name' => $name, 'desc' => $desc ) ); return $this; } function sliderhelp( $id, $name, $desc, $options = array() ) { $this->add( $options + array( 'type' => 'sliderhelp', 'id' => $id, 'name' => $name, 'desc' => $desc ) ); return $this; } function reorder( $id, $name, $desc, $options = array() ) { $this->add( $options + array( 'type' => 'reorder', 'id' => $id, 'name' => $name, 'desc' => $desc ) ); return $this; } function select( $id, $name, $desc, $options = array() ) { $this->add( $options + array( 'type' => 'select', 'id' => $id, 'name' => $name, 'desc' => $desc ) ); return $this; } function section_order( $id, $name, $desc, $options = array() ) { $this->add( $options + array( 'type' => 'section_order', 'id' => $id, 'name' => $name, 'desc' => $desc ) ); return $this; } function pagehelp( $id, $name, $desc, $options = array() ) { $this->add( $options + array( 'type' => 'pagehelp', 'id' => $id, 'name' => $name, 'desc' => $desc ) ); return $this; } function textarea( $id, $name, $desc, $options = array() ) { $this->add( $options + array( 'type' => 'textarea', 'id' => $id, 'name' => $name, 'desc' => $desc ) ); return $this; } function color( $id, $name, $desc, $options = array() ) { $this->add( $options + array( 'type' => 'color', 'id' => $id, 'name' => $name, 'desc' => $desc ) ); return $this; } function image_select( $id, $name, $desc, $options = array() ) { $this->add( $options + array( 'type' => 'image_select', 'id' => $id, 'name' => $name, 'desc' => $desc ) ); return $this; } function single_image( $id, $name, $desc, $options = array() ) { $this->add( $options + array( 'type' => 'single_image', 'id' => $id, 'name' => $name, 'desc' => $desc ) ); return $this; } } /** * Meta Box class */ class RW_Meta_Box { var $_meta_box; var $tabs; // Create meta box based on given data function __construct( $meta_box ) { if( !is_admin() ) { return; } // assign meta box values to local variables and add it's missed values $this->_meta_box = $meta_box; $this->tabs = & $this->_meta_box['tabs']; $this->add_missed_values(); add_action( 'admin_menu', array( &$this, 'add' ) ); // add meta box add_action( 'pre_post_update', array( &$this, 'save' ) ); // save meta box's data // check for some special fields and add needed actions for them $this->check_field_upload(); $this->check_field_color(); } /******************** BEGIN UPLOAD **********************/ // Check field upload and add needed actions function check_field_upload() { if( $this->has_field( 'image' ) || $this->has_field( 'file' ) ) { add_action( 'post_edit_form_tag', array( &$this, 'add_enctype' ) ); // add data encoding type for file uploading add_action( 'admin_head-post.php', array( &$this, 'add_script_upload' ) ); // add scripts for handling add/delete images add_action( 'admin_head-post-new.php', array( &$this, 'add_script_upload' ) ); add_action( 'delete_post', array( &$this, 'delete_attachments' ) ); // delete all attachments when delete post } } // Add data encoding type for file uploading function add_enctype() { echo ' enctype="multipart/form-data"'; } // Add scripts for handling add/delete images function add_script_upload() { echo ' '; } // Delete all attachments when delete post function delete_attachments( $post_id ) { $attachments = get_posts( array( 'numberposts' => -1, 'post_type' => 'attachment', 'post_parent' => $post_id ) ); if( !empty( $attachments ) ) { foreach( $attachments as $att ) { wp_delete_attachment( $att->ID ); } } } /******************** END UPLOAD **********************/ /******************** BEGIN COLOR PICKER **********************/ // Check field color function check_field_color() { if( $this->has_field( 'color' ) && $this->is_edit_page() ) { wp_enqueue_style( 'farbtastic' ); // enqueue built-in script and style for color picker wp_enqueue_script( 'farbtastic' ); } } // Custom script for color picker function add_script_color() { $ids = array(); foreach( $this->tabs as $tab ) { foreach( $tab['fields'] as $field ) { if( 'color' == $field['type'] ) { $ids[] = $field['id']; } } } echo ' '; } /******************** END COLOR PICKER **********************/ /******************** BEGIN META BOX PAGE **********************/ // Add meta box for multiple post types function add() { 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'] ); } } // Callback function to show fields in meta box function show() { global $post; wp_nonce_field( basename( __FILE__ ), 'rw_meta_box_nonce' ); echo '
'; foreach( $this->_meta_box['tabs'] as $counter => $tab ) { $counter++; $id = preg_replace( "/[^a-zA-Z0-9]+/", "-", $tab['title'] ); echo "
"; echo "

{$tab['title']}

"; echo "
"; $this->render_fields( $tab['fields'], "tab{$counter}" ); echo "
"; echo "
"; } echo '
'; $this->add_script_color(); } function render_fields( $fields, $tab = '' ) { global $post; echo '
'; echo ''; foreach( $fields as $field ) { $meta = get_post_meta( $post->ID, $field['id'], !( isset( $field['multiple'] ) && $field['multiple'] ) ); $meta = ( !empty( $meta ) || $meta === "0" ) ? $meta : ( isset( $field['std'] ) ? $field['std'] : '' ); echo ''; // call separated methods for displaying each type of field call_user_func( array( &$this, 'show_field_' . $field['type'] ), $field, $meta ); echo ''; } echo '
'; echo '
'; } /******************** END META BOX PAGE **********************/ /******************** BEGIN META BOX FIELDS **********************/ function show_field_begin( $field, $meta ) { echo ""; } function show_field_end( $field, $meta ) { echo "
{$field['desc']}"; } function show_field_text( $field, $meta ) { $this->show_field_begin( $field, $meta ); echo ""; $this->show_field_end( $field, $meta ); } function show_field_textarea( $field, $meta ) { $this->show_field_begin( $field, $meta ); echo ""; $this->show_field_end( $field, $meta ); } function show_field_select( $field, $meta ) { if( !is_array( $meta ) ) { $meta = (array)$meta; } $this->show_field_begin( $field, $meta ); echo ""; $this->show_field_end( $field, $meta ); } function show_field_radio( $field, $meta ) { $this->show_field_begin( $field, $meta ); foreach( $field['options'] as $key => $value ) { echo " $value "; } $this->show_field_end( $field, $meta ); } function show_field_checkbox( $field, $meta ) { $this->show_field_begin( $field, $meta ); echo " {$field['desc']}"; } function show_field_wysiwyg( $field, $meta ) { $this->show_field_begin( $field, $meta ); echo ""; $this->show_field_end( $field, $meta ); } function show_field_pagehelp( $field, $meta ) { $themenamefull = apply_filters( 'cyberchimps_current_theme_name', 'CyberChimps' ); $pagedocs = apply_filters( 'cyberchimps_page_options_help', 'http://cyberchimps.com/guide/how-to-use-the-page-or-post-page-element/' ); $this->show_field_begin( $field, $meta ); echo "Visit our $themenamefull Page Options help page here: Page Options Instructions"; } function show_field_sliderhelp( $field, $meta ) { $themenamefull = apply_filters( 'cyberchimps_current_theme_name', 'CyberChimps' ); $sliderdocs = apply_filters( 'cyberchimps_slider_options_help', 'http://cyberchimps.com' ); $this->show_field_begin( $field, $meta ); echo "Visit our $themenamefull Slider help page here: Slider Instructions"; } function show_field_reorder( $field, $meta ) { $this->show_field_begin( $field, $meta ); echo "Install the Post Types Order Plugin to control the order of your custom slides."; } function show_field_file( $field, $meta ) { global $post; if( !is_array( $meta ) ) { $meta = (array)$meta; } $this->show_field_begin( $field, $meta ); echo "{$field['desc']}
"; if( !empty( $meta ) ) { // show attached files $attachs = get_posts( array( 'numberposts' => -1, 'post_type' => 'attachment', 'post_parent' => $post->ID ) ); $nonce = wp_create_nonce( 'rw_ajax_delete_file' ); echo '
' . _( 'Uploaded files' ) . '
'; echo '
    '; foreach( $attachs as $att ) { if( wp_attachment_is_image( $att->ID ) ) { continue; } // what's image uploader for? $src = wp_get_attachment_url( $att->ID ); if( in_array( $src, $meta ) ) { echo "
  1. " . wp_get_attachment_link( $att->ID ) . " (ID}!{$src}!{$nonce}'>Delete)
  2. "; } } echo '
'; } // show form upload echo "
" . _( 'Upload new files' ) . "
" . _( 'Add more file' ) . "
"; } function show_field_image( $field, $meta ) { global $post; if( !is_array( $meta ) ) { $meta = (array)$meta; } $this->show_field_begin( $field, $meta ); echo "{$field['desc']}
"; if( !empty( $meta ) ) { // show attached images $attachs = get_posts( array( 'numberposts' => -1, 'post_type' => 'attachment', 'post_parent' => $post->ID, 'post_mime_type' => 'image', // get attached images only 'output' => ARRAY_A ) ); $nonce = wp_create_nonce( 'rw_ajax_delete_file' ); echo '
' . _( 'Uploaded images' ) . '
'; foreach( $attachs as $att ) { $src = wp_get_attachment_image_src( $att->ID, 'full' ); $src = $src[0]; if( in_array( $src, $meta ) ) { echo "

ID}!{$src}!{$nonce}'>Delete
"; } } } // show form upload echo "
" . _( 'Upload new images (Make sure to publish the post to save)' ) . "
"; } function show_field_color( $field, $meta ) { if( empty( $meta ) ) { $meta = '#'; } $this->show_field_begin( $field, $meta ); echo " " . _( 'Select a color' ) . " "; $this->show_field_end( $field, $meta ); } function show_field_checkbox_list( $field, $meta ) { if( !is_array( $meta ) ) { $meta = (array)$meta; } $this->show_field_begin( $field, $meta ); $html = array(); foreach( $field['options'] as $key => $value ) { $html[] = " $value"; } echo implode( '
', $html ); $this->show_field_end( $field, $meta ); } function show_field_date( $field, $meta ) { $this->show_field_text( $field, $meta ); } function show_field_time( $field, $meta ) { $this->show_field_text( $field, $meta ); } function show_field_section_order( $field, $meta ) { //Define image path $image_path = get_template_directory_uri() . "/cyberchimps/lib/images/"; $this->show_field_begin( $field, $meta ); echo "
"; echo "
"; echo "
Inactive Elements
"; echo "
"; foreach( $field['options'] as $key => $option ) { if( is_array( $meta ) ) { if( in_array( $key, $meta ) ) { continue; } } echo "
"; echo ''; echo "{$option}"; echo "
"; } echo "
"; echo "
"; echo '
'; echo "
"; echo "
Active Elements
"; echo "
Drag & Drop Elements
"; echo "
"; if( is_array( $meta ) ) { foreach( $meta as $key => $option ) { if( !array_key_exists( $option, $field['options'] ) ) { continue; } echo "
"; echo ''; echo '' . $field['options'][$option] . ''; echo "
"; } } echo "
"; echo "
"; echo ""; echo '
'; echo "
"; ?> show_field_end( $field, $meta ); } function show_field_image_select( $field, $meta ) { $this->show_field_begin( $field, $meta ); // var_dump($field, $meta); echo "
"; foreach( $field['options'] as $key => $option ) { echo ""; } echo ""; echo "
"; // $this->show_field_end($field, $meta); } function show_field_single_image( $field, $meta ) { $this->show_field_begin( $field, $meta ); if( $meta ) { echo "
"; } echo ""; echo "
" . __( 'or enter URL', 'cyberchimps_core' ) . "
"; echo ""; $this->show_field_end( $field, $meta ); } /******************** END META BOX FIELDS **********************/ /******************** BEGIN META BOX SAVE **********************/ // Save data from meta box function save( $post_id ) { global $pagenow; // check if this is a revision as the revision id is different to post id. if it is get the parent post id if not then get the post id $post_revision = wp_is_post_revision( $post_id ); $post_id = ( $post_revision ) ? $post_revision : $post_id; // check that the save is coming from the edit post page and not the quick edit if( 'admin-ajax.php' != $pagenow ) { if( isset( $_POST['post_type'] ) ) { $post_type = $_POST['post_type']; } else { $post_type = 'null'; } $post_type_object = get_post_type_object( $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__ ), 'rw_meta_box_nonce' ) ) // verify nonce || ( !current_user_can( $post_type_object->cap->edit_post, $post_id ) ) ) { // check permission return $post_id; } foreach( $this->tabs as $tab ) { foreach( $tab['fields'] as $field ) { $name = $field['id']; $type = $field['type']; $old = get_post_meta( $post_id, $name, !( isset( $field['multiple'] ) && $field['multiple'] ) ); $new = isset( $_POST[$name] ) ? $_POST[$name] : ( ( isset( $field['multiple'] ) && $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 ); } } } } } // Common functions for saving field function save_field( $post_id, $field, $old, $new ) { $name = $field['id']; // single value if( !( isset( $field['multiple'] ) && $field['multiple'] ) ) { if( '' != $new && $new != $old ) { update_post_meta( $post_id, $name, $new ); } elseif( '' == $new ) { delete_post_meta( $post_id, $name, $old ); } return; } // multiple values // get new values that need to add and get old values that need to delete $add = array_diff( $new, $old ); $delete = array_diff( $old, $new ); foreach( $add as $add_new ) { add_post_meta( $post_id, $name, $add_new, false ); } foreach( $delete as $delete_old ) { delete_post_meta( $post_id, $name, $delete_old ); } } function save_field_wysiwyg( $post_id, $field, $old, $new ) { $new = wpautop( $new ); $this->save_field( $post_id, $field, $old, $new ); } function save_field_file( $post_id, $field, $old, $new ) { $name = $field['id']; if( empty( $_FILES[$name] ) ) { return; } $this->fix_file_array( $_FILES[$name] ); foreach( $_FILES[$name] as $position => $fileitem ) { $file = wp_handle_upload( $fileitem, array( 'test_form' => false ) ); if( empty( $file['file'] ) ) { continue; } $filename = $file['file']; $attachment = array( 'post_mime_type' => $file['type'], 'guid' => $file['url'], 'post_parent' => $post_id, 'post_title' => preg_replace( '/\.[^.]+$/', '', basename( $filename ) ), 'post_content' => '' ); $id = wp_insert_attachment( $attachment, $filename, $post_id ); if( !is_wp_error( $id ) ) { wp_update_attachment_metadata( $id, wp_generate_attachment_metadata( $id, $filename ) ); add_post_meta( $post_id, $name, $file['url'], false ); // save file's url in meta fields } } } // Save images, call save_field_file, cause they use the same mechanism function save_field_image( $post_id, $field, $old, $new ) { $this->save_field_file( $post_id, $field, $old, $new ); } function save_field_single_image( $post_id, $field, $old, $new ) { if( isset( $_FILES[$field['id']] ) && $_FILES[$field['id']]['tmp_name'] ) { $overrides = array( 'test_form' => false ); $file = wp_handle_upload( $_FILES[$field['id']], $overrides ); if( !is_wp_error( $file ) ) { update_post_meta( $post_id, $field['id'], $file['url'] ); } } elseif( isset( $_POST[$field['id'] . '_url'] ) ) { $url = $_POST[$field['id'] . '_url']; update_post_meta( $post_id, $field['id'], $url ); } } function save_field_checkbox( $post_id, $field, $old, $new ) { $new = $new ? "1" : "0"; update_post_meta( $post_id, $field['id'], $new ); } /******************** END META BOX SAVE **********************/ /******************** BEGIN HELPER FUNCTIONS **********************/ // Add missed values for meta box function add_missed_values() { // default values for meta box $this->_meta_box = array_merge( array( 'context' => 'normal', 'priority' => 'high', 'pages' => array( 'if_custom_slides' ) ), $this->_meta_box ); // default values for fields foreach( $this->tabs as $tabkey => $tab ) { foreach( $tab['fields'] as $key => $field ) { $multiple = in_array( $field['type'], array( 'checkbox_list', 'file', 'image' ) ) ? true : false; $std = $multiple ? array() : ''; $format = 'date' == $field['type'] ? 'yy-mm-dd' : ( 'time' == $field['type'] ? 'hh:mm' : '' ); $this->tabs[$tabkey][$key] = array_merge( array( 'multiple' => $multiple, 'std' => $std, 'desc' => '', 'format' => $format, 'validate_func' => '' ), $field ); } } } // Check if field with $type exists function has_field( $type ) { foreach( $this->_meta_box['tabs'] as $tab ) { foreach( $tab['fields'] as $field ) { if( $type == $field['type'] ) { return true; } } } return false; } // Check if current page is edit page function is_edit_page() { global $pagenow; if( in_array( $pagenow, array( 'post.php', 'post-new.php' ) ) ) { return true; } return false; } /** * Fixes the odd indexing of multiple file uploads from the format: * $_FILES['field']['key']['index'] * To the more standard and appropriate: * $_FILES['field']['index']['key'] */ function fix_file_array( &$files ) { $output = array(); foreach( $files as $key => $list ) { foreach( $list as $index => $value ) { $output[$index][$key] = $value; } } $files = $output; } /******************** END HELPER FUNCTIONS **********************/ } ?> tabs as $keytab => $tab ) { foreach( $tab['fields'] as $key => $field ) { if( 'taxonomy' == $field['type'] && 'checkbox_list' == $field['options']['type'] ) { $this->tabs[$keytab]['fields'][$key]['multiple'] = true; } } } } // show taxonomy list function show_field_taxonomy( $field, $meta ) { global $post; if( !is_array( $meta ) ) { $meta = (array)$meta; } $this->show_field_begin( $field, $meta ); $options = $field['options']; $terms = get_terms( $options['taxonomy'], $options['args'] ); // checkbox_list if( 'checkbox_list' == $options['type'] ) { foreach( $terms as $term ) { echo "slug, $meta ), true, false ) . " /> $term->name
"; } } // select else { echo ""; } $this->show_field_end( $field, $meta ); } } /********************* END EXTENDING CLASS ***********************/ add_action( 'admin_print_styles-post-new.php', 'metabox_enqueue' ); add_action( 'admin_print_styles-post.php', 'metabox_enqueue' ); function metabox_enqueue() { $path_js = get_template_directory_uri() . "/cyberchimps/lib/js/"; $path_css = get_template_directory_uri() . "/cyberchimps/lib/css/"; $color = get_user_meta( get_current_user_id(), 'admin_color', true ); wp_register_style( 'metabox-tabs-css', $path_css . 'metabox-tabs.css' ); wp_register_script( 'jf-metabox-tabs', $path_js . 'metabox-tabs.js' ); wp_register_script( 'jf-metabox-tabs', $path_js . 'metabox-tabs.min.js' ); wp_enqueue_script( 'jf-metabox-tabs' ); // Load different css/js for different version of WP to support respective media uploader if( function_exists( 'wp_enqueue_media' ) ) { wp_enqueue_media(); wp_enqueue_script( 'metabox-media-uploader-3.5', $path_js . 'media-uploader-new.min.js', array( 'jquery' ) ); } else { wp_enqueue_style( 'thickbox' ); wp_enqueue_script( 'media-upload' ); wp_enqueue_script( 'thickbox' ); wp_enqueue_script( 'metabox-media-uploader-below-3.5', $path_js . 'media-uploader-old.min.js', array( 'jquery' ) ); } wp_enqueue_script( 'jf-metabox-tabs' ); wp_enqueue_script( 'jquery-touch-punch-min', $path_js . 'touch-punch.min.js', array( 'jquery' ) ); wp_enqueue_script( 'jquery-touch-sense', $path_js . 'touch-sensitive.min.js', array( 'jquery' ) ); wp_enqueue_style( 'metabox-tabs-css' ); } /********************* END DEFINITION OF META BOXES ***********************/ function cyberchimps_add_edit_form_multipart_encoding() { echo ' enctype="multipart/form-data"'; } add_action( 'post_edit_form_tag', 'cyberchimps_add_edit_form_multipart_encoding' );