Cannot save custom metabox data - wordpress

I have made a custom metabox in a custom post type. My custom metabox includes two radio buttons. But no matter what I do, I'm not able to save data in my database. Wordpress saves it's data in the "wp_postmeta" but not the custom data that I wanted to save. Here's my code:
function wp_add_custom_meta_boxes(){
add_meta_box("custom_meta", "Settings", "wp_meta_box_callback", "images", "normal");
}
add_action("add_meta_boxes", "wp_add_custom_meta_boxes");
function wp_meta_box_callback($post){
wp_nonce_field(basename(__FILE__), "wp_custom_image_nonce");
?>
<div class="meta-row">
<div class="meta-th">
<p>Should this image show on the main page ?</p>
</div>
<div class="meta-td">
<label for="yes">Yes</label>
<input id="yes" type="radio" name="on_mainpage" value="true">
<label for="no">No</label>
<input id="no" type="radio" name="on_mainpage" value="false">
</div>
</div>
<?php
}
function wp_save_meta_info($post_id){
if(!wp_verify_nonce("wp_custom_image_nonce", basename(__FILE__))){
return;
}
if(defined("DOING_AUTOSAVE") && DOING_AUTOSAVE){
return $post_id;
}
if(isset($_POST['on_mainpage'])){
update_post_meta($post_id, "show_on_mainpage", $_POST['on_mainpage']);
}
}
add_action("save_post", "wp_save_meta_info");
I have 1 more question. Does update_post_meta() requires some existing data in the database to be updated or does it automatically saves the data in the database if it doesn't exists ?
Thanks in advance :)

You have a typo in your update post meta function
function wp_save_meta_info($post_id){
if(!wp_verify_nonce($_POST["wp_custom_image_nonce"], basename(__FILE__))){
return;
}
if(defined("DOING_AUTOSAVE") && DOING_AUTOSAVE){
return $post_id;
}
if(isset($_POST['on_mainpage'])){
update_post_meta($post_id, "show_on_mainpage", $_POST['on_mainpage']);
}
}
Also just to point out there is a custom save_post hook for custom post types
the hook is called -- save_post_yourpostypename so
add_action("save_post_posttype", "wp_save_meta_info");
Otherwise you will need to check its the correct post type within the function, or have unique nonce names throughout your custom post types. Also i'd recommend using a different action for your nonces, something descriptive and unique would be better if you are debugging some time in the future
update_post_meta() will create a meta entry for your field name if it doesn't exist so developers prefer it to add_post_meta() when there should only be 1 meta entry for that field name, i.e. the data should be updated on post save rather than a new meta entry created. You can see your postmeta entries on the postmeta db table.

Related

Add dropdown list to woocommerce cart and retrieve value on checkout?

I'd like to modify cart.php to contain a dropdown list of "checkout agents" and then retrieve that data when checking out to redirect to the correct agent (different URLs).
I already have cart.php in the child theme. I have created a cart-custom-checkout.php page to handle retrieving the cart contents and redirecting (wp_redirect) to an agents URL (I tested a single agent by building the URL from the cart contents and it works great).
I enabled the custom checkout via modifying the child theme functions.php as follows:
// enable custom checkout for woocommerce
add_shortcode( 'cart_custom_checkout', 'cart_custom_checkout_function' );
function cart_custom_checkout_function() {
wc_get_template('cart/cart-custom-checkout.php');
}
Then used that shortcode on the checkout page.
Now that everything works like I want in concept, the final step is to create the dropdown list in the cart.php so one of several agents can be chosen. From there I then need to somehow retrieve that in the cart-custom-checkout.php page. If it were part of the WC() cart data or something like that would be great.
Can someone help explain how I can do what I'm wanting to do?
TIA!!
Update: I've gone a little further and added my dropddown list as follows:
add_action('woocommerce_after_cart_totals', 'woocommerce_cart_add_resellers');
function woocommerce_cart_add_resellers() {
wc_get_template('cart/cart-add-reseller.php');
}
The cart-add-reseller.php contents are:
<div style="margin-top:5px">
<select name="agent">
<option value="Agent1">Use Agent1</option>
<option value="Agent2">Use Agent2</option>
</select>
</div>
Now just need to get what agent value is in the cart-custom-checkout.php page. How do I do that?
Update2: I am not getting any $_POST data when clicking the proceeded to checkout button.
// enable custom checkout for woocommerce
add_shortcode( 'cart_custom_checkout', 'cart_custom_checkout_function' );
function cart_custom_checkout_function() {
var_dump($_POST);
wc_get_template('cart/cart-custom-checkout.php');
}
It's empty.
Update 3: I've check $post which just gives me the checkout page itself with the shortcode in it, $_POST is empty, $_SESSIONS is empty, $_GET is empty. I'm not sure where the $_POST data went, maybe some javascript or something like that which I know nothing about. If I could just know a filter or action or something to give me the $_POST data, it will have the value I need. So I give up for now.
Any help would be appreciated.
If I fully understand what you have, if you were to add the following in functions.php, it will add the required field to the cart page and allow it to be accessible via $_POST on the checkout page. This essential replaces the default Proceed to Checkout button, with a new one that includes the select field and a post action.
add_action( 'woocommerce_proceed_to_checkout', 'add_agent_before_proceed_to_checkout', 15 );
function add_agent_before_proceed_to_checkout() {
remove_action( 'woocommerce_proceed_to_checkout', 'woocommerce_button_proceed_to_checkout', 20 );
?>
<form id="checkout_form" method="POST" action="<?php echo esc_url ( wc_get_checkout_url() ); ?>">
<div style="margin-top:5px">
<select name="agent">
<option value selected="selected">-- Select an Agent --</option>
<option value="Agent1">Use Agent1</option>
<option value="Agent2">Use Agent2</option>
</select>
</div>
<button type="submit" class="checkout-button button alt wc-forward" style="width:100%;"><?php
esc_html_e( 'Proceed to checkout', 'woocommerce' ) ?></button>
</form>
<?php
}
The reason what you had added to cart didn't work, is the Proceed to Checkout button (woocommerce\templates\cart\proceed-to-checkout-button.php) by default doesn't do a post action, it is actually a link. Also the spot you were adding your input was not within a form so wouldn't have posted the value.

