Skip to content

Instantly share code, notes, and snippets.

@michael-cannon
Forked from jonathonbyrdziak/example.php
Last active September 13, 2015 23:02
Show Gist options
  • Star 1 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save michael-cannon/9359973 to your computer and use it in GitHub Desktop.
Save michael-cannon/9359973 to your computer and use it in GitHub Desktop.
<?php
/**
* @Author Anonymous
* @link http://www.redrokk.com
* @Package Wordpress
* @SubPackage RedRokk Library
*
* @version 2.0
*/
//security
defined('ABSPATH') or die('You\'re not supposed to be here.');
/**
*
*
* @author Anonymous
* @example
$gallery = redrokk_metabox_class::getInstance('gallery');
*/
if (!class_exists('redrokk_metabox_class')):
class redrokk_metabox_class
{
/**
* HTML 'id' attribute of the edit screen section
*
* @var string
*/
var $_id;
/**
* Save the form fields here that will be displayed to the user
*
* @var array
*/
protected $_fields;
protected $fields;
/**
* Title of the edit screen section, visible to user
* Default: None
*
* @var string
*/
var $title;
/**
* Function that prints out the HTML for the edit screen section. Pass
* function name as a string. Within a class, you can instead pass an
* array to call one of the class's methods. See the second example under
* Example below.
* Default: None
*
* @var callback
*/
var $callback = null;
/**
* The part of the page where the edit screen section should be shown
* ('normal', 'advanced', or 'side'). (Note that 'side' doesn't exist before 2.7)
* Default: 'advanced'
*
* @var string
*/
var $context = 'normal';
/**
* The priority within the context where the boxes should show
* ('high', 'core', 'default' or 'low')
* Default: 'default'
*
* @var string
*/
var $priority = 'default';
/**
* Arguments to pass into your callback function. The callback will receive the
* $post object and whatever parameters are passed through this variable.
* Default: null
*
* @var array
*/
var $callback_args;
/**
* Prebuilt metaboxes can be activated by using this type
* Default: default
*
* (options:)
* default
* images
*
* @var string
*/
var $_type;
/**
*
* @var unknown_type
*/
var $_category_name;
/**
* The type of Write screen on which to show the edit screen section
* ('post', 'page', 'link', or 'custom_post_type' where custom_post_type
* is the custom post type slug)
* Default: None
*
* @var array
*/
var $_object_types = array();
/**
* Whether or not to make the fields available as wp-options
*
* @var bool
*/
var $_isAdminPage = false;
/**
* Constructor.
*
*/
function __construct( $options = array() )
{
//initializing
$this->setProperties($options);
$this->setOptionHooks();
if (!$this->callback) {
$this->callback = array(&$this, 'show');
}
if (!$this->title) {
$this->title = ucfirst($this->_id);
}
//registering this metabox
add_action( 'add_meta_boxes', array(&$this, '_register') );
// backwards compatible (before WP 3.0)
// add_action( 'admin_init', array($this, '_register'), 1 );
add_action( 'save_post', array(&$this, '_save') );
add_filter( 'wp_redirect', array(&$this, '_redirectIntervention'), 40, 1 );
}
/**
* Method properly inturprets the given parameter and sets it accordingly
*
* @param string|object $value
*/
function setObjectTypes( $value )
{
if (is_a($value, 'redrokk_post_class')) {
$value = $value->_post_type;
}
if (is_a($value, 'redrokk_admin_class')) {
$value = $value->id;
$this->_isAdminPage = $value;
}
if (is_array($value)) {
foreach($value as $v)
$this->_object_types[] = $v;
return $this;
}
$this->_object_types[] = $value;
return $this;
}
/**
* Method is designed to return the currently visible post type
*/
function getCurrentPostType()
{
$post_type = false;
if (isset($_REQUEST['post_type'])) {
$post_type = $_REQUEST['post_type'];
}
elseif (isset($_REQUEST['post'])) {
$post = get_post($_REQUEST['post']);
$post_type = $post->post_type;
}
elseif (isset($_REQUEST['page'])) {
$post_type = $_REQUEST['page'];
}
return $post_type;
}
/**
* Method properly prepares the metabox type by binding the necessary hooks
*
* @param mixed $value
*/
function setType( $value = 'default' )
{
$this->_type = $value;
switch ($this->_type)
{
default:
case 'default':
add_action('metabox-show-'.$this->_id, array(&$this, '_renderForm'), 20 );
add_action('metabox-save-'.$this->_id, array(&$this, 'saveAsPostMeta'), 10, 2);
break;
case 'image':
case 'images':
$this->_fields = array(
array(
'name' => 'New Image',
'type' => 'title',
),
array(
'name' => 'Image Title',
'id' => $this->_id.'_post_title',
'type' => 'text',
),
array(
'name' => 'Description',
'id' => $this->_id.'_post_content',
'type' => 'textarea',
),
array(
'name' => 'Image File',
'id' => $this->_id.'_image',
'type' => 'image',
),
array(
'name' => '_metaboxed',
'id' => $this->_id.'_metaboxed',
'type' => 'hidden',
'default' => $this->_id
),
array(
'name' => 'Save Image',
'type' => 'submit',
),
);
add_action('metabox-show-'.$this->_id, array(&$this, '_renderListImageAttachments'), 20 );
add_action('metabox-show-'.$this->_id, array(&$this, '_renderForm'), 20 );
add_action('metabox-save-'.$this->_id, array(&$this, 'saveAsAttachment'), 1, 2);
break;
case 'video':
case 'videos':
$this->_fields = array(
array(
'name' => 'New Video',
'type' => 'title',
),
array(
'name' => 'Video Title',
'id' => $this->_id.'_post_title',
'type' => 'text',
),
array(
'name' => 'Description',
'id' => $this->_id.'_post_content',
'type' => 'textarea',
),
array(
'name' => 'Video File',
'id' => $this->_id.'_image',
'type' => 'image',
),
array(
'name' => 'Video Link',
'id' => $this->_id.'_link',
'type' => 'text',
),
array(
'name' => '_videocat',
'id' => $this->_id.'_videocat',
'default'=>$this->getCategory(),
'type' => 'hidden',
),
array(
'name' => '_metaid',
'id' => $this->_id.'_metaid',
'type' => 'hidden',
),
array(
'name' => 'Save Video',
'type' => 'submit',
),
);
add_action('metabox-show-'.$this->_id, array(&$this, '_renderListAttachments'), 20 );
add_action('metabox-show-'.$this->_id, array(&$this, '_renderListVideoAttachments'), 20 );
add_action('metabox-show-'.$this->_id, array(&$this, '_renderForm'), 20 );
add_action('metabox-save-'.$this->_id, array(&$this, 'saveAsPostMeta'), 1, 2);
break;
}
}
/**
* Returns the category to use
*/
function getCategory()
{
return isset($this->_category_name)
? $this->_category_name
: '_videocat';
}
/**
* Method will save the posted content as an image attachment
*
*/
function saveAsAttachment( $source, $post_id )
{
if (empty($_FILES) || !isset($_REQUEST[$this->_id.'files'])) return $source;
// initializing
$property = $_REQUEST[$this->_id.'files'];
$post_data = array();
if (isset($source[$this->_id.'_post_title']) && $source[$this->_id.'_post_title']) {
$post_data['post_title'] = $source[$this->_id.'_post_title'];
}
if (isset($source[$this->_id.'_post_content']) && $source[$this->_id.'_post_content']) {
$post_data['post_content'] = $source[$this->_id.'_post_content'];
}
$id = media_handle_upload($property, $post_id, $post_data);
$source[$property] = $id;
$type = 'post';
if ($this->getCurrentPostType() && $this->getCurrentPostType() !='page') {
$type = $this->getCurrentPostType();
}
//saving the attachment ID to the taxonomy
if (!in_array($type, get_post_types(array('public' => false)))) {
$old = get_metadata($type, $post_id, $property, true);
if ($id && $id != $old) {
wp_delete_attachment( $old, true );
update_metadata($type, $post_id, $property, $id);
}
}
foreach ((array)$source as $property => $new)
{
//skip everything but the specially prefixed
if (strpos($property, $this->_id) !== 0) continue;
if (in_array($property, array(
$this->_id.'_post_title',
$this->_id.'_post_content',
))) continue;
$old = get_metadata($type, $id, $property, true);
if ($new && $new != $old) {
update_metadata($type, $id, $property, $new);
}
elseif (!$new) {
delete_metadata($type, $id, $property, $old);
}
}
return $source;
}
/**
* Method saves the data provided as post meta values
*
* @param array $source
* @param integer $post_id
*/
function saveAsPostMeta( $source, $post_id )
{
$type = 'post';
if (!$this->getCurrentPostType()) {
$type = $this->_table;
}
//save as a file
//if there's no FILES then we save as a meta
$source = $this->saveAsAttachment( $source, $post_id );
//get the ID of this meta set
$id = false;
if (isset($source[$this->_id.'_metaid']) && $source[$this->_id.'_metaid']) {
$id = $source[$this->_id.'_metaid'];
}
// if this is a built in metabox
if ($this->_type != 'default'
&& (!isset($source[$this->_id.'_image']) || !$source[$this->_id.'_image']))
return false;
// Saving only the specially prefixed items
foreach ((array)$source as $property => $new)
{
//skip everything but the specially prefixed
if (strpos($property, $this->_id) !== 0) continue;
//each meta set has it's own ID
$property = str_replace($this->_id, $this->_category_name.'_'.$id, $property);
$old = get_metadata($type, $post_id, $property, true);
if ($new && $new != $old) {
update_metadata($type, $post_id, $property, $new);
}
elseif (!$new) {
delete_metadata($type, $post_id, $property, $old);
}
}
// maybe there's a last id
if (!$id) {
if (!$id = get_metadata($type, $post_id, '_metaidlast', true)) {
$id = 0;
}
$id++;
update_metadata($type, $post_id, '_metaidlast', $id);
}
// saving all of the standard items
foreach ((array)$source as $property => $new)
{
//skip special properties that are prefixed with the id
if (strpos($property, $this->_id) === 0) continue;
$old = get_metadata($type, $post_id, $property, true);
update_metadata($type, $post_id, $property, $new);
// if ($new && $new != $old) {
// update_metadata($type, $post_id, $property, $new);
// }
// elseif (!$new) {
// delete_metadata($type, $post_id, $property, $old);
// }
}
return true;
}
/**
* Do something with the data entered
*
* @param integer $post_id
*/
function _save( $post_id )
{
//initializing
$post = get_post($post_id);
// verify if this is an auto save routine.
// If it is our form has not been submitted, so we dont want to do anything
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return;
// verify this came from the our screen and with proper authorization,
// because save_post can be triggered at other times
if ( !isset($_REQUEST[ get_class().$this->_id ]) )
return;
if ( !wp_verify_nonce( $_REQUEST[ get_class().$this->_id ], plugin_basename( __FILE__ ) ) )
return;
// this metabox is to be displayed for a certain object type only
if ( !in_array($post->post_type, $this->_object_types) )
return;
// Check permissions
if ( 'page' == $post->post_type )
{
if ( !current_user_can( 'edit_page', $post->ID ) )
return;
}
else
{
if ( !current_user_can( 'edit_post', $post->ID ) )
return;
}
//saving the request data
if (!$this->_type) $this->setType();
do_action('metabox-save-'.$this->_id, $this->getRequestPostMetas(), $post->ID, $this );
return true;
}
/**
* Method returns the post meta
*
*/
function getRequestPostMetas()
{
$ignores = array('post_title', 'post_name', 'post_content', 'post_excerpt', 'post',
'post_status', 'post_type', 'post_author', 'ping_status', 'post_parent', 'message',
'post_category', 'comment_status', 'menu_order', 'to_ping', 'pinged', 'post_password',
'guid', 'post_content_filtered', 'import_id', 'post_date', 'post_date_gmt', 'tags_input',
'action');
$fields = array();
foreach ((array)$this->getFields() as $field) {
if (!array_key_exists('id', $field)) continue;
$fields[] = $field['id'];
}
$requests = $_REQUEST;
foreach ((array)$requests as $k => $request)
{
if ((!empty($fields) && !in_array($k, $fields))
|| (in_array($k, $ignores) || strpos($k, 'nounce') !== false))
{
unset($requests[$k]);
}
}
return apply_filters('metabox-requests-'.$this->_id, $requests);
}
/**
* Display the inner contents of the metabox
*
* @param object $post
*/
function show( $post )
{
// Use nonce for verification
wp_nonce_field( plugin_basename( __FILE__ ), get_class().$this->_id );
do_action('metabox-show-'.$this->_id, $this);
}
/**
*
*/
function getImages( $post_id = false )
{
if (!$post_id) {
global $post;
$post_id = $post->ID;
}
//
return get_children(array(
'post_parent' => $post_id,
'post_type' => 'attachment',
'post_mime_type'=> 'image',
'meta_query' => array(
array(
'key' => $this->_id.'_metaboxed',
'value' => $this->_id,
'compare' => '='
)
)
));
}
/**
* Method displays a list of attached images
*
*/
function _renderListImageAttachments()
{
global $post, $current_screen;
$images = $this->getImages();
// no images to render
if (empty($images)) {
?><p>No images have been saved.</p><?php
// rendering the images
} else {
?>
<table class="wp-list-table form-table widefat" style="border:none;">
<?php foreach ((array)$images as $post_id => $image): ?>
<?php $image_attributes = wp_get_attachment_image_src( $image->ID, 'thumbnail' ); ?>
<tbody id="the-list">
<tr>
<th scope="row" style="width:20%!important">
<div style="padding:10px;background:whiteSmoke;">
<img src="<?php echo wp_get_attachment_thumb_url( $image->ID ); ?>" /></div>
</th>
<td>
<b><?php echo $image->post_title; ?></b>
<p><?php echo get_the_content($image->ID); ?></p>
<div class="row-actions">
<span class="inline">
<a href="<?php echo wp_nonce_url(
"media.php?attachment_id=$image->ID"
."&action=edit&_redirect="
.urlencode( $this->_currentPageURL() )
); ?>">
Edit</a> |
</span>
<span class="trash">
<a class="submitdelete"
onclick="return showNotice.warn();"
href="<?php echo wp_nonce_url(
"post.php?action=delete&_redirect="
.urlencode( $this->_currentPageURL() )
."&amp;post=$image->ID",
'delete-attachment_' . $image->ID ); ?>">
Delete Permanently</a> |
</span>
<span class="inline">
<a target="_blank"
href="<?php echo get_attachment_link($image->ID); ?>">
View</a>
</span>
</div>
</td>
</tr>
</tbody>
<?php endforeach; ?>
</table>
<?php
}
return;
}
/**
* Return a clean list of meta listings created by this system
*
* @param string $category
* $param object $post
*/
public static function getMetaListings( $category, $post = null )
{
// initializing
if ($post === NULL) {
global $post;
}
$custom = get_post_custom($post->ID);
$return = array();
//looping all values to build our return array
foreach((array)$custom as $property => $value)
{
$parts = explode('_',$property);
if (!isset($parts[0]) || !isset($parts[1]) || !isset($parts[2])) continue;
if ($parts[0] != $category) continue;
$pro = str_replace($parts[0].'_'.$parts[1].'_', '', $property);
$return[$parts[1]][$pro] = $value;
}
return $return;
}
/**
* Function removes a specific category meta
*
* @param string $category
* $param string $meta_id
* $param object $post
*/
public static function deleteMetaListing( $category, $meta_id, $post = null )
{
// initializing
if ($post === NULL) {
global $post;
}
$listings = redrokk_metabox_class::getMetaListings( $category, $post );
if (!isset($listings[$meta_id])) return false;
$type = 'post';
foreach((array)$listings[$meta_id] as $property => $value) {
$pro = $category.'_'.$meta_id.'_'.$property;
delete_metadata($type, $post->ID, $pro, $value[0]);
}
return true;
}
/**
* Method displays a list of meta attachments
*
*/
function _renderListAttachments()
{
global $post;
//delete action prior to pulling new listings
if (isset($_REQUEST['redrokkdelete']) && $_REQUEST['redrokkdelete']) {
redrokk_metabox_class::deleteMetaListing($this->_category_name, $_REQUEST['redrokkdelete'], $post);
}
//pull new listings
$metaListings = redrokk_metabox_class::getMetaListings($this->_category_name, $post);
if (!empty($metaListings)) {
?>
<table class="wp-list-table form-table widefat" style="border:none;">
<tbody id="the-list">
<?php foreach ((array)$metaListings as $meta_id => $video): ?>
<?php $video = apply_filters('redrokk_metabox_class::_renderListAttachments', $video, $meta_id);?>
<tr id="<?php echo $this->_category_name; ?>_<?php echo $meta_id; ?>">
<th scope="row" style="width:20%!important">
<div style="padding:10px;background:whiteSmoke;">
<?php if(isset($video['link'])) echo apply_filters('the_content', $video['link'][0]); ?>
</div>
</th>
<td>
<b><?php if(isset($video['post_title'])) echo $video['post_title'][0]; ?></b>
<p><?php if(isset($video['post_content'])) echo $video['post_content'][0]; ?></p>
<div class="row-actions">
<span class="inline">
<a href="#" id="edit_<?php echo $this->_category_name; ?>_<?php echo $meta_id; ?>">
Edit</a> |
</span>
<span class="trash">
<a class="submitdelete"
onclick="return showNotice.warn();"
href="<?php echo site_url( "wp-admin/post.php?post={$post->ID}"
."&action=edit"
."&redrokkdelete=$meta_id"
); ?>">
Delete Permanently</a>
</span>
</div>
<script type="application/javascript">
jQuery('#edit_<?php echo $this->_category_name; ?>_<?php echo $meta_id; ?>').click(function(){
var data = {
<?php
$data = array();
//making sure all fields will be cleared
foreach ((array)$this->getFields() as $field) {
if (!isset($field['id']) || !isset($field['type'])) continue;
if (!in_array($field['type'], array('text','file','image','textarea','hidden')))
continue;
$id = str_replace($this->_id.'_', '', $field['id']);
$data[$id] = "'$id':''";
}
//adding our values to the array
foreach((array)$video as $vp => $vv)
{
if (isset($vv[0])) $vv = $vv[0];
$data[$vp] = "'$vp':'$vv'";
}
//adding the meta ID to the array
$data[$id] = "'metaid':'$meta_id'";
echo implode(',',$data);
?>
};
jQuery.each(data, function(key, value){
jQuery('#<?php echo $this->_id; ?>_'+key).val( value );
});
return false;
});
</script>
</td>
<?php do_action('redrokk_metabox_class::_renderListAttachments::rows', $video, $meta_id, $this); ?>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php
}
}
/**
* Method displays a list of attached videos
*
*/
function _renderListVideoAttachments()
{
global $post;
//pull new listings
$videos =& get_children( "post_parent=$post->ID&post_type=attachment&post_mime_type=video/mp4" );
// no images to render
if (!empty($videos)) {
?>
<table class="wp-list-table form-table widefat" style="border:none;">
<tbody id="the-list">
<?php foreach ((array)$videos as $post_id => $video): ?>
<?php $image_attributes = wp_get_attachment_link( $video->ID ); ?>
<tr>
<th scope="row" style="width: 140px">
<div style="padding:10px;background:whiteSmoke;">
<?php echo $image_attributes; ?>
</div>
</th>
<td>
<b><?php echo $video->post_title; ?></b>
<p><?php echo get_the_content($video->ID); ?></p>
<div class="row-actions">
<span class="inline">
<a href="<?php echo wp_nonce_url(
"media.php?attachment_id=$meta_id"
."&action=edit&_redirect="
.urlencode( $this->_currentPageURL() )
); ?>">
Edit</a> |
</span>
<span class="trash">
<a class="submitdelete"
onclick="return showNotice.warn();"
href="<?php echo wp_nonce_url(
"post.php?action=delete&_redirect="
.urlencode( $this->_currentPageURL() )
."&amp;post=$video->ID",
'delete-attachment_' . $video->ID ); ?>">
Delete Permanently</a>
</span>
</div>
</td>
</tr>
<?php endforeach; ?>
</tbody>
</table>
<?php
}
}
/**
*
*/
function getFields()
{
// initializing
if (!$this->fields)
{
$custom = get_post_custom($this->_id);
$defaults = array(
'name' => '',
'desc' => '',
'id' => '',
'type' => 'text',
'options' => array(),
'default' => '',
'value' => '',
'class' => '',
'multiple' => '',
'args' => array(
'hide_empty' => 0,
'name' => 'element_name',
'hierarchical' => true
),
'attributes' => '',
'value' => '',
);
foreach ((array)$this->_fields as $key => $field)
{
$field = wp_parse_args($field, $defaults);
$field['args'] = wp_parse_args($field['args'], $defaults['args']);
// GET PREDEFINED OPTIONS
if (empty($field['options']))
{
$method = 'get_options'.substr($field['type'],6);
if (method_exists($this, $method))
{
$field['options'] = call_user_method($method, $this) +$field['options'];
}
}
// SAVED VALUE
if (is_array($custom) && array_key_exists($field['id'], $custom))
{
if (isset($custom[$field['id']][0])) {
$field['value'] = esc_attr( $custom[$field['id']][0] );
} else {
$field['value'] = esc_attr( $custom[$field['id']] );
}
}
elseif ($field['default'] || is_bool($field['default']))
{
if (strtolower($field['default']) == 'true') {
$field['value'] = true;
}
elseif (strtolower($field['default']) == 'false') {
$field['value'] = false;
}
else {
$field['value'] = $field['default'];
}
}
else
{
// SELECT BOX
if (substr($field['type'],0,6) == 'select')
{
if (is_array($field['options']))
$field['value'] = key($field['options']);
}
// CHECKBOX TO BOOLEAN
elseif (in_array($field['type'], array('checkbox','radio')))
{
if (!$field['default']) {
$field['value'] = false;
}
}
}
// rebuild the fields
$this->fields[$key] = $field;
}
}
return $this->fields;
}
/**
* Method renders the form from any source
*
* @param array $fields
*/
function _renderForm()
{
//initializing
global $post;
$fields = $this->getFields();
// no fields to render
if (empty($fields)) {
?>
<p>No form fields have been defined. Use <pre>
$metabox->set('_fields', array(
array(
'name' => 'Title',
'type' => 'title',
),
array(
'name' => 'Title',
'desc' => '',
'id' => 'title',
'type' => 'text',
'std' => ''
),
array(
'name' => 'image',
'desc' => '',
'id' => 'imagefile',
'type' => 'image',
'std' => ''
),
array(
'name' => 'Textarea',
'desc' => 'Enter big text here',
'id' => 'textarea_id',
'type' => 'textarea',
'std' => 'Default value 2'
),
array(
'name' => 'Select box',
'id' => 'select_id',
'type' => 'select',
'options'=> array(
'value1' => 'Value 1',
'value2' => 'Value 2',
'value3' => 'Value 3',
'value4' => 'Value 4',
)
),
array(
'name' => 'Radio',
'id' => 'radio_id',
'type' => 'radio',
'value' => 'test',
'desc' => 'Check this box if you want its value saved',
),
array(
'name' => '',
'id' => 'radio_id',
'type' => 'radio',
'value' => 'test2',
'desc' => 'Check this box if you want its value saved',
),
array(
'name' => 'Checkbox',
'id' => 'checkbox_id',
'type' => 'checkbox',
'desc' => 'Check this box if you want its value saved',
),
));</pre>
</p>
<?php
// rendering the fields
} else {
?>
<table class="form-table">
<?php
do_action("{$this->_class}_before");
$custom = get_post_custom($this->_id);
foreach ((array)$fields as $field):
extract($field);
$field['args']['name'] = $element_name = $id;
// grabbing the meta value
if (array_key_exists($id, $custom)) {
if (isset($custom[$id][0]))
$meta = esc_attr( $custom[$id][0] );
else
$meta = esc_attr( $custom[$id] );
} else {
$meta = $default;
}
$id = sanitize_title($id);
if (array_key_exists('deleteattachment', $_GET)
&& $id == $_GET['fileproperty']
&& $meta == $_GET['deleteattachment'])
{
wp_delete_attachment( $_GET['deleteattachment'], $force_delete = true );
update_post_meta($post->ID, $id, '');
}
?>
<?php switch ($type){ default: ?>
<?php if (is_callable($type) && function_exists($type)) : ?>
<tr>
<th scope="row" style="width:20%!important">
<label for="<?php echo $id; ?>"><?php echo $name; ?></label>
</th>
<td>
<?php call_user_func($type, $args); ?>
<span class="description"><?php echo $desc; ?></span>
</td>
</tr>
<?php break; endif; ?>
<?php case 'text': ?>
<tr>
<th scope="row" style="width:20%!important">
<label for="<?php echo $id; ?>"><?php echo $name; ?></label>
</th>
<td>
<input <?php echo $attributes ?>
id="<?php echo $id; ?>"
value="<?php echo $meta; ?>"
type="<?php echo $type; ?>"
name="<?php echo $id; ?>"
class="text large-text <?php echo $class; ?>" />
<span class="description"><?php echo $desc; ?></span>
</td>
</tr>
<?php break; ?>
<?php case 'submit': ?>
<?php case 'button': ?>
<tr>
<td colspan="2">
<input <?php echo $attributes ?>
id="<?php echo $id; ?>"
value="<?php echo $name; ?>"
type="submit"
name="submit"
class="button-primary <?php echo $class; ?>" />
<span class="description"><?php echo $desc; ?></span>
</td>
</tr>
<?php break; ?>
<?php case 'file': ?>
<?php case 'image': ?>
<tr>
<th scope="row" style="width:20%!important">
<label for="<?php echo $id; ?>"><?php echo $name; ?></label>
</th>
<td>
<?php if ($meta && wp_get_attachment_url( $meta ) && !in_array($this->_type, array('image','images','video','videos'))): ?>
<?php echo wp_get_attachment_image( $meta ); ?>
<span><a href="<?php echo add_query_arg('fileproperty', $id, add_query_arg('deleteattachment', $meta, $this->_currentPageURL())); ?>">
Delete Image</a></span>
<?php else: ?>
<input type="hidden" name="<?php echo $this->_id; ?>files" value="<?php echo $id; ?>" />
<!-- first hidden input forces this item to be submitted when it is not checked -->
<input <?php echo $attributes ?>
id="<?php echo $id; ?>"
type="file"
name="<?php echo $id; ?>"
onChange="jQuery(this).closest('form').attr('enctype', 'multipart/form-data');"
class="<?php echo $class; ?>" />
<?php endif; ?>
<span class="description"><?php echo $desc; ?></span>
</td>
</tr>
<?php break; ?>
<?php case 'title': ?>
<tr>
<th colspan="2" scope="row">
<h3 <?php echo $attributes ?> style="border: 1px solid #ddd;
padding: 10px;
background: #eee;
border-radius: 2px;
color: #666;
margin: 0;"><?php echo $name; ?>
</h3>
</th>
</tr>
<?php break; ?>
<?php case 'checkbox': ?>
<tr>
<th scope="row" style="width:20%!important">
<label for="<?php echo $id; ?>"><?php echo $name; ?></label>
</th>
<td>
<input type="hidden" name="<?php echo $id; ?>" value="" />
<!-- first hidden input forces this item to be submitted when it is not checked -->
<?php foreach ((array)$options as $_value => $_name): ?>
<input value="<?php echo $_value; ?>" type="checkbox" <?php echo $attributes ?>
name="<?php echo $element_name; ?>" id="<?php echo $id; ?>"
<?php echo $meta == $_value? 'checked="checked"' :''; ?>
class="<?php echo $class; ?>" />
<?php echo $_name; ?>
<?php endforeach; ?>
<span class="description"><?php echo $desc; ?></span>
</td>
</tr>
<?php break; ?>
<?php case 'radio': ?>
<tr>
<th scope="row" style="width:20%!important">
<label for="<?php echo $id; ?>"><?php echo $name; ?></label>
</th>
<td>
<?php foreach ((array)$options as $_value => $_name): ?>
<input name="<?php echo $element_name; ?>" id="<?php echo $id; ?>"
value="<?php echo $_value; ?>" type="<?php echo $type; ?>"
<?php echo $meta == $_value?'checked="checked"' :''; ?>
<?php echo $attributes ?> class="<?php echo $class; ?>" />
<?php echo $_name; ?>
<?php endforeach; ?>
<span class="description"><?php echo $desc; ?></span>
</td>
</tr>
<?php break; ?>
<?php case 'textarea': ?>
<tr>
<th scope="row" style="width:20%!important">
<label for="<?php echo $id; ?>"><?php echo $name; ?></label>
</th>
<td>
<textarea <?php echo $attributes ?>
id="<?php echo $id; ?>"
name="<?php echo $id; ?>"
class="large-text <?php echo $class; ?>"
><?php echo $meta; ?></textarea>
<span class="description"><?php echo $desc; ?></span>
</td>
</tr>
<?php break; ?>
<?php case 'wpeditor': ?>
<tr>
<th scope="row" style="width:20%!important">
<label for="<?php echo $id; ?>"><?php echo $name; ?></label>
</th>
<td>
<?php wp_editor( $meta, $id, $settings = array() ); ?>
<span class="description"><?php echo $desc; ?></span>
</td>
</tr>
<?php break; ?>
<?php case 'select_capabilities': ?>
<?php case 'select_roles': ?>
<?php case 'select_menu': ?>
<?php case 'select_pages': ?>
<?php case 'select_users': ?>
<?php case 'select_categories': ?>
<?php case 'select': ?>
<tr>
<th scope="row" style="width:20%!important">
<label for="<?php echo $id; ?>"><?php echo $name; ?></label>
</th>
<td>
<?php if ($type == 'select_categories'): ?>
<?php wp_dropdown_categories($args); ?>
<?php else: ?>
<select <?php echo $attributes ?>
id="<?php echo $id; ?>"
name="<?php echo $id; ?>"
class="<?php echo $class; ?>"
<?php echo $multiple ?"MULTIPLE SIZE='$multiple'" :''; ?>
><?php foreach ((array)$options as $_value => $_name): ?>
<option
value="<?php echo $_value; ?>"
<?php echo $meta == $_value ?' selected="selected"' :''; ?>
><?php echo $_name; ?></option>
<?php endforeach; ?></select>
<?php endif; ?>
<span class="description"><?php echo $desc; ?></span>
</td>
</tr>
<?php break; ?>
<?php case 'hidden': ?>
<tr>
<td colspan="2">
<input <?php echo $attributes ?>
id="<?php echo $id; ?>"
value="<?php echo $meta ?$meta :$default; ?>"
type="<?php echo $type; ?>"
name="<?php echo $id; ?>"
style="visibility:hidden;" />
</td>
</tr>
<?php break; ?>
<?php case 'custom': ?>
<tr>
<td colspan="2">
<?php echo $desc.$default; ?>
</td>
</tr>
<?php } ?>
<?php endforeach; ?>
</table>
<?php
}
return $this;
}
/**
* Returns an options list of menus
*/
function get_options_pages()
{
// initializing
$options = array('0'=>' -- ');
$pages = get_pages(array('post_type' => 'page', 'post_status' => 'publish'));
foreach($pages as $page) {
$options[$page->ID] = $page->post_title;
}
return $options;
}
/**
* Returns an options list of menus
*/
function get_options_menu()
{
// initializing
$options = array('0'=>' -- ');
$menus = get_terms('nav_menu', array(
'hide_empty' => 0
));
foreach($menus as $menu) {
$options[$menu->slug] = $menu->name;
}
return $options;
}
/**
* Returns an options list of users
*/
function get_options_users()
{
// initializing
global $wpdb;
$options = array('0'=>' -- ');
$query = $wpdb->prepare("SELECT $wpdb->users.ID, $wpdb->users.display_name FROM $wpdb->users");
$results = $wpdb->get_results( $query );
foreach ((array)$results as $result)
{
$options[$result->ID] = $result->display_name;
}
return $options;
}
/**
* Returns an options list of capabilities
*/
function get_options_capabilities()
{
// initializing
global $wpdb;
$options = array();
$roles = get_option($wpdb->prefix . 'user_roles');
foreach ((array)$roles as $role)
{
if(!isset($role['capabilities'])) continue;
foreach ((array)$role['capabilities'] as $cap => $v)
{
$options[$role['name']."::$cap"] = $role['name']."::$cap";
}
}
return $options;
}
/**
* Returns an options list of roles
*/
function get_options_roles()
{
// initializing
global $wpdb;
$options = array(
'read' => 'Public'
);
$roles = get_option($wpdb->prefix . 'user_roles');
foreach ((array)$roles as $role)
{
$options[strtolower($role['name'])] = $role['name'];
}
return $options;
}
/**
* Adds a box to the main column on the Post and Page edit screens
*
*/
function _register()
{
// this metabox is to be displayed for a certain object type only
if (!empty($this->_object_types) && !in_array($this->getCurrentPostType(), $this->_object_types) )
return;
if (!$this->callback_args) {
$this->callback_args = $this;
}
// if the user has not already set the type of this metabox,
// then we need to do that now
if (!$this->_type) {
$this->setType();
}
add_meta_box(
$this->_id,
$this->title,
$this->callback,
$this->getCurrentPostType(),
$this->context,
$this->priority,
$this->callback_args
);
}
/**
* Method set's the hooks for the options creted by this metabox
*
*/
function setOptionHooks()
{
foreach ((array)$this->getFields() as $field)
{
if (!isset($field['id'])) continue;
//creating the callback for the admin page
$function = create_function('$default','
if (!$default) {
$default = "'. $field['value'] .'";
}
return redrokk_admin_class::getInstance("'.$this->_isAdminPage.'")
->getOption("'.$field['id'].'", $default, true);
');
add_filter("pre_option_{$field['id']}", $function, 20, 2);
}
}
/**
* Method redirects the user if we have added a request redirect
* in the url
*
* @param string $location
*/
function _redirectIntervention( $location )
{
if (isset($_GET['_redirect'])) {
$location = urldecode($_GET['_redirect']);
}
return $location;
}
/**
* Get the current page url
*/
function _currentPageURL()
{
$pageURL = 'http';
if (isset($_SERVER["HTTPS"]) && $_SERVER["HTTPS"] == "on") {$pageURL .= "s";}
$pageURL .= "://";
if ($_SERVER["SERVER_PORT"] != "80") {
$pageURL .= $_SERVER["SERVER_NAME"].":".$_SERVER["SERVER_PORT"].$_SERVER["REQUEST_URI"];
} else {
$pageURL .= $_SERVER["SERVER_NAME"].$_SERVER["REQUEST_URI"];
}
return $pageURL;
}
/**
* Method to bind an associative array or object to the JTable instance.This
* method only binds properties that are publicly accessible and optionally
* takes an array of properties to ignore when binding.
*
* @param mixed $src An associative array or object to bind to the JTable instance.
* @param mixed $ignore An optional array or space separated list of properties to ignore while binding.
*
* @return boolean True on success.
*
* @link http://docs.joomla.org/JTable/bind
* @since 11.1
*/
public function bind($src, $ignore = array())
{
// If the source value is not an array or object return false.
if (!is_object($src) && !is_array($src))
{
trigger_error('Bind failed as the provided source is not an array.');
return false;
}
// If the source value is an object, get its accessible properties.
if (is_object($src))
{
$src = get_object_vars($src);
}
// If the ignore value is a string, explode it over spaces.
if (!is_array($ignore))
{
$ignore = explode(' ', $ignore);
}
// Bind the source value, excluding the ignored fields.
foreach ($this->getProperties() as $k => $v)
{
// Only process fields not in the ignore array.
if (!in_array($k, $ignore))
{
if (isset($src[$k]))
{
$this->$k = $src[$k];
}
}
}
return true;
}
/**
* Set the object properties based on a named array/hash.
*
* @param mixed $properties Either an associative array or another object.
*
* @return boolean
*
* @since 11.1
*
* @see set()
*/
public function setProperties($properties)
{
if (is_array($properties) || is_object($properties))
{
foreach ((array) $properties as $k => $v)
{
// Use the set function which might be overridden.
$this->set($k, $v);
}
return true;
}
return false;
}
/**
* Modifies a property of the object, creating it if it does not already exist.
*
* @param string $property The name of the property.
* @param mixed $value The value of the property to set.
*
* @return mixed Previous value of the property.
*
* @since 11.1
*/
public function set($property, $value = null)
{
$_property = 'set'.str_replace(' ', '', ucwords(str_replace('_', ' ', $property)));
if (method_exists($this, $_property)) {
return $this->$_property($value);
}
$previous = isset($this->$property) ? $this->$property : null;
$this->$property = $value;
return $previous;
}
/**
* Returns an associative array of object properties.
*
* @param boolean $public If true, returns only the public properties.
*
* @return array
*
* @see get()
*/
public function getProperties($public = true)
{
$vars = get_object_vars($this);
if ($public)
{
foreach ($vars as $key => $value)
{
if ('_' == substr($key, 0, 1))
{
unset($vars[$key]);
}
}
}
return $vars;
}
/**
* Method returns the called class
*
*/
public static function get_called_class()
{
if (function_exists('get_called_class')) {
return get_called_class();
}
$called_class = false;
$objects = array();
$traces = debug_backtrace();
foreach ($traces as $trace)
{
if (isset($trace['object'])) {
if (is_object($trace['object'])) {
$objects[] = $trace['object'];
}
}
}
if (count($objects)) {
$called_class = get_class($objects[0]);
}
return $called_class;
}
/**
*
* contains the current instance of this class
* @var object
*/
static $_instances = null;
/**
* Method is called when we need to instantiate this class
*
* @param array $options
*/
public static function getInstance( $id, $options = array() )
{
if (!isset(self::$_instances[$id]))
{
$class = self::get_called_class();
$options['_class'] = $class;
$options['_id'] = $id;
self::$_instances[$id] =& new $class($options);
}
return self::$_instances[$id];
}
}
endif;
<?php
/*
Here's a couple of metaboxes that I've recently created using this system
*/
$subpostings = redrokk_metabox_class::getInstance('subpostings', array(
'title' => '(optional) Subscription for Postings',
'description' => "As an optional feature, you have a complete api at your disposal which will allow you the ability to offer and manage member posts. In addition to these settings, you may need to create the associated pages for accepting posts from your frontend.",
'_object_types' => 'page',
'priority' => 'high',
//this combination allows you to include the metabox on a single post,
//or exclude a single post
'include_exclude' => true,
'object_ids' => 306,
'_fields' => array(
array(
'name' => 'Maximum Posts',
'id' => 'max_posts',
'type' => 'text',
'class' => 'small-text',
'desc' => "The maximum number of posts that this subscriber is allowed to make.
<br/>-1 allows an infinite number of posts
<br/> 0 does not allow the subscriber to post",
'default' => '0',
),
array(
'name' => 'New Posting Defaults',
'type' => 'title',
),
array(
'name' => 'New Post Email',
'id' => 'new_post_email',
'type' => 'checkbox',
'desc' => "Would you like an email when a subscriber makes a new post?"
),
array(
'name' => 'Post Type',
'id' => 'postnew__post_type',
'type' => 'post_type',
),
array(
'name' => 'New Post Status',
'id' => 'postnew__post_status',
'type' => 'post_status',
'desc' => "When a subscriber makes a new post it will have this status",
),
array(
'name' => 'Default Category',
'id' => 'postnew__post_category',
'type' => 'category',
),
array(
'name' => 'Tagged with',
'id' => 'postnew__tags_input',
'type' => 'text',
'desc' => "Leave a comma deliminated list of tags to add to new member posts"
),
array(
'name' => 'Edit Posting Defaults',
'type' => 'title',
),
array(
'name' => 'Edit Post Email',
'id' => 'edit_post_email',
'type' => 'checkbox',
'desc' => "Would you like an email when a subscriber makes an edit?"
),
array(
'name' => 'Can User Edit?',
'id' => 'can_user_edit',
'type' => 'checkbox',
'desc' => "Leaving unchecked will not allow users to edit their posts"
),
array(
'name' => 'Edit Post Status',
'id' => 'postedit__post_status',
'type' => 'post_status',
'desc' => "When a subscriber edits their posts, this will be the new status",
),
array(
'name' => 'Tagged with',
'id' => 'postedit__tags_input',
'type' => 'text',
'desc' => "Leave a comma deliminated list of tags to add to new member posts"
),
)
));
$subroles = redrokk_metabox_class::getInstance('subroles', array(
'title' => '(optional) Role Management',
'description' => "As an optional feature, you can use these settings to manage the users roles during certain subscription triggers.",
'_object_types' => $sub,
'priority' => 'high',
'_fields' => array(
array(
'name' => 'Role',
'id' => 'role',
'type' => 'role',
'desc' => "New subscribers will be assigned to this role.",
),
array(
'name' => 'Expired to Role',
'id' => 'downgrade_role',
'type' => 'role',
'desc' => "Terminated subscriptions will be assigned to this role.",
),
)
));
$subdisplay = redrokk_metabox_class::getInstance('subdisplay', array(
'title' => 'Subscription Listing Preview',
'_object_types' => 'post',
'priority' => 'default',
'callback' => 'ms_subdisplay', //use a valid callback to display a custom template
));
//some example fields to use in your form
$metabox->set('_fields', array(
array(
'name' => 'Title',
'type' => 'title',
),
array(
'name' => 'Title',
'desc' => '',
'id' => 'title',
'type' => 'text',
'std' => ''
),
array(
'name' => 'image',
'desc' => '',
'id' => 'imagefile',
'type' => 'image',
'std' => ''
),
array(
'name' => 'Textarea',
'desc' => 'Enter big text here',
'id' => 'textarea_id',
'type' => 'textarea',
'std' => 'Default value 2'
),
array(
'name' => 'Select box',
'id' => 'select_id',
'type' => 'select',
'options'=> array(
'value1' => 'Value 1',
'value2' => 'Value 2',
'value3' => 'Value 3',
'value4' => 'Value 4',
)
),
array(
'name' => 'Radio',
'id' => 'radio_id',
'type' => 'radio',
'value' => 'test',
'desc' => 'Check this box if you want its value saved',
),
array(
'name' => '',
'id' => 'radio_id',
'type' => 'radio',
'value' => 'test2',
'desc' => 'Check this box if you want its value saved',
),
array(
'name' => 'Checkbox',
'id' => 'checkbox_id',
'type' => 'checkbox',
'desc' => 'Check this box if you want its value saved',
),
));
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment