Skip to content

Instantly share code, notes, and snippets.

@turtlepod
Last active December 27, 2015 15:39
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save turtlepod/7349400 to your computer and use it in GitHub Desktop.
Save turtlepod/7349400 to your computer and use it in GitHub Desktop.
Simple Meta Box Helper Class
<?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