I want to save a meta with a checkbox for all my posts, here's my code :
add_action( 'save_post','save_metaboxes' );
function save_metaboxes( $post_ID ) {
if( isset( $_POST['is_viewpay'] ) ) {
if( !empty( $_POST['is_viewpay'] ) ) {
update_post_meta( $post_ID, '_is_viewpay', 'active' );
} else {
update_post_meta( $post_ID, '_is_viewpay', '' );
}
}
}
The problem is when I uncheck the checkbox and save my post, It always stay checked. I don't know why.
Thanks for your help !
When you uncheck the checkbox, isset($_POST['is_viewpay']) will evaluate to false so it skips over your remaining code.
Instead you could do:
if(isset($_POST['is_viewpay'])) {
update_post_meta($post_ID, '_is_viewpay', 'active');
} else {
update_post_meta($post_ID, '_is_viewpay', '');
}
As a side note, it's highly recommended to use Nonces (which will help protect your page from malicious attacks).
Related
I use the following lines to save a Value to the database. I have one question regarding this code, when I delete input it still keeps it. The only way to delete that is to put (space) as input.
$field_key_pills_1 = 'custom_text_field_category_pills';
if ( isset( $_POST[$field_key_pills_1] ) && ! empty( $_POST[$field_key_pills_1] ) ) {
$attribute_pills_1 = wc_get_product( $post_id );
$attribute_pills_1->update_meta_data( $field_key_pills_1, sanitize_text_field( $_POST[$field_key_pills_1] ) );
$attribute_pills_1->save();
} else {
$attribute_pills_1 = wc_get_product( $post_id );
$attribute_pills_1 = delete_post_meta( $post_id, 'custom_text_field_category_pills' );
}
Please give me any tip that you think, can solve this problem.
Try instead the following revisited code using WC_Data delete_meta_data() method to remove product meta data (meta key + value):
$key_pills_1 = 'custom_text_field_category_pills';
$product_pills1 = wc_get_product( $post_id );
// Check that the product and the product input field exists
if ( is_a($product_pills1, 'WC_Product') && isset($_POST[$key_pills_1]) {
if ( ! empty($_POST[$key_pills_1]) ) {
$product_pills1->update_meta_data( $key_pills_1, sanitize_text_field($_POST[$key_pills_1]) ); // Set or update
} else {
$product_pills1->delete_meta_data( $key_pills_1 ); // remove
}
$product_pills1->save(); // Sync and save to database
}
It should work.
I have a custom metabox that I created and have been using on my website for a while, but there's a bit of an issue with how it saves. It tends to be rather volatile, meaning that when backing-up with xml or bulk-editing, it will always lose the data.
The following is the code that I use for the checkbox and to save it
function member_page_featured_meta() {
add_meta_box( 'member_page_meta', __( 'Page Template (if default, select none)', 'member_page_textdomain' ), 'member_page_meta_callback', 'page', 'side', 'low' );
}
add_action( 'add_meta_boxes', 'member_page_featured_meta' );
/**
* Outputs the content of the meta box
*/
function member_page_meta_callback( $post ) {
$values = get_post_meta( $post->ID );
$check = isset( $values['member_box_check'] ) ? esc_attr( $values['member_box_check'][0] ) : '';
wp_nonce_field( basename( __FILE__ ), 'member_page_nonce' );
$member_page_stored_meta = get_post_meta( $post->ID );
?>
<p>
<div class="member_page-row-content">
<label for="featured-checkbox">
<input type="checkbox" name="featured-checkbox" id="featured-checkbox" value="yes" <?php if ( isset ( $member_page_stored_meta['featured-checkbox'] ) ) checked( $member_page_stored_meta['featured-checkbox'][0], 'yes' ); ?> />
<?php _e( 'Member Page', 'member_page_textdomain' )?>
</label><br />
<label for="list-checkbox">
<input type="checkbox" name="list-checkbox" id="list-checkbox" value="yes" <?php if ( isset ( $member_page_stored_meta['list-checkbox'] ) ) checked( $member_page_stored_meta['list-checkbox'][0], 'yes' ); ?> />
<?php _e( 'Home List', 'member_page_textdomain' )?>
</label><br />
</div>
</p>
<?php
}
/**
* Saves the custom meta input
*/
function member_page_meta_save( $post_id ) {
// Checks save status - overcome autosave, etc.
$is_autosave = wp_is_post_autosave( $post_id );
$is_revision = wp_is_post_revision( $post_id );
$is_valid_nonce = ( isset( $_POST[ 'member_page_nonce' ] ) && wp_verify_nonce( $_POST[ 'member_page_nonce' ], basename( __FILE__ ) ) ) ? 'true' : 'false';
// Exits script depending on save status
if ( $is_autosave || $is_revision || !$is_valid_nonce ) {
return;
}
// Checks for input and saves - save checked as yes and unchecked at no
//This line of code is my hack (just keeps the boxes from saving pretty much)
//if (!empty($_POST['featured-checkbox']) && !empty($_POST['list-checkbox'])) {
if( isset( $_POST[ 'featured-checkbox' ] ) ) {
update_post_meta( $post_id, 'featured-checkbox', 'yes' );
} else {
update_post_meta( $post_id, 'featured-checkbox', 'no' );
};
if( isset( $_POST[ 'list-checkbox' ] ) ) {
update_post_meta( $post_id, 'list-checkbox', 'yes' );
} else {
update_post_meta( $post_id, 'list-checkbox', 'no' );
};
// (bracket ending the first if statement) }
}
add_action( 'save_post', 'member_page_meta_save' );
Is there any way to prevent this issue from happening or is it just something that has to be dealt with when saving check-boxes?
I've sorted out a bit of a hack that is working for now, but whenever I need to make changes to the check-boxes (which is fairly often by the nature of how they're used), I have to comment out a few lines of code, make the change, then un-comment the lines of code and it's a bit unconventional.
I mostly need to make it work when backing-up and restoring (on my backup/production website).
The save_post action is triggered when a post is created or updated, so quick edits and regular edits and the import of posts will trigger it too.
It is actually your script which clears the post meta when doing a quick edit or import, because the POST array does not contain the previously saved values of the checkboxes.
To solve this, you might want to know the "type of saving" currently happening, and only update the post meta when you are on the post edit screen in the admin area. A way of doing this is to check the action parameter of the POST array like the following, because the action parameter only has the value editpost when saving from a post edit screen:
if (filter_input(INPUT_POST, 'action') != 'editpost') {
return;
}
Putting this code at the beginning of the function hooked to the save_post action (member_page_meta_save in your case) will let the rest of the function run only when saving from the post edit screen.
I am trying to add the ability to update a meta value through Wordpress's bulk post edit menu. I have it working on a single post, but I can't figure out why it's not working for bulk.
// Add our text to the quick & bulk edit box
add_action('quick_edit_custom_box', 'on_quick_edit_custom_box', 10, 2);
add_action('bulk_edit_custom_box', 'on_quick_edit_custom_box', 10, 2);
function on_quick_edit_custom_box($column_name, $post_type) {
global $post;
$postMeta = get_post_meta( $post->ID, 'wpsl_locatorID', true );
if ('wpsl_locatorID' == $column_name && get_post_type() == 'location' ) {
echo "<fieldset class=\"inline-edit-col-right\" style=\"margin-top: 0;\">";
echo "<div class=\"inline-edit-col\">";
echo "<div class=\"inline-edit-group\">";
echo "<label class=\"alignleft\">";
echo "<span class=\"title\" for=\"wpsl_locatorID\">Movie ID</span>";
echo "<input type=\"text\" name=\"wpsl_locatorID\" id=\"wpsl_locatorID\" value=\"{$postMeta}\" />";
echo "</label>";
echo "</div>";
echo "</fieldset>";
};
}
// Update the post meta
add_action( 'save_post', 'locationMetaUpdate', 10, 2 );
function locationMetaUpdate( $post_id ) {
// Bail if we're doing an auto save
if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
// if our nonce isn't there, or we can't verify it, bail
// if un-commented than the value won't update at all. I'm guessing b/c of WP's ajax function vs. reloading the page.
//if( !isset( $_POST['meta_box_nonce'] ) || !wp_verify_nonce( $_POST['meta_box_nonce'], 'my_meta_box_nonce' ) ) return;
// if our current user can't edit this post, bail
if ( ! current_user_can( 'edit_posts' ) ) return;
// Make sure that it is set.
if ( ! isset( $_POST['wpsl_locatorID'] ) ) {
return;
}
// Sanitize user input.
$my_data = sanitize_text_field( $_POST['wpsl_locatorID'] );
// Update the meta field in the database.
update_post_meta( $post_id, 'wpsl_locatorID', $my_data );
};
Like I said above, this works for a single quick edit but not on bulk edit. I've tried to find a solution, but I'm sure it's something simple I'm missing.
So honestly I'm not sure why it's now working; but all I did was condense the action like on WP's save_post codex page.
// Update the post meta
add_action( 'save_post', 'locationMetaUpdate', 10, 3 );
function locationMetaUpdate( $post_id, $post, $update ) {
//print_r($_POST); die();
// if our current user can't edit this post, bail
if ( ! current_user_can( 'edit_posts' ) ) return;
// Make sure that it is set.
if ( isset( $_REQUEST['wpsl_locatorID'] ) ) {
update_post_meta( $post_id, 'wpsl_locatorID', sanitize_text_field( $_REQUEST['wpsl_locatorID'] ) );
}
}
I am creating a metabox that loops through all the posts of another CPT: 'product'. The metabox lists all the published products in that CPT, puts them in a table row along with an input box. Each input box has a unique ID based off of the CPT product id.
Most of this code I have added based on other posts, but I am having a problem saving the data. I know that it has to do with my value="", my nonce, and $meta_value, but I am not sure where to go next. Below is the code I have so far:
<?php
add_action('admin_init', 'my_theme_on_admin_init');
function my_theme_on_admin_init() {
add_meta_box('my_metabox',
__('Daily Inventory Levels', 'textdomain'),
'my_metabox_render',
'location_inventory', 'normal', 'high'
);
}
function my_metabox_render($post) {
// using an underscore, prevents the meta variable
// from showing up in the custom fields section
global $woocommerce, $post;
$productsList = new WP_Query( 'post_type=product&post_status=publish');
?>
<div class="inside">
<table class="form-table">
<input type="hidden" name="inventory_noncename" id="inventory_noncename" value="<?php wp_create_nonce( 'inventory-nonce' ); ?>" />
<?php
while ( $productsList->have_posts() ) {
$productsList->the_post();
?>
<tr><td><label for="location_inventory_product-<?php the_ID(); ?>"><?php the_title(); ?></label></td><td><input id="location_inventory_product-<?php the_ID(); ?>" name="location_inventory_product-<?php the_ID(); ?>" cols="40" rows="5" value="<?php echo $meta_key; ?>" /></td></tr>
<?php }
wp_reset_postdata();
?>
</table>
</div>
<?php
}
/*update on save*/
add_action('save_post', 'save_postdata_dynamic_inventory_metabox' );
function save_postdata_dynamic_inventory_metabox( $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;
}
// Check permissions
if ( 'location_inventory' == $_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;
}
// verify this came from the our screen and with proper authorization,
// because save_post can be triggered at other times
if (isset($_POST['inventory_noncename'])){
if ( !wp_verify_nonce( $_POST['inventory_noncename'], 'inventory-nonce' ) )
return;
} else {
return;
}
// Get the posted data and sanitize it for use as an HTML class.
$new_meta_value = ( isset( $_POST['location_inventory_product-'.the_ID().''] ) ? sanitize_html_class( $_POST['location_inventory_product-'.the_ID().''] ) : '' );
// Get the meta key.
$meta_key = 'location_inventory_product-'.the_ID().'';
// Get the meta value of the custom field key.
$meta_value = get_post_meta( $post_id, $meta_key, true );
// If a new meta value was added and there was no previous value, add it.
if ( $new_meta_value && '' == $meta_value )
add_post_meta( $post_id, $meta_key, $new_meta_value, true );
// If the new meta value does not match the old value, update it.
elseif ( $new_meta_value && $new_meta_value != $meta_value )
update_post_meta( $post_id, $meta_key, $new_meta_value );
// If there is no new meta value but an old value exists, delete it.
elseif ( '' == $new_meta_value && $meta_value )
delete_post_meta( $post_id, $meta_key, $meta_value );
} // ends function save_postdata_dynamic_reviews_metabox
Some observations:
1) The hook save_post takes 2 arguments:
add_action( 'save_post', 'save_postdata_dynamic_inventory_metabox', 10, 2 );
function save_postdata_dynamic_inventory_metabox( $post_id, $post_object ) { }
2) I don't think checking for permissions is necessary (at least, never seen it). Just in case, this is an example of the post_object use:
if ( 'location_inventory' == $post_object->post_type )
3) Short this check:
if ( !isset($_POST['inventory_noncename']) || !wp_verify_nonce( $_POST['inventory_noncename'], 'inventory-nonce' ) )
return;
4) The use of the_ID() inside the function save_postdata_dynamic_inventory_metabox is wrong. This is only available inside a Loop and you already have $post_id at hand.
5) Finally, and the most important, the way you're handling the $meta_key is wrong. For one, it's not defined inside the function my_metabox_render. Check this Answer for a working example.
Research in this search query to find more examples.
I'm trying to add a checkbox into my custom meta box in WordPress and I ran into a problem with saving it - whenever I check the checkbox and update the post/page, it comes back unchecked again.
Here's the code I'm using:
add_meta_box(
'sl-meta-box-sidebar', // id
'Sidebar On/Off', // title
'sl_meta_box_sidebar', // callback function
'page', // type of write screen
'side', // context
'low' // priority
);
function sl_meta_box_sidebar() {
global $meta; sl_post_meta( $post->ID ); ?>
<input type="checkbox" name="sl_meta[sidebar]" value="<?php echo htmlspecialchars ($meta['sidebar']); ?>" />Check to turn the sidebar <strong>off</strong> on this page.
}
This creates the checkbox in the sidebar of the "Edit Page" screen, as it should, no problem there. I'm not sure what should I enter in the value of the checkbox, with text fields it obviously returns whatever was saved as meta information... I tried just using "checked" instead cause that would be my first guess (then simply check for the value when using this meta data), but it didn't save the checkbox either.
Here's the function that saves all the meta data, which I assume causes this problem:
function sl_save_meta_box( $post_id, $post ) {
global $post, $type;
$post = get_post( $post_id );
if( !isset( $_POST[ "sl_meta" ] ) )
return;
if( $post->post_type == 'revision' )
return;
if( !current_user_can( 'edit_post', $post_id ))
return;
$meta = apply_filters( 'sl_post_meta', $_POST[ "sl_meta" ] );
foreach( $meta as $key => $meta_box ) {
$key = 'meta_' . $key;
$curdata = $meta_box;
$olddata = get_post_meta( $post_id, $key, true );
if( $olddata == "" && $curdata != "" )
add_post_meta( $post_id, $key, $curdata );
elseif( $curdata != $olddata )
update_post_meta( $post_id, $key, $curdata, $olddata );
elseif( $curdata == "" )
delete_post_meta( $post_id, $key );
}
do_action( 'sl_saved_meta', $post );
}
add_action( 'save_post', 'sl_save_meta_box', 1, 2 );
It works perfectly for text fields, but the checkbox just won't save. I'm not sure if the saving function is wrong, or am I missing something about the value of the checkbox.
Any help appreciated!
I had trouble with this previously and here is how I solved it.
First, creating the Checkbox.
<?php
function sl_meta_box_sidebar(){
global $post;
$custom = get_post_custom($post->ID);
$sl_meta_box_sidebar = $custom["sl-meta-box-sidebar"][0];
?>
<input type="checkbox" name="sl-meta-box-sidebar" <?php if( $sl_meta_box_sidebar == true ) { ?>checked="checked"<?php } ?> /> Check the Box.
<?php } ?>
Next, saving.
<?php
add_action('save_post', 'save_details');
function save_details($post_ID = 0) {
$post_ID = (int) $post_ID;
$post_type = get_post_type( $post_ID );
$post_status = get_post_status( $post_ID );
if ($post_type) {
update_post_meta($post_ID, "sl-meta-box-sidebar", $_POST["sl-meta-box-sidebar"]);
}
return $post_ID;
} ?>