So I've been playing around with some custom metaboxes and following tutorials etc - I've got to the point where the top metabox field is saving correctly but the second one (width) doesn't save - is there anything obvious I'm doing wrong here? I've tried separating the second field's save in to a separate function to test but that also did not work.
add_action( 'add_meta_boxes', 'youtube_metaboxes' );
function youtube_metaboxes() {
add_meta_box('wpt_youtube', 'youtube URL', 'wpt_youtube', 'product', 'side', 'default');
}
function wpt_youtube() {
global $post;
echo '<input type="hidden" name="youtubemeta_noncename" id="youtubemeta_noncename" value="' .
wp_create_nonce( plugin_basename(__FILE__) ) . '" />';
$addyoutube = get_post_meta($post->ID, '_youtube', true);
echo '<input type="text" name="_youtube" value="' . $addyoutube . '" class="widefat" />';
$youtubeWidth = get_post_meta($post->ID, '_width', true);
echo 'Width: <br /><input type="text" name="_width" value="' . $youtubeWidth . '" class="widefat" />';
}
// Save the Metabox Data
function wpt_save_youtube_meta($post_id, $post) {
if ( !wp_verify_nonce( $_POST['youtubemeta_noncename'], plugin_basename(__FILE__) )) {
return $post->ID;
}
if ( !current_user_can( 'edit_post', $post->ID ))
return $post->ID;
$addyoutube_meta['_youtube'] = $_POST['_youtube'];
foreach ($addyoutube_meta as $key => $value) {
if( $post->post_type == 'revision' ) return;
$value = implode(',', (array)$value); // If $value is an array, make it a CSV (unlikely)
if(get_post_meta($post->ID, $key, FALSE)) {
update_post_meta($post->ID, $key, $value);
} else {
add_post_meta($post->ID, $key, $value);
}
if(!$value) delete_post_meta($post->ID, $key);
}
$addWidth_meta['_width'] = $_POST['_width'];
foreach ($addWidth_meta as $key => $value) {
if( $post->post_type == 'revision' ) return;
$value = implode(',', (array)$value); // If $value is an array, make it a CSV (unlikely)
if(get_post_meta($post->ID, $key, FALSE)) {
update_post_meta($post->ID, $key, $value);
} else {
add_post_meta($post->ID, $key, $value);
}
if(!$value) delete_post_meta($post->ID, $key);
}
}
add_action('save_post', 'wpt_save_youtube_meta', 1, 2); // save the custom fields
I had a look through this article:
http://wp.tutsplus.com/tutorials/reusable-custom-meta-boxes-part-1-intro-and-basic-fields/
Seems like a much better way of creating custom meta boxes.
Related
I'm trying to wrap the billing state and billing country fields on checkout in a div but seems to not work. This my code:
<div class="woocommerce-billing-fields__field-wrapper">
<?php
$fields = $checkout->get_checkout_fields( 'billing' );
foreach ( $fields as $key => $field ) {
if($key == 'billing_state'){
} else if($key == 'billing_country'){
} else{
woocommerce_form_field( $key, $field, $checkout->get_value( $key ) );
}
}
?>
<div class="state-province">
<?php woocommerce_form_field( "billing_state", $checkout->checkout_fields['billing']['billing_state'], $checkout->get_value( 'billing_state' ) ); ?>
<?php woocommerce_form_field( "billing_country", $checkout->checkout_fields['billing']['billing_country'], $checkout->get_value( 'billing_country' ) ); ?>
</div>
</div>
I found a solution disabling class 'form-row' to avoid js from woocommerce and adding priority:
function change_woocommerce_field_markup($field, $key, $args, $value) {
$field = str_replace('form-row', '', $field);
$field = '<div class="single-field-wrapper" data-priority="' . $args['priority'] .
'">' . $field . '</div>';
if($key === 'billing_state')
$field = '<div class="state-province">'.$field;
else if ($key === 'billing_country')
$field = $field.'</div>';
return $field;
}
add_filter("woocommerce_form_field","change_woocommerce_field_markup", 10, 4);
Here is the explanation: https://wordpress.stackexchange.com/questions/309700/how-to-hook-on-a-woocommerce-checkout-field/309788
I'm wondering if someone could help me. I'm trying to save the value of only the checked checkboxes in a wordpress metabox to the database as an array. So far, I've been able to save each of them as individual columns but I'd like to compile them into only one array, and when the checkbox is unclick, I'd like to update_post_meta to remove just the unclicked one. For some reason, it all keeps getting overridden.
The code I'm using that keeps saving them individually:
function save_location_meta($post_id) {
global $location_meta_fields;
// verify nonce
if (!isset($_POST['location_meta_box_nonce']) || !wp_verify_nonce($_POST['location_meta_box_nonce'], basename(__FILE__)))
return $post_id;
// check autosave
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE)
return $post_id;
// check permissions
if ('page' == $_POST['post_type']) {
if (!current_user_can('edit_page', $post_id))
return $post_id;
} elseif (!current_user_can('edit_post', $post_id)) {
return $post_id;
}
// loop through fields and save the data
foreach ($location_meta_fields as $field) {
$old = get_post_meta($post_id, $field['id'], true);
$new = $_POST[$field['id']];
if($new == '' && !$old && array_key_exists('default',$field)){
$new = $field['default'];
}
if ($new != '' && $new != $old) {
update_post_meta($post_id, $field['id'], $new);
} elseif ($new == '' && $old != '') {
$post_users = get_weekly_stats( $post_id, $field['id'], $old );
$uid_key = array_search( $field['id'], $post_users);
unset( $post_users[$uid_key] );
update_post_meta( $post_id, "_test_one", $uid_key );
update_post_meta( $post_id, "test", $post_users );
delete_post_meta($post_id, $field['id'], $old);
}
} // end foreach
}
add_action('save_post', 'save_location_meta');
The metabox callback that displays the checkboxes:
function one_callback( $post ) {
global $location_meta_fields, $post;
// Use nonce for verification
echo '<input type="hidden" name="location_meta_box_nonce" value="'.wp_create_nonce(basename(__FILE__)).'" />';
// Begin the field table and loop
echo '<table class="form-table">';
foreach ($location_meta_fields as $field) {
// get value of this field if it exists for this post
$meta = get_post_meta($post->ID, $field['id'], true);
// begin a table row with
echo '<tr>
<td>';
echo '<input type="checkbox" name="'.$field['id'].'" id="'.$field['id'].'" ',$meta ? ' checked="checked"' : '','/>
<label for="'.$field['id'].'">'.$field['label'].'</label>';
echo '</td></tr>';
} // end foreach
echo '</table>'; // end table
}
My question: How do I save the checked values in one array as opposed to one for each checked value?
You need to write the names of the inputs with "[]", then PHP will treat the saved values as array.
function one_callback( $post ) {
global $location_meta_fields, $post;
// Use nonce for verification
echo '<input type="hidden" name="location_meta_box_nonce" value="'.wp_create_nonce(basename(__FILE__)).'" />';
// Begin the field table and loop
echo '<table class="form-table">';
foreach ($location_meta_fields as $field) {
// get value of this field if it exists for this post
$meta = get_post_meta($post->ID, $field['id'], true); ?>
<tr>
<td>
<input type="checkbox" name="fields[]" value="<?php echo $field['id']; ?>" id="<?php echo $field['id']; ?>" <?php checked($meta); ?>/>
<label for="<?php echo $field['id']; ?>"><?php echo $field['label']; ?></label>';
</td>
</tr>
<?php } // end foreach
echo '</table>'; // end table
}
So if you want for example to access the first value that was checked, you can do it like this $_POST['fields'][0].
Then in your function save_location_meta(), you don't need to loop over the fields, you can just save them as array to the DB like this:
update_post_meta($post_id, 'my-fields', $_POST['fields']);
I'm trying to disable the wpautop filter on pages where the metabox checkbox is selected.
Here is the code to add my checkbox, I know it's a bit verbose but it was originally taken from an example with multiple elements to add. I'm planning on editing it later.
$prefix = 'dbkt_';
$meta_box = array(
'id' => 'my-meta-box',
'title' => 'Disable Automatic formatting?',
'page' => 'page',
'context' => 'normal',
'priority' => 'high',
'fields' => array(
array(
'name' => 'Disable wpautop?',
'id' => $prefix . 'checkbox',
'type' => 'checkbox'
)
)
);
add_action('admin_menu', 'mytheme_add_box');
// Add meta box
function mytheme_add_box() {
global $meta_box;
add_meta_box($meta_box['id'], $meta_box['title'], 'mytheme_show_box', $meta_box['page'], $meta_box['context'], $meta_box['priority']);
}
// Callback function to show fields in meta box
function mytheme_show_box() {
global $meta_box, $post;
// Use nonce for verification
echo '<input type="hidden" name="mytheme_meta_box_nonce" value="', wp_create_nonce(basename(__FILE__)), '" />';
echo '<table class="form-table">';
foreach ($meta_box['fields'] as $field) {
// get current post meta data
$meta = get_post_meta($post->ID, $field['id'], true);
echo '<tr>',
'<th style="width:20%"><label for="', $field['id'], '">', $field['name'], '</label></th>',
'<td>';
switch ($field['type']) {
case 'text':
echo '<input type="text" name="', $field['id'], '" id="', $field['id'], '" value="', $meta ? $meta : $field['std'], '" size="30" style="width:97%" />', '<br />', $field['desc'];
break;
case 'textarea':
echo '<textarea name="', $field['id'], '" id="', $field['id'], '" cols="60" rows="4" style="width:97%">', $meta ? $meta : $field['std'], '</textarea>', '<br />', $field['desc'];
break;
case 'select':
echo '<select name="', $field['id'], '" id="', $field['id'], '">';
foreach ($field['options'] as $option) {
echo '<option ', $meta == $option ? ' selected="selected"' : '', '>', $option, '</option>';
}
echo '</select>';
break;
case 'radio':
foreach ($field['options'] as $option) {
echo '<input type="radio" name="', $field['id'], '" value="', $option['value'], '"', $meta == $option['value'] ? ' checked="checked"' : '', ' />', $option['name'];
}
break;
case 'checkbox':
echo '<input type="checkbox" name="', $field['id'], '" id="', $field['id'], '"', $meta ? ' checked="checked"' : '', ' />';
break;
}
echo '</td><td>',
'</td></tr>';
}
echo '</table>';
}
add_action('save_post', 'mytheme_save_data');
// Save data from meta box
function mytheme_save_data($post_id) {
global $meta_box;
// verify nonce
if (!wp_verify_nonce($_POST['mytheme_meta_box_nonce'], basename(__FILE__))) {
return $post_id;
}
// check autosave
if (defined('DOING_AUTOSAVE') && DOING_AUTOSAVE) {
return $post_id;
}
// check permissions
if ('page' == $_POST['post_type']) {
if (!current_user_can('edit_page', $post_id)) {
return $post_id;
}
} elseif (!current_user_can('edit_post', $post_id)) {
return $post_id;
}
foreach ($meta_box['fields'] as $field) {
$old = get_post_meta($post_id, $field['id'], true);
$new = $_POST[$field['id']];
if ($new && $new != $old) {
update_post_meta($post_id, $field['id'], $new);
} elseif ('' == $new && $old) {
delete_post_meta($post_id, $field['id'], $old);
}
}
}
That is all working fine, the checkbox is added to the edit page where I want it, and it's state is saved correctly. The part I'm having issues with is actually getting the value of the checkbox and disabling wpautop based on this value.
Here is my (not working) code for disabling the filter based on the checkbox:
$is_checked = get_post_meta( $post->ID, 'my-meta-box', true );
if($is_checked){
remove_filter( 'the_content', 'wpautop' );
remove_filter( 'the_excerpt', 'wpautop' );
}
I'm really new to PHP and web programming in general so I'm having a really hard time trying to figure out how to debug my code. Is there an equivalent to a console I can print to in PHP? What is the general process to debug my code while working in a wordpress development environment?
Turns out I needed to wrap the check in a function & use an action call. Something about the order that the php is ran vs the value of the checkbox is recieved? If someone can explain why I had to do it this way that would be awesome.
Here is the working code:
add_action('template_redirect','my_function');
function my_function(){
$is_checked = get_post_meta( get_the_ID(), 'dbkt_checkbox', true );
if($is_checked) {
remove_filter( 'the_content', 'wpautop' );
remove_filter( 'the_excerpt', 'wpautop' );
}
}
I'm debugging my wordpress theme and I keep getting this notification in my functions.php file:
Undefined variable: post in (myfolders)/functions.php on line 961
This is line 961
echo apply_filters('the_content', get_post_meta($post->ID, 'mpc_projects_description', true));
The code is for a custom tinymce for my custom post type(Portfolio) project description.
What is causing variable to be undefined? Here is the code in it's entirety:
add_action( 'add_meta_boxes', 'mpc_add_description_meta_box' );
// Add the projects Meta Box
function mpc_add_description_meta_box() {
add_meta_box('mpc_add_description_meta_box', 'Project Description', 'mpc_add_description_meta_box_callback', 'portfolio', 'normal', 'high');
}
// the description output
function mpc_add_description_meta_box_callback() {
global $post;
// Noncename needed to verify where the data originated
echo '<input type="hidden" name="mpc_projects_description_noncename" id="mpc_projects_description_noncename" value="'.wp_create_nonce(plugin_basename(__FILE__)).'" />';
// Get the location data if its already been entered
$input = get_post_meta($post->ID, 'mpc_projects_description', true);
// echo '<input type="text" name="mpc_projects_description" value="' . $input . '" " />';
wp_editor($input, 'mpc_projects_description', array('textarea_name' => 'mpc_projects_description', 'editor_css' => '<style>#wp-mpc_projects_description-editor-container{background-color:white;style="width:100%;}</style>'));
echo '<table id="post-status-info" cellspacing="0"><tbody><tr><td id="wp-word-count">Word count: <span class="word-count_2">';
$words = strip_tags($input);
$count = str_word_count($words, 0);
echo $count;
echo '</span></td>
<td class="autosave-info">
<span class="autosave-message"> </span>
</td>
</tr></tbody></table>';
}
//save the data
add_action('save_post', 'mpc_save_description_meta', 1, 2); // save the custom fields
function mpc_save_description_meta($post_id, $post) {
// verify this came from the our screen and with proper authorization,
// because save_post can be triggered at other times
if ( !wp_verify_nonce( $_POST['mpc_projects_description_noncename'], plugin_basename(__FILE__) )) {
return $post->ID;
}
// Is the user allowed to edit the post or page?
if ( !current_user_can( 'edit_post', $post->ID ))
return $post->ID;
// OK, we're authenticated: we need to find and save the data
// We'll put it into an array to make it easier to loop though.
$mpc_description_meta['mpc_projects_description'] = $_POST['mpc_projects_description'];
// Add values of $mpc_description_meta as custom fields
foreach ($mpc_description_meta as $key => $value) { // Cycle through the $mpc_description_meta array!
if( $post->post_type == 'revision' ) return; // Don't store custom data twice
$value = implode(',', (array)$value); // If $value is an array, make it a CSV (unlikely)
if(get_post_meta($post->ID, $key, FALSE)) { // If the custom field already has a value
update_post_meta($post->ID, $key, $value);
} else { // If the custom field doesn't have a value
add_post_meta($post->ID, $key, $value);
}
if(!$value) delete_post_meta($post->ID, $key); // Delete if blank
}
}
echo apply_filters('the_content', get_post_meta($post->ID, 'mpc_projects_description', true));
The post global is available inside the functions but you haven't set it outside.
Change:
echo apply_filters('the_content', get_post_meta($post->ID, 'mpc_projects_description', true));
To:
global $post;
echo apply_filters('the_content', get_post_meta($post->ID, 'mpc_projects_description', true));
This could also depend on where you use this code. If you fire the code before the post object is set then you'll get this error.
If it's just in functions.php then change it to:
function wpse_post_test() {
global $post;
echo apply_filters('the_content', get_post_meta($post->ID, 'mpc_projects_description', true));
}
add_action( 'wp', 'wpse_post_test' );
After reviewing your question again it appears you are attempting to output this inside functions.php. What are you trying to achieve?
I´m woring on a costum meta-box for wordpress. Trouble is wordpress only seems to retain/save some of the values I enter in the fields.. I can´t really find a pattern either.. so here's the code:
<?php
function add_products_metaboxes() {
add_meta_box('sra_product_info', 'Product Information', 'sra_products_info', 'product', 'side', 'default');
}
// The Productinfo Metabox
function sra_products_info() {
//get access to the post object
global $post;
// Noncename needed to verify where the data originated
echo '<input type="hidden" name="productmeta_noncename" id="productmeta_noncename" value="' .
wp_create_nonce( plugin_basename(__FILE__) ) . '" />';
// Get the data from the field if its already been entered
$name = get_post_meta($post->ID, '_name', true);
$price = get_post_meta($post->ID, '_price', true);
$includes = get_post_meta($post->ID, '_includes', true);
$supports = get_post_meta($post->ID, '_supports', true);
$version = get_post_meta($post->ID, '_version' , true);
$extrainfo = get_post_meta($post->ID, '_extrainfo', true);
// Echo out the form
echo '<form>';
echo '<label for="_name">Name</label>' . '<input type="text" name="_name" value="' . $name . '"/>';
echo '<label for="_price">Price</label>' . '<input type="text" name="_price" value="' . $price . '"/>';
echo '<label for="_includes">Includes</label> <textarea name="_includes" rows="4" cols="10">' . $includes . '</textarea>';
echo '<label for="_supports">Supports</label> <input type="text" name="_supports" value="' . $supports . '"/>';
echo '<label for="_version">Version</label>' . '<input type="text" name="_version" value="' . $version . '"/>';
echo '<label for="_extrainfo">Extras</label> <textarea name="_extrainfo" rows="4" cols="10">' . $extrainfo . '</textarea>';
echo '</form>';
}
// Save the Metabox Data
function sra_save_product_meta($post_id, $post) {
// verify this came from the our screen and with proper authorization,
// because save_post can be triggered at other times
if ( !wp_verify_nonce( $_POST['productmeta_noncename'], plugin_basename(__FILE__) )) {
return $post->ID;
}
// Is the user allowed to edit the post or page?
if ( !current_user_can( 'edit_post', $post->ID ))
return $post->ID;
// OK, we're authenticated: we need to find and save the data
// check if the field exists in the posts array - if it does, then put cintent in $product_meta.
// this code needs to be refactored!
if (isset($_POST['_name'])) {
$product_meta['_name'] = $_POST['_name'];
}
if (isset($_POST['_price'])) {
$product_meta['_price'] = $_POST['_price'];
}
if (isset($_POST['_includes'])) {
$product_meta['_includes'] = $_POST['_includes'];
}
if (isset($_POST['_supports'])) {
$product_meta['_supports'] = $_POST['_supports'];
}
if (isset($_POST['_version'])) {
$product_meta['_version'] = $_POST['_version'];
}
if (isset($_POST['_extrainfo'])) {
$product_meta['_extrainfo'] = $_POST['_extrainfo'];
}
// Add values of $prpduct_meta as custom fields
foreach ($product_meta as $key => $value) { // Cycle through the $product_meta array!
if( $post->post_type == 'revision' ) return; // Don't store custom data twice
$value = implode(',', (array)$value); // If $value is an array, make it a CSL (unlikely)
if(get_post_meta($post->ID, $key, FALSE)) { // If the custom field already has a value
update_post_meta($post->ID, $key, $value);
} else { // If the custom field doesn't have a value
add_post_meta($post->ID, $key, $value);
}
if(!$value) delete_post_meta($post->ID, $key); // Delete if blank
}
}
add_action('save_post', 'sra_save_product_meta', 1, 2); // save the custom fields
Do you see any obvious mistakes? I think I've become a bit blind to my own mistakes in this code..
In general, I would advise to use prefixes for your field names. Values like _name have too much chances getting in conflict with other values with the same name elsewhere. Use things like _product_name, etc. Can you try that? If your code works with pages, it should have an impact.
And why not adding the 4th parameter with 'true' to add_post_meta() and previous value for update_post_meta()? See WordPress codex about these functions: http://codex.wordpress.org/Function_Reference/add_post_meta. So it would go:
if(get_post_meta($post->ID, $key, FALSE)) { // If the custom field already has a value
update_post_meta($post->ID, $key, $value, /***OLDVALUE***/ ); // See http://codex.wordpress.org/Function_Reference/update_post_meta for old value
} else { // If the custom field doesn't have a value
add_post_meta($post->ID, $key, $value, true);
}
I think it is clear you have a conflict with a metakey with the same name. Not in pages, but in posts. So try to use this 4th parameter to ensure you are referencing a unique key (and my advice, still, use clear prefixes to differenciate from anything else, be it plugins, core, etc.)