Wordpress Submit hidden input data as custom field (Payment Plugin)

So, I got a payment plugin where some information is entered in an popup.
The popup stores the input data in a hidden input on the payment page
In payments field I got this for the hidden input:
<input type="hidden" class="" name="auth" id="auth" placeholder="" value="">
Via JS I put the value from the popup to the input hidden data, which definetly works!
Then I add an action:
add_action( 'woocommerce_checkout_update_order_meta', 'ccp_payment_update_order_meta' );
function ccp_payment_update_order_meta( $order_id ) {
update_post_data( $order_id, 'auth', sanitize_text_field($POST['auth']) );
}
Somehow after the submission of the checkout form the data ($POST['auth']) is empty.
Why is this happening?
How can I store the value right?
Got it sorted out. It need to be in an paragraph like that
<p class="form-row form-row-wide"><input type="hidden" ...></p>

change meta while saving in Wordpress

i added metaboxes to my custom post. how can i change a meta while saving. for example change a URL or read the site name and save it to another hidden meta?
thanks.
you should use a hidden input inside the custom post type as follows:
<input type="text" name="variable" style="display:none;" readonly>
At the same time
Try below code:
On same page you can get form field and insert into db:
you can further use generated post id for save custom meta.
if(isset($_POST['variable'])){
$var = $_POST['variable'];
update_post_meta($post->ID, 'name', $var);
}

Theme my login validate profile page?

I am using the theme my login WordPress plugin, using the custom pages I have added my own registration fields and validated them with no issues.
However I have worryingly discovered that corrupt code can be added and update to the profile page once a user is registered, I am wondering if there is the same offering for the profile page in terms of validation as there is for the registration?
The best way would be to use "theme my login" template pages, it already have the registration and profile part. You can add and remove fields to your liking and also style it, here is a tutorial for that
http://www.jfarthing.com/development/theme-my-login/adding-extra-registration-fields/.
If you have your custom built profile page then i suggest you use wpnonce to check the validity of the POST requests. Secondly use wordpress's own functions for fetching and updating data. Functions like get_user_meta and update_user_meta, these come built in with all the validation and you dont have to worry about it.
EDIT : I have written this code to demonstrate how to use a nonce field and then how to check the validity of the nonce field (By default Nonces are valid for 24 hours). The code below adds a form and asks for users height. The first php part wont run until the post request has been made. Once the request has been made then it checks for the integrity of the request. If all conditions are met then it will add a new meta field in the database called 'user_height', and will be updated every time the user changes it. Once the height has been set, it will also auto populate this in the input box, so they can see what is their current height. I hope this code covers all your doubts of showing user meta, adding/updating user meta and also validation nonces.
<?php
// Checking if the post request has been submitted and then verifing nonce
if (!isset( $_POST['get_user_height'] ) || !wp_verify_nonce( $_POST['get_user_height'], 'user_body_built' )
) {
print 'Sorry, the request cannot be verified.';
exit;
} else {
if(isset($_POST['user_height']) && !empty($_POST['user_height'])){
update_user_meta( $user_id, 'user_height', $_POST['user_height']);
}
}
<form method="post">
// Fetching previous height of user
<?php $user_height = get_user_meta($user_id, 'user_height', TRUE);?>
// Getting user's height and then saving it to users meta, if height was already set it will also show the current height.
<input type="text" name="user_height" <?php if($user_height){echo 'value="'.$user_height.'"';} ?> placeholder="enter your height">
// Generating a nonce field which will be checked on post request
<?php wp_nonce_field( 'user_body_built', 'get_user_height' ); ?>
</form>
Second EDIT (showcasing how to use existing registration fields on profile page, replace input names with the ones on registeration page): Just add this code in your profile page or functions.php it will automatically show these fields in the profile page.
function tml_edit_user_profile( $profileuser ) {?>
<p>
<label for="phone_number">Phone Number</label>
<!-- replace name attribute with the ones used on registration page -->
<input id="phone_number" type="text" name="phone_number" value="<?php echo $profileuser->phone_number; ?>" />
</p>
<?php
}
add_action( 'edit_user_profile', 'tml_edit_user_profile' );

