Why doesn't my metabox save its values? - wordpress

I know there are many questions about variants of this, but I have not been able to find an answer.
I have a metabox on the post type page, containing nothing but a checkbox. It seems like it won't save no matter what I do. Here is all the code for the metabox.
/*--------------------------------------------------------------------------*
* Register metabox
/*--------------------------------------------------------------------------*/
function kasparabi_page_left_menu() {
add_meta_box( 'kasparabi-left-menu-meta', __( 'Left Menu', 'kasparabi' ), 'kasparabi_render_left_menu_meta_box', 'page', 'side' );
}
add_action( 'add_meta_boxes', 'kasparabi_page_left_menu' );
/*--------------------------------------------------------------------------*
* Callbacks
/*--------------------------------------------------------------------------*/
function kasparabi_render_left_menu_meta_box($post) {
wp_nonce_field( basename( __FILE__ ), 'kasparabi-left-menu-meta_nonce' );
?>
<p>
<div>
<label for="left-menu-checkbox">
<input type="checkbox" name="left-menu-checkbox" <?php (get_post_meta( $post->ID, 'left_menu_checkbox', true) == 'on') ? ' checked="checked"' : ''; ?> />
<?php _e( 'Display left menu', 'kasparabi' )?>
</label>
</div>
</p>
<?php
}
/*--------------------------------------------------------------------------*
* Save functions
/*--------------------------------------------------------------------------*/
function kasparibi_left_menu_meta_save( $post_id, $post ) {
// Checks save status
$is_autosave = wp_is_post_autosave( $post_id );
$is_revision = wp_is_post_revision( $post_id );
$is_valid_nonce = ( isset( $_POST[ 'kasparabi-left-menu-meta_nonce' ] ) && wp_verify_nonce( $_POST[ 'kasparabi-left-menu-meta_nonce' ], basename( __FILE__ ) ) ) ? 'true' : 'false';
// Exits script depending on save status
if ( $is_autosave || $is_revision || !$is_valid_nonce ) {
return $post_id;
}
/* Get the post type object. */
$post_type = get_post_type_object( $post->post_type );
/* Check if the current user has permission to edit the post. */
if ( !current_user_can( $post_type->cap->edit_post, $post_id ) )
return $post_id;
/* Get the posted data and sanitize it for use as an HTML class. */
$new_meta_value = ( isset( $_POST['left-menu-checkbox'] ) ? sanitize_html_class( $_POST['left-menu-checkbox'] ) : '' );
$meta_key = 'left_menu_checkbox';
$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 );
}
add_action( 'save_post', 'kasparibi_left_menu_meta_save' );

Turns out I didn't echo out the checked value, and that I needed to specify how many parameters the save function should receive.
Check this post here: https://wordpress.stackexchange.com/questions/126539/why-does-not-my-metabox-save

Related

Save custom data to customer and pre fill value on next orders

