How to add custom fields for WooCommerce order page (admin)? - wordpress

I would like to add few input fields for the orders in WooCommerce/Wordpress. The fields will be only visible on the admin page. How to do that? Is it same like the pages/posts?
For the post types above I used add_post_meta. Is it the best way for that, or is there any hook for order fields?

Yes, just add_meta_box() to the post type shop_order and proceed as normal.
add_action( 'add_meta_boxes', 'add_meta_boxes' );
function add_meta_boxes()
{
add_meta_box(
'woocommerce-order-my-custom',
__( 'Order Custom' ),
'order_my_custom',
'shop_order',
'side',
'default'
);
}
function order_my_custom()
{
echo '<h1>Sample meta box</h1>';
}

Because you're asking specifically about WooCommerce, I'd like to expand on brasofilo's accepted answer by showing how you'd get the relevant WooCommerce order object (WC_Order) for the page the meta box is on.
Here's how you'd display the billing email from the order:
add_action('add_meta_boxes', function() {
add_meta_box('woocommerce-order-meta-24179529',
__( 'My Meta Box Title' ),
function() {
global $post;
// wc_get_order() returns one of bool|WC_Order|WC_Order_Refund
$order = wc_get_order($post->ID);
if($order instanceof WC_Order) {
echo "Billing email: ";
echo $order->get_billing_email();
}
},
'shop_order',
'side',
'default'
);
});

Related

How to update Order meta data, from a WooCommerce Action

I'm trying to add some custom meta_data to a WooCommerce Order, by running a Order action.
Here is my code:
function custom_add_order_actions( $actions ){
global $theorder;
$actions['my_custom_action'] = 'My custom action';
return $actions;
}
add_action( 'woocommerce_order_actions', 'custom_add_order_actions' );
function custom_add_single_action( $order ){
// Non of these change anything on the order
$order->set_billing_first_name( 'A new test name' );
$order->update_post_meta( 'a_test_field', 'Test field value' );
update_post_meta( $order->get_id(), 'a_test_field', 'Some other value' );
// $order->save(); // I even tried adding this as well, but it doesn't change anything.
}
add_action( 'woocommerce_order_action_my_custom_action', 'custom_add_single_action' );
How do I change the order (or specifically, post_meta fields for an order) from inside an action?
A example
Imagine that I add a post_meta field, with the field name (key): a_test_field.
It's currently an ACF-field, but it's the same for regular WordPress custom fields.
If I change the value of the field and press 'Update', then the value changes:
So far so good. Now the value of the field is 'Foobar'.
What's wierd is that even if I do this:
add_action( 'woocommerce_order_action_my_custom_action', 'custom_add_single_action' );
function custom_add_single_action( $order ){
update_post_meta( $order->get_id(), 'a_test_field', 'A new value' );
die(); // This die is vital, to make the change in the database.
}
Then I can see the value change in the database to 'A new value'.
But if I just do this:
add_action( 'woocommerce_order_action_my_custom_action', 'custom_add_single_action' );
function custom_add_single_action( $order ){
$order->update_post_meta( 'a_test_field', 'A new value' );
// No die(); here...
}
Then the value remains 'Foobar' in the database.
Sorry but the following lightly revisited code works (Selecting the action and click on the button arrow):
add_action( 'woocommerce_order_actions', 'add_custom_order_action' );
function add_custom_order_action( $actions ){
$actions['my_custom_action'] = __('My custom action', 'WooCommerce');
return $actions;
}
add_action( 'woocommerce_order_action_my_custom_action', 'triggered_custom_order_action' );
function triggered_custom_order_action( $order ){
$order->update_meta_data( '_test_1_custom_field', 'AAFFBB9977' );
$order->save();
update_post_meta( $order->get_id(), '_test_2_custom_field', 'Some other value' );
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
Note: Order actions are mostly used for some other things than what you are trying to do.
Now when using a meta box with an input field (as you are showing), on submit, you should save that field value using the action hook save_post_shop_order like in those related threads:
Metabox with multi checkbox in WooCommerce admin single orders
Dynamic custom order numbers based on payment method
Metabox with multiple custom fields for WooCommerce admin order pages

Wordpress change metabox title

Actually, I'm working on woocommerce customization...
I've read this question about the title change in metabox:
Customizing WooCommerce Short Description Metabox title
It help me a lot. But, in the product, how can I find the "metabox tag" callback name?
function epptm_rename_meta_boxes(){
remove_meta_box( 'tagsdiv-product_tag', 'product', 'side' );
add_meta_box( 'tagsdiv-product_tag', __( 'This metabox is awesome', 'your-plugin' ), 'CALLBACK?', 'product', 'side' );
}
add_action( 'add_meta_boxes', 'epptm_rename_meta_boxes', 40 );
here is another solution found:
/**
* hook to the 'add_meta_boxes' action to modify title
*/
function change_meta_box_titles() {
global $wp_meta_boxes; // array of defined meta boxes
// cycle through the array, change the titles you want
$wp_meta_boxes['product']['side']['core']['tagsdiv-product_tag']['title']= 'Here is my new title';
}
add_action('add_meta_boxes', 'change_meta_box_titles');

How can I display a desired date into a Wordpress page?

I'm trying to find a way to choose a date and display it into a Wordpress page.
Simply put, that's the way this may operate:
One or several pages are input a shortcode or a PHP code via PHP insert
An operator/webmaster chooses a date from let's say a calendar or drop down
This date (formatted) shows into the pages that have the shortcode/PHP code
I do not want automatic or current date which I can do with this plugin.
Can anybody help achieve this with a plugin or a PHP snippet?
Display a custom date field in Settings->Reading:
function wpse_52414489_custom_date() {
// Add the section to reading settings so we can add our
// fields to it
add_settings_section(
'eg_custom_settings',
'My custom settings',
'',
'reading'
);
// Add the field with the names and function to use for our new
// settings, put it in our new section
add_settings_field(
'eg_custom_date',
'My custom date',
'eg_custom_date_callback',
'reading',
'eg_custom_settings'
);
// Register our setting so that $_POST handling is done for us and
// our callback function just has to echo the <input>
register_setting( 'reading', 'eg_custom_date' );
}
function eg_custom_date_callback() {
echo '<input name="eg_custom_date" id="eg_custom_date" type="date" value="' . get_option( 'eg_custom_date' ) . '" class="code" /> Explanation text';
}
add_action( 'admin_init', 'wpse_52414489_custom_date' );
Add your shortcode (EDIT: custom date format):
add_filter( 'init', function() {
add_shortcode( 'my-custom-date', function() {
return date( 'd/m/Y', strtotime( get_option( 'eg_custom_date' ) ) );
});
});
Usage:
[my-custom-date]
Output:
2018-09-18

How do I change the add to cart text on the cart page only?

I'm trying to change the "add to cart" button text to 'Complete Sale' when on the shopping cart page, be "subscribe now" on product id 4968, and be 'Book' everywhere else.
Here is my code in the functions.php file:
function woo_custom_cart_button_text() {
if (is_single('Product1')) {
return __( 'Subscribe Now', 'woocommerce' );
} else {
return __( 'Book', 'woocommerce' );
}
}
add_filter( 'woocommerce_product_single_add_to_cart_text', 'woo_custom_cart_button_text' );
Try to change is_single to is_page(). And put slug or id of the page inside the is_page().

Display custom meta box to the admin sidebar not working

I created a custom meta box to display some content inside the post display in the admin area and want it to show in the sidebar instead of below the wysiwyg editor. I added "side" to the context but nothing happens! I've been playing with this for many hours and haven't had any luck.
This is my code:
function add_custom_meta_box() {
add_meta_box (
'custom_meta_box',
'Custom Meta Box Title',
'show_custom_meta_box',
'post',
'side',
'high'
);
}
add_action('add_meta_boxes', 'add_custom_meta_box');
function show_custom_meta_box() {
// here i have all the code
}
Adapted from this Q&A, the following will force the custom meta box into the second position in the side column.
Check the comments and note the caveat for admin_init.
It only works if the user hasn't rearranged the positions himself. When registering a new user, the position is set for him, as the hooks admin_init and user_register are attached to the same callback function.
// This fires at **every** page load, a better hook must be found
add_action( 'admin_init', 'set_user_metaboxes_so_14183498' );
// This fires when a new user is created
add_action( 'user_register', 'set_user_metaboxes_so_14183498' );
function set_user_metaboxes_so_14183498( $user_id = null )
{
// This is the metakey we will need to update
$meta_key = 'meta-box-order_post';
// So this can be used without hooking into user_register
if( !$user_id )
$user_id = get_current_user_id();
// Set the default order if it has not been set yet by the user.
// These are WP handles, PLUS our custom meta box handle
if ( ! get_user_meta( $user_id, $meta_key, true ) )
{
$meta_value = array(
'side' => 'submitdiv,custom_meta_box,formatdiv,postimagediv',
'normal' => 'postcustom,commentsdiv,slugdiv,revisionsdiv',
'advanced' => '',
);
update_user_meta( $user_id, $meta_key, $meta_value );
}
}

Resources