Wordpress post layout meta box not saving - php

I added the meta box to my post page, so that I can choose what layout I have for each post. I created a meta box, and it's showing, but it won't save.
if ( ! function_exists( 'post_layout_meta_box' ) ){
function post_layout_meta_box( $post ){
$custom = get_post_custom($post->ID);
$page_layout = isset($custom["page_layout_left"][0]) ? $custom["page_layout_left"][0] : ( isset($custom["page_layout_right"][0]) ? $custom["page_layout_right"][0] : $custom["page_layout_none"][0] );
?>
<p>
<select name="page_layout" id="page_layout">
<option value="left_sidebar" <?php selected( $page_layout, 'left_sidebar' ); ?>>Left Sidebar</option>
<option value="right_sidebar" <?php selected( $page_layout, 'right_sidebar' ); ?>>Right Sidebar</option>
<option value="full_width" <?php selected( $page_layout, 'full_width' ); ?>>No Sidebar</option>
</select>
</p>
<?php
}
}
if ( ! function_exists( 'post_save_layout_meta_box' ) ){
function post_save_layout_meta_box($post_id){
if ( defined('DOING_AUTOSAVE') && DOING_AUTOSAVE ){
return $post_id;
} else{
if( isset( $_POST['page_layout'] ) ) {
update_post_meta( $post_id, 'page_layout', wp_kses($_POST['page_layout'], '') );
}
}
}
}
add_action( 'save_post', 'post_save_layout_meta_box' );
So what am I missing? When I choose Right Sidebar for example, it will return the value to the Left Sidebar after updating a page.
EDIT: Figured it out:
The problem was in this:
$page_layout = isset($custom["page_layout_left"][0]) ? $custom["page_layout_left"][0] : ( isset($custom["page_layout_right"][0]) ? $custom["page_layout_right"][0] : $custom["page_layout_none"][0] );
It should be
$page_layout = isset($custom["page_layout"][0]) ? $custom["page_layout"][0] : 'left_sidebar';

I guess this, in these lines of code there is problem. Wordpress confuse with page_layout_left, page_layout_right.
$page_layout = isset($custom["page_layout_left"][0]) ? $custom["page_layout_left"][0] : ( isset($custom["page_layout_right"][0]) ? $custom["page_layout_right"][0] : $custom["page_layout_none"][0] );
update_post_meta( $post_id, 'page_layout', wp_kses($_POST['page_layout'], '') );
I suggest if you want to use page_layout_left in update_post_meta() function then you should first find what option user selected i.e left or right or full width.
After that in update_post_meta function instead of using page_layout custom field name, use either page_layout_left or page_layout_right like this.
update_post_meta( $post_id, 'page_layout_left', wp_kses($_POST['page_layout'], '') );
Hope it may work.
Happy Coding.
Atul Jindal

Related

WordPress Save Dropdown Metabox

I have already created custom meta box at my custom post type.
so I create drop down list to choose a Teacher's name and the Class.
The value can be shown in the dropdown, but after publishing the post the value cannot save and dropdown set to default again.
can somebody know, if I am missing part or wrong code here?
Thanks if you wanna help, so here's my code:
function portfolio_student(){
add_meta_box( 'portfolio_student', 'Select The Teachers and Classes', 'meta_box_data', 'portfolio', 'normal', 'high' ); }
function meta_box_data(){
// $post is already set, and contains an object: the WordPress post
global $post;
$values = get_post_custom( $post->ID );
$teachers = isset( $values['the_teachers'] ) ? esc_attr( $values['the_teachers'] ) : '';
$classes = isset( $values['the_classes'] ) ? esc_attr( $values['the_classes'] ) : '';
// We'll use this nonce field later on when saving.
wp_nonce_field( 'my_meta_box_nonce', 'meta_box_data' );
?>
<p>
<label for="the_teachers">Teacher</label>
<select name="the_teachers" id="the_teachers">
<option value="0">-- Select Class --</option>
<?php
$args = array(
'numberposts' => -1,
'post_type' => 'teacher'
);
$teacher_posts = get_posts($args);
foreach( $teacher_posts as $post ) : setup_postdata($post); ?>
<option value="<?php echo $post->ID; ?>" <?php selected($teachers, $post->ID); ?>><?php the_title(); ?></option>
<?php endforeach; ?>
</select>
</p>
<p>
<label for="the_classes">Class</label>
<select name="the_classes" id="the_classes">
<option value="0">-- Select Class --</option>
<?php
$args = array(
'numberposts' => -1,
'post_type' => 'class'
);
$class_posts = get_posts($args);
foreach( $class_posts as $post ) : setup_postdata($post); ?>
<option value="<?php echo $post->ID; ?>" <?php selected($classes, $post->ID); ?>><?php the_title(); ?></option>
<?php endforeach; ?>
</select>
</p>
<?php}
add_action( 'save_post', 'cd_meta_box_save' );function cd_meta_box_save( $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( !isset( $_POST['meta_box_data'] ) || !wp_verify_nonce( $_POST['meta_box_data'], 'my_meta_box_nonce' ) )
return;
// if our current user can't edit this post, bail
if( !current_user_can( 'edit_post' ) )
return;
// Make sure your data is set before trying to save it
if( isset( $_POST['the_teachers'] ) )
//Update Meta Data
$teacher_meta = $_POST['the_teachers'];
//EndUpdate
update_post_meta( $post_id, 'the_teachers', $teacher_meta );
if( isset( $_POST['the_classes'] ) )
//Update Meta Data
$class_meta = $_POST['the_classes'];
//EndUpdate
update_post_meta( $post_id, 'the_classes', $class_meta ); }
Try changing these
update_post_meta( $post_id, 'the_teachers', $teacher_meta );
update_post_meta( $post_id, 'the_classes', $class_meta );
To
update_post_meta( $post->ID, 'the_teachers', $teacher_meta );
update_post_meta( $post->ID, 'the_classes', $class_meta );
Since you have declared $post as the global variable

Wordpress Custom Metabox Checkbox Save Issue

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.

WooCommerce admin order edit save post

In WooCommerce, when I submit, how to catch a custom select field added in the order edit admin pages?
I have added this custom select field in the file class-wc-meta-box-order-data.php. I get this:
But I dont know how to catch or to save $_POST['vendor']
I have tried to add $_POST['vendor'] in wp-admin/post.php ,but it doesn't work.
This is the code that I have added:
<select class="wc-customer-search" id="customer_user" name="customer_user" data-placeholder="<?php esc_attr_e( 'Guest', 'woocommerce' ); ?>" data-allow_clear="true">
<option value="<?php echo esc_attr( $user_id ); ?>" selected="selected"><?php echo htmlspecialchars( $user_string ); ?></option>
</select>
<!--/email_off-->
</p>
<p> <label for="order_status">供應商: </label>
<select name="vendor">
<?php
global $wpdb;
$user_count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->users" );
for($i=1;$i<=$user_count;$i++){
$user_info = get_userdata($i);
if (implode(', ', $user_info->roles)=='vendor')
echo "<option value=".$user_info->user_login.">$user_info->user_login</option>";
}
?>
</select></p>
How can I get the submitted value and how can I save it?
Overriding core files is something prohibited for developers. So this is not the correct way to do it.
The way to do it is using the available hooks in the source code, instead of overriding this core files, as you will loose everything when the plugin will be updated.
Replace all original core files
Add this code instead (I have make some minor necessary changes).
Here is the replacement code + a hook to save the data to the order meta data:
add_action( 'woocommerce_admin_order_data_after_order_details', 'custom_code_after_order_details', 10, 1 );
function custom_code_after_order_details ( $order ) {
// Get custom field value from '_vendor' meta key
$value = $order->get_meta('_vendor');
?>
<p> <label for="order_status">供應商: </label>
<select name="vendor">
<?php global $wpdb;
$user_count = $wpdb->get_var( "SELECT COUNT(*) FROM $wpdb->users" );
echo '<option value="">Select a vendor</option>';
for ( $i=1; $i<=$user_count; $i++ ) {
$user_info = get_userdata($i);
if ( in_array('vendor', $user_info->roles) ){
$user_login = $user_info->user_login;
$selected = $value == $user_login ? 'selected' : '';
echo '<option '.$selected.' value="'.$user_login.'">'.$user_login.'</option>';
}
}
?>
</select></p>
<input type="hidden" name="custom_select_field_nonce" value="<?php echo wp_create_nonce(); ?>">
<?php
}
add_action( 'save_post', 'save_custom_code_after_order_details', 10, 1 );
function save_custom_code_after_order_details( $post_id ) {
// We need to verify this with the proper authorization (security stuff).
// Check if our nonce is set.
if ( ! isset( $_POST[ 'custom_select_field_nonce' ] ) ) {
return $post_id;
}
$nonce = $_REQUEST[ 'custom_select_field_nonce' ];
//Verify that the nonce is valid.
if ( ! wp_verify_nonce( $nonce ) ) {
return $post_id;
}
// If this is an autosave, our form has not been submitted, so we don't want to do anything.
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return $post_id;
}
// Check the user's permissions.
if ( 'page' == $_POST[ 'post_type' ] ) {
if ( ! current_user_can( 'edit_page', $post_id ) ) {
return $post_id;
}
} else {
if ( ! current_user_can( 'edit_post', $post_id ) ) {
return $post_id;
}
}
// Update the meta field in the database.
update_post_meta( $post_id, '_vendor', $_POST[ 'vendor' ] );
}
Code goes in function.php file of your active child theme (or theme) or also in any plugin file.
This code is tested and works.

Custom Metabox Not Saving with looped input box

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.

How to save a checkbox meta box in WordPress?

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;
} ?>

Categories