A WooCommerce plugin provides custom order data (a Fedex number) from checkout so clients don't have to pay shipping costs. I need this value (fedex number) saved to the customer so next time a order is created in backend the Fedex number is pre-filled.
I created a meta box in WooCommerce Order admin which shows the value and also created a field beneath Billing details which shows the value.
I can't figure out how to get the value pre-filled when creating a new order in backend.
Here's what I got so far:
//* Display field value on the order edit page *//
add_action( 'woocommerce_admin_order_data_after_billing_address',
'my_fedex_checkout_field_display_admin_order_meta', 10, 1 );
function my_fedex_checkout_field_display_admin_order_meta($order){
echo '<p><strong>'.__('FedEx number Client').':</strong> ' .
get_post_meta( $order->id, 'FedEx_number', true ) . '</p>';
}
//* Adding Meta container admin shop_order pages *//
add_action( 'add_meta_boxes', 'fedex_add_meta_boxes' );
if ( ! function_exists( 'fedex_add_meta_boxes' ) )
{
function fedex_add_meta_boxes()
{
global $woocommerce, $order, $post;
add_meta_box( 'fedex_other_fields', __('FedEx number
Client','woocommerce'), 'fedex_add_other_fields_for_orders',
'shop_order', 'side', 'core' );
}
}
//* adding Meta field in the meta container admin shop_order pages
//*
if ( ! function_exists( 'fedex_save_wc_order_other_fields' ) )
{
function fedex_add_other_fields_for_orders()
{
global $woocommerce, $order, $post;
$meta_field_data = get_post_meta( $post->ID, 'FedEx_number',
true ); //? get_post_meta( $post->ID, 'FedEx_number', true ) : '';
echo '<input type="hidden" name="fedex_other_meta_field_nonce"
value="' . wp_create_nonce() . '">
<p style="border-bottom:solid 1px #eee;padding-bottom:13px;">
<input type="text" style="width:250px;";"
name="FedEx_number" placeholder="' . $meta_field_data . '" value="'
. $meta_field_data . '"></p>';
}
}
//* Save Fedex number to Customer //*
add_action('save_post_shop_order', 'customer_fedex_save', 50, 3 );
function customer_fedex_save( $post_id, $post, $update ) {
// Checking that is not an autosave
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return $post_id;
// Check the user’s permissions (for 'shop_manager' and
'administrator' user roles)
if ( ! current_user_can( 'edit_shop_order', $post_id ) )
return $post_id;
if( isset($_POST['FedEx_number']) ) {
$order = wc_get_order( $post_id );
// Update user meta data
update_user_meta( $order->get_customer_id(), 'FedEx_number',
sanitize_text_field( $_POST['FedEx_number'] ) );
}
}
I have made some changes to your code adding also some additional functions. As I don't use your Fedex plugin, I have tested this partially and I am not really sure that it will work as you would like.
The code:
// On Order submit: Save 'FedEx_number' as user meta data if it doesn't exits
add_action( 'woocommerce_checkout_update_order_meta', 'sync_fedex_checkout_field_to_order', 100, 1 );
function sync_fedex_checkout_field_to_order( $order_id, $data ){
$meta_key = 'FedEx_number';
$user_id = (int) get_post_meta( $order_id, '_customer_user', true );
if( $user_id > 0 ) {
$meta_value = get_user_meta( $user_id, $meta_key, true );
}
// Sync 'FedEx_number' as user meta data if it doesn't exist yet
if( $user_id > 0 && ! $meta_value ) {
// Get the 'FedEx_number' value and update user data
if( $meta_value = get_post_meta( $order_id, $meta_key, true ) )
update_user_meta( $user_id, $meta_key, esc_attr( $meta_value ) );
}
}
// Display the fedex field value under admin order billing address section
add_action( 'woocommerce_admin_order_data_after_billing_address', 'my_fedex_checkout_field_display_admin_order_meta', 10, 1 );
function my_fedex_checkout_field_display_admin_order_meta( $order ){
$meta_key = 'FedEx_number';
$user_id = $order->get_customer_id();
if( $user_id > 0 ) {
$meta_value = get_user_meta( $user_id, $meta_key, true );
}
if( ! isset($meta_value) ) {
$meta_value = $order->get_meta( $meta_key );
}
if( isset($meta_value) ) {
echo '<p><strong>'.__("FedEx number Client", "woocommerce").':</strong> ' . $meta_value . '</p>';
}
}
// Add fedex order metabox
add_action( 'add_meta_boxes', 'add_fedex_meta_box' );
function add_fedex_meta_box() {
global $post;
add_meta_box( 'fedex_meta_box',
__("FedEx number Client", "woocommerce'"),
'fedex_meta_box_content',
'shop_order', 'side', 'core' );
}
// The fedex metabox content
function fedex_meta_box_content() {
global $post;
$meta_key = 'FedEx_number';
$user_id = get_post_meta( $post->ID, '_customer_user', true );
if( $user_id > 0 ) {
$meta_value = get_user_meta( $user_id, $meta_key, true );
} else {
$meta_value = get_post_meta( $post->ID, $meta_key, true );
}
echo '<p style="border-bottom:solid 1px #eee;padding-bottom:13px;">
<input type="text" style="width:250px;" name="'.$meta_key.'" value="'.$meta_value.'">
<input type="hidden" name="fedex_field_nonce" value="' . wp_create_nonce() . '"></p>';
}
add_action('save_post_shop_order', 'customer_fedex_save', 100, 1 );
function customer_fedex_save( $post_id ) {
// Security check
if ( ! isset( $_POST[ 'fedex_field_nonce' ] ) ) {
return $post_id;
}
//Verify that the nonce is valid.
if ( ! wp_verify_nonce( $_POST[ 'fedex_field_nonce' ] ) ) {
return $post_id;
}
// Checking that is not an autosave
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return $post_id;
}
// Check the user’s permissions (for 'shop_manager' and 'administrator' user roles)
if ( ! current_user_can( 'edit_shop_order', $post_id ) ) {
return $post_id;
}
$meta_key = 'FedEx_number';
if( isset($_POST[$meta_key]) ) {
$user_id = (int) get_post_meta( $post_id, '_customer_user', true );
// Update post meta
update_post_meta( $post_id, $meta_key, sanitize_text_field( $_POST[$meta_key] ) );
// Update user meta
if( $user_id > 0)
update_user_meta( $user_id, $meta_key, sanitize_text_field( $_POST[$meta_key] ) );
}
}
Code goes in function.php file of your active child theme (or active theme). Tested partially.

