* @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 '';
}
/******************** 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 "{$field['name']} ";
}
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 "";
foreach ($field['options'] as $key => $value) {
echo "$value ";
}
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 "" . wp_get_attachment_link($att, '' , false, false, ' ') . " (" . __('Delete') . " ) ";
}
echo ' ';
}
// show form upload
echo "" . __('Upload new files') . "
";
}
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 "
";
// re-arrange images with 'menu_order', thanks Onur
if (!empty($meta)) {
$meta = implode(',', $meta);
$images = $wpdb->get_col("
SELECT ID FROM $wpdb->posts
WHERE post_type = 'attachment'
AND ID in ($meta)
ORDER BY menu_order ASC
");
foreach ($images as $image) {
$src = wp_get_attachment_image_src($image,'thumbnail');
$src = $src[0];
$post_link = get_edit_post_link($image);
echo "
" . __('Delete') . "
";
}
}
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 'Month ';
for ($month =1; $month<=12; $month++) {
echo '', $months[$month], ' ';
}
echo ' ';
echo '';
echo 'Day ';
for ($day = 1; $day <=31; $day++) {
echo '', $day, ' ';
}
echo ' ';
echo '';
echo 'Year ';
foreach ($years as $year) {
echo '', $year, ' ';
}
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 "
". __('Name')." ";
if(is_taxonomy_hierarchical($field['options']['taxonomy'])) {
echo "
Parent: ";
echo 'None ';
$this->walk_taxonomy_option($field['options']['taxonomy'],0,0);
echo " ";
}
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($field['options']['optional']) {
echo "None ";
}
foreach ($terms as $term) {
echo "slug, $meta), true, false);
if(!is_wp_error($meta) && !empty($meta)) {
foreach($meta as $name) {
if(!strcmp($term->slug, $name->slug)) {
echo 'selected="selected"';
$selected_child = $name->slug;
continue;
}
}
}
echo ">$term->name ";
}
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 "{$tabs}{$term->name} " ;
$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 '';
if($field['optional']) {
echo 'None ';
}
foreach ($results as $r) {
echo 'ID == $post->post_parent ? ' selected="selected"' : '', '>', $r->post_title, ' ';
}
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 "";
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 **********************/
}
?>