Wordpress : Adding meta box in Admin Menu page

I am working on a plugin, which creates a couple of Virtual pages, and I wish these links to be available in Menu admin page, to let users have the liberty to add them as they create menus.
I want to add a Meta box in Menu administration, very similar to Page/Category meta boxes, to let users select what page to add in their menu.
Apparently, the only possible research is in the core itself.
Here, /wp-includes/nav-menu.php, we can get how to insert the meta box:
add_action('admin_init', 'so_13875144_nav_menu_meta_box');
function so_13875144_nav_menu_meta_box() {
add_meta_box(
'my-custom-nav-box',
__('Custom Box'),
'so_13875144_display_menu_custom_box',
'nav-menus',
'side',
'default'
);
}
function so_13875144_display_menu_custom_box() {
/* Not sure about this global var */
//global $_nav_menu_placeholder;
//$_nav_menu_placeholder = ( 0 > $_nav_menu_placeholder ) ? intval($_nav_menu_placeholder) - 1 : -1;
?>
<p id="menu-item-custom-box">
<label class="howto" for="custom-menu-item-custom-box">
<span><?php _e('URL'); ?></span>
<input id="custom-menu-item-custom-box" name="menu-item[<?php echo $_nav_menu_placeholder; ?>][menu-item-custom-box]" type="text" class="code menu-item-textbox" value="my text" />
</label>
</p>
<?php
}
But, the hard part, which I haven't managed to make work, is to save the value.
This is the file /wp-admin/nav-menus.php that has to be studied.
Tried to hook into the action wp_update_nav_menu, but the custom meta box input field is not being passed into $_POST.
WordPress Answers may have some hint: https://wordpress.stackexchange.com/search?q=wp_update_nav_menu
http://codex.wordpress.org/Function_Reference/add_meta_box
Use the post_type 'nav-menus'
I know I'm late to the party but just for anyone else trying to do this...
b__ is right, that is the way to get it to show on the page except it is much easier to use checkboxes than any other field because there is an inbuilt javascript function that looks for checkboxes.
All you need to do is copy the html from an existing checkbox -
<li><label class="menu-item-title"><input type="checkbox" class="menu-item-checkbox" name="menu-item[-1][menu-item-object-id]" value="2"> Sample Page</label><input type="hidden" class="menu-item-db-id" name="menu-item[-1][menu-item-db-id]" value="0"><input type="hidden" class="menu-item-object" name="menu-item[-1][menu-item-object]" value="page"><input type="hidden" class="menu-item-parent-id" name="menu-item[-1][menu-item-parent-id]" value="0"><input type="hidden" class="menu-item-type" name="menu-item[-1][menu-item-type]" value="post_type"><input type="hidden" class="menu-item-title" name="menu-item[-1][menu-item-title]" value="Sample Page"><input type="hidden" class="menu-item-url" name="menu-item[-1][menu-item-url]" value=""><input type="hidden" class="menu-item-target" name="menu-item[-1][menu-item-target]" value=""><input type="hidden" class="menu-item-attr_title" name="menu-item[-1][menu-item-attr_title]" value=""><input type="hidden" class="menu-item-classes" name="menu-item[-1][menu-item-classes]" value=""><input type="hidden" class="menu-item-xfn" name="menu-item[-1][menu-item-xfn]" value=""></li>
but give them each a unique ID and put your details in for the URL, title etc.
Then, add a submit button at the end to add to the menu -
<input type="submit" class="button-secondary submit-add-to-menu right" value="<?php esc_attr_e('Add to Menu'); ?>" name="YOUR NAME" id="YOUR ID" onclick="(function(){$('#THE DIV YOU HAVE PUT YOUR LIST IN').addSelectedToMenu( api.addMenuItemToBottom );})"/>
And that should add the item to the list.
This is a pretty old question but I was trying to do this today so in case it points anyone in the right direction...
I won't cover adding the meta box, as it's covered above. I'll also only cover a custom link as I haven't looked into adding a post, page, term link etc.
Just to cover the logic of how I got there...Looking at wp-admin/js/nav-menu.js, for a custom link you'll want to use window.wpNavMenu.addItemToMenu(). This ajax submits to the function wp_ajax_add_menu_item() in wp-admin/includes/ajax-actions.php. This then submits to wp_save_nav_menu_items() in wp-admin/includes/nav-menu.php. The upshot from looking at these files is that all menu items are of a post_type, taxonomy, post_type_archive or custom type.
Hook the javascript to the HTML as you wish, but if you want to submit a custom link, you need to call addItemToMenu() as follows:
var url = 'http://example.com';
var title = 'Link text';
window.wpNavMenu.addItemToMenu({
'-1': {
'menu-item-type': 'custom',
'menu-item-url': url,
'menu-item-title': title,
}
}, window.wpNavMenu.addMenuItemToBottom);
Menu item type has to be "custom" otherwise it requires info for a post, page etc. with which to associate the menu item.

Resources