How to add custom filed and save it in wordpress?

Following code I tried out But it is not save value of custom Fileds.
add_action( 'add_meta_boxes', 'cd_meta_box_add' );
function cd_meta_box_add()
{
add_meta_box( 'my-meta-box-id', 'My First Meta Box', 'cd_meta_box_cb', 'product', 'side', 'high' );
}
In above I have add code it is display when posttype is product
function cd_meta_box_cb( $product)
{
$values = get_post_custom( $product->ID );
$text = isset( $values['my_meta_box_text'] ) ? esc_attr($values['my_meta_box_text'][0] ) : ”;
?>
<p>
<label for="my_meta_box_text">Text Label</label>
<input type="text" name="my_meta_box_text" id="my_meta_box_text" value="<?php echo $text; ?>" />
</p>
<?php
}
In above code it will added the metabox with textbox and if value in metabox then it is display
add_action( 'save_post', 'cd_meta_box_save' );
function cd_meta_box_save( $product_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_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_post' ) ) return;
}
I want to save data in a wp_postmeta table. Above code i have tried out. I am beginner in wordpress.Can any give me suggestion ?
Use This code for creating custom fields for post.
class Rational_Meta_Box {
private $screens = array(
'post',
);
private $fields = array(
array(
'id' => 'custom-field-1',
'label' => 'custom field 1',
'type' => 'text',
),
array(
'id' => 'custom-field-2',
'label' => 'custom field 2',
'type' => 'text',
),
);
/**
* Class construct method. Adds actions to their respective WordPress hooks.
*/
public function __construct() {
add_action( 'add_meta_boxes', array( $this, 'add_meta_boxes' ) );
add_action( 'save_post', array( $this, 'save_post' ) );
}
/**
* Hooks into WordPress' add_meta_boxes function.
* Goes through screens (post types) and adds the meta box.
*/
public function add_meta_boxes() {
foreach ( $this->screens as $screen ) {
add_meta_box(
'my-custom-fields',
__( 'my custom fields', 'wordpress' ),
array( $this, 'add_meta_box_callback' ),
$screen,
'advanced',
'high'
);
}
}
/**
* Generates the HTML for the meta box
*
* #param object $post WordPress post object
*/
public function add_meta_box_callback( $post ) {
wp_nonce_field( 'my_custom_fields_data', 'my_custom_fields_nonce' );
echo 'its for custom fields for post typle';
$this->generate_fields( $post );
}
/**
* Generates the field's HTML for the meta box.
*/
public function generate_fields( $post ) {
$output = '';
foreach ( $this->fields as $field ) {
$label = '<label for="' . $field['id'] . '">' . $field['label'] . '</label>';
$db_value = get_post_meta( $post->ID, 'my_custom_fields_' . $field['id'], true );
switch ( $field['type'] ) {
default:
$input = sprintf(
'<input %s id="%s" name="%s" type="%s" value="%s">',
$field['type'] !== 'color' ? 'class="regular-text"' : '',
$field['id'],
$field['id'],
$field['type'],
$db_value
);
}
$output .= $this->row_format( $label, $input );
}
echo '<table class="form-table"><tbody>' . $output . '</tbody></table>';
}
/**
* Generates the HTML for table rows.
*/
public function row_format( $label, $input ) {
return sprintf(
'<tr><th scope="row">%s</th><td>%s</td></tr>',
$label,
$input
);
}
/**
* Hooks into WordPress' save_post function
*/
public function save_post( $post_id ) {
if ( ! isset( $_POST['my_custom_fields_nonce'] ) )
return $post_id;
$nonce = $_POST['my_custom_fields_nonce'];
if ( !wp_verify_nonce( $nonce, 'my_custom_fields_data' ) )
return $post_id;
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return $post_id;
foreach ( $this->fields as $field ) {
if ( isset( $_POST[ $field['id'] ] ) ) {
switch ( $field['type'] ) {
case 'email':
$_POST[ $field['id'] ] = sanitize_email( $_POST[ $field['id'] ] );
break;
case 'text':
$_POST[ $field['id'] ] = sanitize_text_field( $_POST[ $field['id'] ] );
break;
}
update_post_meta( $post_id, 'my_custom_fields_' . $field['id'], $_POST[ $field['id'] ] );
} else if ( $field['type'] === 'checkbox' ) {
update_post_meta( $post_id, 'my_custom_fields_' . $field['id'], '0' );
}
}
}
}
new Rational_Meta_Box;
So it will create custom fields in your post type and also saved it too.
follow this for the references https://developer.wordpress.org/plugins/metadata/creating-custom-meta-boxes/
Just replace your add_action( 'save_post', 'cd_meta_box_save' ); function and put below code.
add_action( 'save_post', 'cd_meta_box_save' );
function cd_meta_box_save( $product_id )
{
if( isset( $_POST[ 'my_meta_box_text' ] ) ) {
update_post_meta( $product_id,'my_meta_box_text', $_POST['my_meta_box_text'] );
}
}
Full code like ( it's working fine and also save custom field in postmeta table)
add_action( 'add_meta_boxes', 'cd_meta_box_add' );
function cd_meta_box_add()
{
add_meta_box( 'my-meta-box-id', 'My First Meta Box', 'cd_meta_box_cb', 'post', 'side', 'high' );
}
function cd_meta_box_cb( $product)
{
$values = get_post_custom( $product->ID );
$text = isset( $values['my_meta_box_text'] ) ? esc_attr($values['my_meta_box_text'][0] ) : '';
?>
<p>
<label for="my_meta_box_text">Text Label</label>
<input type="text" name="my_meta_box_text" id="my_meta_box_text" value="<?php echo $text; ?>" />
</p>
<?php
}
add_action( 'save_post', 'cd_meta_box_save' );
function cd_meta_box_save( $product_id )
{
if( isset( $_POST[ 'my_meta_box_text' ] ) ) {
update_post_meta( $product_id,'my_meta_box_text', $_POST['my_meta_box_text'] );
}
}
Take a look at Pods.
It is a very powerful plugin for customization.
http://pods.io/

metabox is inserting only one value of checkbox

only one checkbox value is inserted on database,i want multiple checkbox value insert on database.
What i want that, Multiple checkbox should insert on database and after insertion on database, inserted checkbox should be checked.Please help
function prfx_custom_meta() {
add_meta_box( 'prfx_meta', __( 'Meta Box Title', 'prfx-textdomain' ), 'prfx_meta_callback', 'post' );
}
add_action( 'add_meta_boxes', 'prfx_custom_meta' );
function prfx_meta_callback( $post ) {
wp_nonce_field( basename( __FILE__ ), 'prfx_nonce' );
$prfx_stored_meta = get_post_meta( $post->ID ); ?>
<form method="post">
<?php
$users = get_users();
foreach ($users as $user){ ?>
<label for="meta-checkbox">
<input type="checkbox" name="meta-checkbox[]" id="meta-checkbox" value="<?php echo $user->user_login; ?>" <?php if ( isset ( $prfx_stored_meta['meta-checkbox'] ) ) checked( $prfx_stored_meta['meta-checkbox'][0], 'yes' ); ?> />
<?php _e( 'Checkbox label', 'prfx-textdomain' )?>
</label>
<?php
} ?>
</form>
<?php
}
function prfx_meta_save( $post_id ) {
// Checks save status
$is_autosave = wp_is_post_autosave( $post_id );
$is_revision = wp_is_post_revision( $post_id );
$is_valid_nonce = ( isset( $_POST[ 'prfx_nonce' ] ) && wp_verify_nonce( $_POST[ 'prfx_nonce' ], basename( __FILE__ ) ) ) ? 'true' : 'false';
// Exits script depending on save status
if ( $is_autosave || $is_revision || !$is_valid_nonce ) {
return;
}
$checkbox = $_POST['meta-checkbox'];
// Checks for input and saves
if( isset( $_POST[ 'meta-checkbox' ] ) ) {
for($i=0;$i<sizeof($checkbox);$i++){
update_post_meta( $post_id, 'meta-checkbox', $checkbox[$i] );
}
} else {
update_post_meta( $post_id, 'meta-checkbox', '' );
}
}
add_action( 'save_post', 'prfx_meta_save' );

Why do my custom meta data fields clear after saving?

I've added a custom meta field to my Wordpress post type. Everytime I save, the fields don't hold the information (however the information is saved to the database).
My code:
function add_post_meta() {
add_meta_box(
'my_meta_box',
__( 'Metabox', 'framework' ),
'meta_box_content',
'post_type',
'advanced',
'high'
);
}
add_action( 'add_meta_boxes', 'add_post_meta' );
function virtual_merchant_box_content( $post ) {
wp_nonce_field( plugin_basename( __FILE__ ), 'meta_box_content_nonce' );
echo '<table><tr>';
echo '<td><label for="input_value">Enter Input Value:</label></td>';
echo '<td><input type="text" id="input_value" name="input_value" /></td>';
echo '</tr></table>';
}
function meta_box_save( $post_id ) {
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE )
return;
if ( !wp_verify_nonce( $_POST['meta_box_content_nonce'], plugin_basename( __FILE__ ) ) )
return;
if ( 'page' == $_POST['post_type'] ) {
if ( !current_user_can( 'edit_page', $post_id ) )
return;
} else {
if ( !current_user_can( 'edit_post', $post_id ) )
return;
}
$input_value = $_POST['input_value'];
update_post_meta( $post_id, 'input_value', $input_value );
}
add_action( 'save_post', 'metat_box_save' );
Get the input value using get_post_meta(), and then add it to the value="" attribute of the text input field.
function virtual_merchant_box_content( $post ) {
wp_nonce_field( plugin_basename( __FILE__ ), 'meta_box_content_nonce' );
$input_value = get_post_meta( $post->ID, 'input_value', true);
echo '<table><tr>';
echo '<td><label for="input_value">Enter Input Value:</label></td>';
echo '<td><input type="text" id="input_value" name="input_value" value="' . $input_value . '" /></td>';
echo '</tr></table>';
}

$post_id or $post->ID in wordpress meta box construction

Can someone explain why when creating meta boxes the callback needs the post id to be passed via $post->ID, however with the action hook 'save_post', the function can pass $post_id. A general explanation of when to use which one would help clear up some issues I've been having, thanks.
ex:
function show_custom_meta_box($post) {
$meta = get_post_meta($post->ID, 'custom_meta_class', true);
// Use nonce for verification
echo '<input type="hidden" name="custom_meta_box_nonce" value="'.wp_create_nonce(basename(__FILE__)).'" />';
// Begin the field table and loop
echo '<table class="form-table">';
echo '<tr>
<th><label for="custom-meta-class">Custom Meta Box</label></th>
<td>
<input class="widefat" type="text" name="custom-meta-class" id="custom-meta-class" value="'.$meta.'" size="50" />';
echo '</td></tr>';
echo '</table>'; // end table
}
and for the $post_id
function save_custom_meta($post) {
if( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) return;
/* Verify the nonce before proceeding. */
if ( !isset( $_POST['custom_meta_box_nonce'] ) || !wp_verify_nonce( $_POST['custom_meta_box_nonce'], basename( __FILE__ ) ) )
return $post_id;
$post_type = get_post_type_object( $post->post_type );
/* Check if the current user has permission to edit the post. */
if ( !current_user_can( $post_type->cap->edit_post, $post_id ) )
return $post_id;
/* Get the posted data and sanitize it for use as an HTML class. */
$new_meta_value = ( isset( $_POST['custom-meta-class'] ) ? sanitize_html_class( $_POST['custom-meta-class'] ) : '' );
/* Get the meta key. */
$meta_key = 'custom_meta_class';
/* Get the meta value of the custom field key. */
$meta_value = get_post_meta( $post_id, $meta_key, true );
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 );
}
I don't have an answer but I have the exact same problem. I'm surprised nobody has chimed in in the last 7 years.
Here's my code, it works (in functions.php)
add_action('save_post','extract_citations',100,1);
function extract_citations($post_id){
$the_post = get_post($post_id);
$content = $the_post->post_content;
preg_match_all('/<a\s+.*?href=[\"\']?([^\"\' >]*)[\"\']?[^>]*>(.*?)<\/a>/i',$content,$citation_array);
$citation_urls = $citation_array[1];
update_post_meta($post_id,'citations',serialize($citation_urls));
}
Here is code that does NOT work, despite being theoretically correct:
add_action('save_post','extract_citations',100,1);
function extract_citations($post){
$the_post = get_post($post->ID);
$content = $the_post->post_content;
preg_match_all('/<a\s+.*?href=[\"\']?([^\"\' >]*)[\"\']?[^>]*>(.*?)<\/a>/i',$content,$citation_array);
$citation_urls = $citation_array[1];
update_post_meta($post->ID,'citations',serialize($citation_urls));
}
I know this is a very old thread, but I wanted to add my thoughts.
Let’s pretend that the Post ID is 1724
In the first example you are inserting 1724 directly into the function so line 3 would become
$the_post = get_post(1724);
While in the second example of are asking for the ID of the post number so your line 3 would become
$the_post = get_post(1703->ID);
The thing to remember is that when you call the function within your site the number is added which becomes $post_id, it doesn’t actually matter what word you put in the brackets of the function.

Resources