Last active
December 27, 2015 15:39
-
-
Save turtlepod/7349400 to your computer and use it in GitHub Desktop.
Simple Meta Box Helper Class
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
<?php | |
/* Prevent loading this file directly and/or if the class is already defined */ | |
if ( ! defined( 'ABSPATH' ) || class_exists( 'SC_Plugin_Meta_Box_Class' ) ) | |
return; | |
/** | |
* Shellcreeper Meta Boxes Class | |
* Helper class to easily create meta boxes in post edit screen with Meta Box API. | |
* Rename this class name if you use it in your plugin/theme. | |
* | |
* This program is free software; you can redistribute it and/or modify | |
* it under the terms of the GNU General Public License as published by | |
* the Free Software Foundation; either version 2 of the License, or | |
* (at your option) any later version. | |
* | |
* This program is distributed in the hope that it will be useful, | |
* but WITHOUT ANY WARRANTY; without even the implied warranty of | |
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
* GNU General Public License for more details. | |
* | |
* You should have received a copy of the GNU General Public License | |
* along with this program; if not, write to the Free Software | |
* Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA | |
* | |
* @version 0.1.0 | |
* @author David Chandra Purnama <david@shellcreeper.com> | |
* @link http://shellcreeper.com | |
* @license http://www.gnu.org/licenses/old-licenses/gpl-2.0.html | |
* @copyright Copyright (c) 2013, David Chandra Purnama | |
*/ | |
class SC_Plugin_Meta_Box_Class{ | |
/** | |
* @var $config the config for the meta box created | |
* @access public | |
*/ | |
var $config; | |
/** | |
* Class Constructor | |
* @param array $config the configuration required for the updater to work | |
* @return void | |
*/ | |
public function __construct( $config = array() ) { | |
/* Default config. */ | |
$defaults = array( | |
'id' => '', // unique meta box id | |
'title' => '', // meta box title | |
'callback' => '', // meta box callback | |
'post_types' => array( 'post' ), // $screen | |
'context' => 'normal', // 'normal', 'advanced', or 'side' | |
'priority' => 'default', // 'high', 'core', 'default' or 'low' | |
'callback_args' => null, // callback args in array() | |
'save_callback' => '', // save post callback function | |
'nonce' => '', // nonce string | |
'meta_keys' => array(), // meta keys config | |
'style' => 'margin-top:-6px;' // wrapper style | |
); | |
/* Merge configs and defaults. */ | |
$this->config = wp_parse_args( $config, $defaults ); | |
$config = $this->config; | |
/* Only load if config ID and Title is not empty. */ | |
if ( $config['id'] !== '' && $config['title'] !== '' ){ | |
/* If meta keys is not empty. */ | |
if ( !empty( $config['meta_keys'] ) ){ | |
/* Load register meta function */ | |
add_action( 'init', array( &$this, 'register_meta' ) ); | |
} | |
/* Load meta box setup */ | |
add_action( 'admin_init', array( &$this, 'load_meta_boxes' ) ); | |
} | |
} | |
/** | |
* Register meta for sanitazion | |
* @return void | |
*/ | |
public function register_meta(){ | |
/* Get config */ | |
$config = $this->config; | |
/* Only if meta_keys not empty, and is array */ | |
if ( !empty( $config['meta_keys'] ) && is_array( $config['meta_keys'] ) ){ | |
/* For each meta keys */ | |
foreach( $config['meta_keys'] as $meta_key_data ){ | |
/* For each post types */ | |
foreach( $config['post_types'] as $post_type ){ | |
/* Register meta */ | |
register_meta( $post_type, $meta_key_data['key'], $meta_key_data['sanitize'] ); | |
} | |
} | |
} | |
} | |
/** | |
* Load Meta Box | |
* @return void | |
*/ | |
public function load_meta_boxes(){ | |
/* Fire our meta box setup function on the post editor screen. */ | |
add_action( 'load-post.php', array( &$this, 'setup_meta_boxes' ) ); | |
add_action( 'load-post-new.php', array( &$this, 'setup_meta_boxes' ) ); | |
} | |
/** | |
* Setup Meta Box | |
* @return void | |
*/ | |
public function setup_meta_boxes(){ | |
/* Get config */ | |
$config = $this->config; | |
/* Save Callback function */ | |
$save_callback = array( &$this, 'save_callback' ); | |
if ( !empty( $config['save_callback'] ) && function_exists( $config['save_callback'] ) ){ | |
$save_callback = $config['save_callback']; | |
} | |
/* Add meta boxes on the 'add_meta_boxes' hook. */ | |
add_action( 'add_meta_boxes', array( &$this, 'add_meta_boxes' ), 10, 2 ); | |
/* Save post meta on the 'save_post' hook. */ | |
add_action( 'save_post', $save_callback, 10, 2 ); | |
/* Save attachment meta. */ | |
if ( in_array( 'attachment', $config['post_types'] ) ) { | |
add_action( 'add_attachment', $save_callback, 10, 2 ); | |
add_action( 'edit_attachment', $save_callback, 10, 2 ); | |
} | |
} | |
/** | |
* Add Meta Box | |
* @return void | |
*/ | |
public function add_meta_boxes( $post_type, $post ) { | |
/* Get config */ | |
$config = $this->config; | |
/* Calback function. */ | |
$callback = array( &$this, 'callback' ); | |
if ( !empty( $config['callback'] ) && function_exists( $config['callback'] ) ){ | |
$callback = $config['callback']; | |
} | |
/* Check post type and user caps. */ | |
if ( ( in_array( $post_type, $config['post_types'] ) ) && ( current_user_can( 'edit_post_meta', $post->ID ) || current_user_can( 'add_post_meta', $post->ID ) || current_user_can( 'delete_post_meta', $post->ID ) ) ){ | |
/* Add Meta Box */ | |
add_meta_box( $config['id'], $config['title'], $callback, $post_type, $config['context'], $config['priority'] ); | |
} | |
} | |
/** | |
* Callback Function | |
* @return void | |
*/ | |
public function callback( $post, $box ) { | |
/* Get config */ | |
$config = $this->config; | |
/* Open Wrapper */ | |
echo '<div id="' . sanitize_html_class( $config['id'] ) . '-meta-box" class="sc-mb-wrap" style="' . $config['style']. '">'; | |
/* Nonce */ | |
wp_nonce_field( basename( __FILE__ ), $config['nonce'] ); | |
/* Foreach meta key, create fields */ | |
foreach( $config['meta_keys'] as $meta_key_id => $meta_key_data ){ | |
/* Sanitize ID */ | |
$meta_key_id = sanitize_html_class( $meta_key_id ); | |
/* Default value */ | |
$default = ''; | |
if( isset( $meta_key_data['default'] ) ){ | |
$default = $meta_key_data['default']; | |
} | |
/* Multiple value in one key */ | |
if ( is_array( $default ) ){ | |
$post_meta_data = get_post_meta( $post->ID, $meta_key_data['key'], false ); | |
$value = array(); | |
if ( !empty( $post_meta_data ) ){ | |
$value = $post_meta_data; | |
} | |
elseif( !empty( $default ) ){ | |
$value = $default; | |
} | |
} | |
/* Single value */ | |
else{ | |
$post_meta_data = get_post_meta( $post->ID, $meta_key_data['key'], true ); | |
$value = ''; | |
if ( !empty( $post_meta_data ) ){ | |
$value = $post_meta_data; | |
} | |
elseif( !empty( $default ) ){ | |
$value = $default; | |
} | |
} | |
$title = ( isset( $meta_key_data['title'] ) ? $meta_key_data['title'] : '' ); | |
$desc = ( isset( $meta_key_data['desc'] ) ? $meta_key_data['desc'] : '' ); | |
$class = ( isset( $meta_key_data['class'] ) ? $meta_key_data['class'] : '' ); | |
$label = ( isset( $meta_key_data['label'] ) ? esc_attr( $meta_key_data['label'] ) : '' ); | |
$wrap_class = ( isset( $meta_key_data['wrap_class'] ) ? $meta_key_data['wrap_class'] : '' ); | |
$wrap_class = esc_attr( $wrap_class ); | |
$wrap_class = ( !empty( $wrap_class ) ? $wrap_class : 'misc-pub-section' ); | |
$wrap_open = '<div id="' . $meta_key_id . '-wrap" class="' . $wrap_class . '">'; | |
$wrap_close = '</div>'; | |
/* Render field based on 'type' */ | |
switch ( $meta_key_data['type'] ) { | |
/* Custom */ | |
case 'custom': | |
if ( isset( $meta_key_data['type_callback'] ) && !empty( $meta_key_data['type_callback'] ) && function_exists( $meta_key_data['type_callback'] ) ){ | |
call_user_func( $meta_key_data['type_callback'], array( | |
'post' => $post, | |
'box' => $box, | |
'meta_key_data' => $meta_key_data | |
)); | |
} | |
break; | |
/* Checkbox */ | |
case 'checkbox': | |
$checkbox_value = ( isset( $meta_key_data['value'] ) ? esc_attr( $meta_key_data['value'] ) : '1' ); | |
echo $wrap_open; | |
echo $title; | |
echo '<input type="checkbox" name="' . $meta_key_data['name'] . '" value="' . $checkbox_value . '" class="' . $class . '" id="' . $meta_key_id . '" ' . checked( $value, $checkbox_value, false ) . '/>'; | |
if( !empty( $label ) ) echo ' <label for="' . $meta_key_id . '">' . $label . '</label>'; | |
echo $desc; | |
echo $wrap_close; | |
break; | |
/* Text */ | |
case 'text': | |
echo $wrap_open; | |
echo $title; | |
if( !empty( $label ) ) echo ' <label for="' . $meta_key_id . '">' . $label . '</label>' . '<br/>'; | |
echo '<input type="text" name="' . $meta_key_data['name'] . '" class="' . $class . '" id="' . $meta_key_id . '" value="' . $value . '"/>'; | |
echo $desc; | |
echo $wrap_close; | |
break; | |
/* Textarea */ | |
case 'textarea': | |
$cols = ( isset( $meta_key_data['cols'] ) ? esc_attr( $meta_key_data['cols'] ) : '60' ); | |
$rows = ( isset( $meta_key_data['rows'] ) ? esc_attr( $meta_key_data['rows'] ) : '5' ); | |
echo $wrap_open; | |
echo $title; | |
if( !empty( $label ) ) echo ' <label for="' . $meta_key_id . '">' . $label . '</label>'; | |
echo '<textarea name="' . $meta_key_data['name'] . '" class="' . $class . '" id="' . $meta_key_id . '" cols="' . $cols . '" rows="' . $rows . '">' . $value . '</textarea>'; | |
echo $desc; | |
echo $wrap_close; | |
break; | |
/* Select */ | |
case 'select': | |
echo $wrap_open; | |
echo $title; | |
if( !empty( $label ) ) echo ' <label for="' . $meta_key_id . '">' . $label . '</label><br />'; | |
echo '<select name="' . $meta_key_data['name'] . '" class="' . $class . '" id="' . $meta_key_id . '">'; | |
foreach ( $meta_key_data['options'] as $option ) { | |
echo '<option id="' . $option['id'] . '" value="' . $option['value'] . '" ' . selected( $value, $option['value'], false ) . '>' . $option['label'] . '</option>'; | |
} | |
echo '</select>'; | |
echo $desc; | |
echo $wrap_close; | |
break; | |
/* Radio */ | |
case 'radio': | |
echo $wrap_open; | |
echo $title; | |
echo '<ul id="' . $meta_key_id . '" class="' . $class . '">'; | |
foreach ( $meta_key_data['options'] as $option ) { | |
echo '<li>'; | |
echo '<input value="' . $option['value'] . '" type="radio" name="' . $meta_key_data['name'] . '" id="' . $option['id'] . '" ' . checked( $value, $option['value'], false ) . '/>'; | |
echo ' <label for="' . $option['id'] . '">' . $option['label'] . '</label>'; | |
echo '</li>'; | |
} | |
echo '</ul>'; | |
echo $desc; | |
echo $wrap_close; | |
break; | |
/* Multicheck: using multiple data in the same key */ | |
case 'multicheck': | |
if ( is_array( $default ) ){ | |
echo $wrap_open; | |
echo $title; | |
echo '<ul id="' . $meta_key_id . '" class="' . $class . '">'; | |
foreach ( $meta_key_data['options'] as $option ) { | |
$checked = in_array( $option['value'], $value ) ? 'checked="checked"' : ''; | |
echo '<li>'; | |
echo '<input value="' . $option['value'] . '" type="checkbox" name="' . $meta_key_data['name'] . '[]' . '" id="' . $option['id'] . '" ' . $checked . '>'; | |
echo ' <label for="' . $option['id'] . '">' . $option['label'] . '</label>'; | |
echo '</li>'; | |
} | |
echo '</ul>'; | |
echo $desc; | |
echo $wrap_close; | |
} | |
break; | |
} | |
} | |
/* Close Wrapper */ | |
echo '</div>'; | |
} | |
/** | |
* Save Callback Function | |
* @return void | |
*/ | |
public function save_callback( $post_id, $post = '' ) { | |
/* Get config */ | |
$config = $this->config; | |
/* Fix for attachment save issue in WordPress 3.5. @link http://core.trac.wordpress.org/ticket/21963 */ | |
if ( !is_object( $post ) ){ | |
$post = get_post(); | |
} | |
/* Verify the nonce before proceeding. */ | |
if ( !isset( $_POST[$config['nonce']] ) || !wp_verify_nonce( $_POST[$config['nonce']], basename( __FILE__ ) ) ){ | |
return $post_id; | |
} | |
/* Return on auto save, ajax, cron */ | |
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) | |
return; | |
if ( defined( 'DOING_AJAX' ) && DOING_AJAX ) | |
return; | |
if ( defined( 'DOING_CRON' ) && DOING_CRON ) | |
return; | |
if ( 'revision' === $post->post_type ) | |
return; | |
/* Get the post type object. */ | |
$post_type = get_post_type_object( $post->post_type ); | |
/* Check if the current user has permission to edit the post. */ | |
if ( !current_user_can( $post_type->cap->edit_post, $post_id ) ){ | |
return $post_id; | |
} | |
/* Foreach meta key, create fields */ | |
foreach( $config['meta_keys'] as $meta_key_id => $meta_key_data ){ | |
/* Get the meta key. */ | |
$meta_key = $meta_key_data['key']; | |
/* Defaults */ | |
$default = ''; | |
if( isset( $meta_key_data['default'] ) ){ | |
$default = $meta_key_data['default']; | |
} | |
/* Custom validation/save post | |
------------------------------------- */ | |
if ( isset( $meta_key_data['validate'] ) && !empty( $meta_key_data['validate'] ) && function_exists( $meta_key_data['validate'] ) ){ | |
call_user_func( $meta_key_data['validate'], array( | |
'post_id' => $post_id, | |
'post' => $post, | |
'meta_key_data' => $meta_key_data | |
)); | |
} | |
/* Multiple data in one key | |
------------------------------------- */ | |
elseif ( is_array( $default ) ){ | |
/* Get the previous post meta. */ | |
$meta_values = get_post_meta( $post_id, $meta_key, false ); | |
/* Get the submitted post meta. */ | |
$new_meta_values = ( isset( $_POST[$meta_key_data['name']] ) ? $_POST[$meta_key_data['name']] : array() ); | |
/* First delete all data. */ | |
if ( current_user_can( 'delete_post_meta', $post_id, $meta_key ) ){ | |
delete_post_meta( $post_id, $meta_key ); | |
} | |
/* Only add if new data is not empty */ | |
if ( current_user_can( 'add_post_meta', $post_id, $meta_key ) && !empty( $new_meta_values ) ) { | |
foreach ( $new_meta_values as $new_meta_value ) { | |
add_post_meta( $post_id, $meta_key, $new_meta_value, false ); | |
} | |
} | |
} | |
/* Only single data in one key | |
------------------------------------- */ | |
else{ | |
/* Get the previous post meta. */ | |
$meta_value = get_post_meta( $post_id, $meta_key, true ); | |
/* Get the submitted post meta. */ | |
$new_meta_value = ( isset( $_POST[$meta_key_data['name']] ) ? $_POST[$meta_key_data['name']] : '' ); | |
/* If there is no new meta value but an old value exists, delete it. */ | |
if ( current_user_can( 'delete_post_meta', $post_id, $meta_key ) && '' == $new_meta_value && $meta_value ){ | |
delete_post_meta( $post_id, $meta_key, $meta_value ); | |
} | |
/* If a new meta value was added and there was no previous value, add it. */ | |
elseif ( current_user_can( 'add_post_meta', $post_id, $meta_key ) && $new_meta_value && '' == $meta_value ){ | |
add_post_meta( $post_id, $meta_key, $new_meta_value, true ); | |
} | |
/* If the old meta doesn't match the new meta, update the post meta. */ | |
elseif ( current_user_can( 'edit_post_meta', $post_id, $meta_key ) && $meta_value !== $new_meta_value ){ | |
update_post_meta( $post_id, $meta_key, $new_meta_value ); | |
} | |
} | |
} | |
} | |
} // end class |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment