I am developing a cycle renting site in which user select the date range (in days) from start date to end. And I am storing that data using wc_add_order_item_meta() function as a meta data of the order, right.
Then, I wanted to give user a functionality like he could change or extend the days by going through the orders page. This is also done, I have created a modal and added a ajax request on change of dates on modal.
Now, I sent data to functions.php using AJAX and I used wc_update_order_item_meta() to update the meta data.
Here's my function looks like :
add_action( 'wp_ajax_update_date_picker', 'update_date_picker' );
function update_date_picker() {
$p_da = $_POST['p_date'];
$r_da = $_POST['r_date'];
$t_dy = $_POST['t_days'];
$order_id = $_POST['order_id'];
$order = wc_get_order($order_id);
foreach ($order->get_items() as $item_id => $item_obj) {
$pd = wc_update_order_item_meta($item_id, 'pickup_hidden_datetime', $p_da);
$rd = wc_update_order_item_meta($item_id, 'return_hidden_datetime', $r_da);
$td = wc_update_order_item_meta($item_id, 'return_hidden_days', $t_dy);
if($pd&&$rd&&$td){
echo "Nice work, Bilal";
}
die();
}
}
This is updating too but not at all the places. I mean, it's giving me right response, when I refresh, it's also giving the updated data but when I go through the view item page it's showing there the old data only instead of updated one. Even when I check the orders in the admin, it's showing the old meta data there too.
Any idea would be appreciated, Thanks in Advance.
I think it's because of the cache that WooCommerce has... try something like this.
add_action( 'wp_ajax_update_date_picker', 'update_date_picker' );
function update_date_picker() {
$p_da = $_POST['p_date'];
$r_da = $_POST['r_date'];
$t_dy = $_POST['t_days'];
$order_id = $_POST['order_id'];
$order = wc_get_order($order_id);
foreach ($order->get_items() as $item_id => $item_obj) {
$pd = wc_update_order_item_meta($item_id, 'pickup_hidden_datetime', $p_da);
$rd = wc_update_order_item_meta($item_id, 'return_hidden_datetime', $r_da);
$td = wc_update_order_item_meta($item_id, 'return_hidden_days', $t_dy);
if($pd&&$rd&&$td){
echo "Nice work, Bilal";
}
}
clean_post_cache( $order->get_id() );
wc_delete_shop_order_transients( $order );
wp_cache_delete( 'order-items-' . $order->get_id(), 'orders' );
die();
}
Related
While im pretty hopeless at php, i feel like im getting close on this one, i just cant quite lock it in
So we have 2 plugins in the mix here WCFM & AST
In WCFM, a vendor adds a tracking number and carrier this is store in the order meta data with a meta keys of
wcfm_tracking_code
AND
wcfm_tracking_url
i found this hook elesewhere that allows me to fire a set of things to happen, once the tracking has been submitted into the system
“wcfm_after_order_mark_shipped” (Parameters -> $order_id, $order_item_id, $tracking_code, $tracking_url)
so now i want to take the above 2 order meta datas and push them into another plugin called AST
They code they provide to push data into thier system is:
<?php if ( class_exists( 'WC_Advanced_Shipment_Tracking_Actions' ) ) {
$order_id = '123'; //Replace with your order id
$tracking_provider = 'USPS'; //Replace with your shipping provider
$tracking_number = '123123'; //Replace with your tracking number
$date_shipped = '2020-06-22'; ////Replace with your shipped date
$status_shipped = 1; // 0=no,1=shipped,2=partial shipped(if partial shipped order status is enabled)
$sku = 't-shirt,blue-jeans'; //the line item (product) SKU
$qty = '1,1'; //the line item (product) quantity
if ( function_exists( 'ast_insert_tracking_number' ) ) {
ast_insert_tracking_number( $order_id, $tracking_number, $tracking_provider, $date_shipped, $status_shipped, $sku, $qty );
}
}
SO using both codes provided, can anyone show me how i can take the metadata input from WCFM and push it into AST?
Ive hired someone on upwork, and they cant even figure it out, but it seems so straightforward.
This is the code we have,it pushes the data in but it comes in looking like this
Instead of this like it should
add_action( 'wcfm_after_order_mark_shipped', 'testwr', 99, 6 );
function testwr( $order_id, $order_item_id, $tracking_code, $tracking_url, $product_id, $wcfm_tracking_data ) {
$order = wc_get_order( $order_id );
$data['order_id'] = $order_id;
$data['tracking_provider'] = $tracking_url;
$data['wcfm_tracking_code'] = $wcfm_tracking_data['wcfm_tracking_code'];
$data['date_shipped'] = $order->order_date;
$data['status_shipped'] = 1;
extract($data);
foreach ($order->get_items() as $item) {
$product = wc_get_product($item->get_product_id());
$item_quantity[] = $item->get_quantity();
$item_sku[] = $product->get_sku();
}
if( $item_sku ) {
$data['sku'] = implode( ",",$item_sku );
}
$tracking_url = $tracking_url . "/" . $tracking_code;
$url = "<a href='".$tracking_url."'>test</a>";
$data['qty'] = implode( ",",$item_quantity );
$test = ast_insert_tracking_number( $order_id, $tracking_url, $tracking_url, $date_shipped, $status_shipped, $sku, $qty);
var_dump($test);
print_r($tracking_code);
print_r($data);
print_r($wcfm_tracking_data);
var_dump($order_item_id);
//ast_insert_tracking_number
die();
}
Kudos to anyone willing to give this a try and some time
Regards
I would like that when a user orders items, a special unique key is generated for each item. These keys / This key should then be visible in ALL order mails (admin and customer). Here is what I tried to do after some research around the web :
add_action('woocommerce_order_status_processing', 'process_membership_order');
//Trying to generate my keys for each item
function process_membership_order($order_id) {
$order = new WC_Order($order_id);
$items = $order->get_items();
foreach ($items as $item_id => $product) {
$key_id = "TESTING123"; //testing purpose of course, will call a function later
wc_add_order_item_meta($item_id, 'custom_key', $key_id);
}
}
add_action( 'woocommerce_email_order_meta', 'add_email_order_meta', 10, 3 );
//Trying to edit the email order infos
function add_email_order_meta($order_obj, $sent_to_admin, $plain_text){
$key = get_post_meta( $order_obj->get_order_number(), 'custom_key', true );
if ( $plain_text === false ) {
echo "<h2>Custom Information</h2><p>$key</p>";
} else {
echo "CUSTOM INFORMATION : $key";
}
}
It doesn't seem to work, my mails have the new title but it's always empty instead of showing my TESTING123 as many times as there is an item. I'm more a tinkerer than a dev, I've used an entire day on this, a little push on the right direction would be really appreciated, I think I'm close but something's missing ! Anyway, any advice would be great, thank you.
I think you need to get order items from the order object and then you can get your custom meta by using wc_get_order_item_meta. check below code.
add_action('woocommerce_order_status_processing', 'process_membership_order');
//Trying to generate my keys for each item
function process_membership_order($order_id) {
$order = new WC_Order($order_id);
$items = $order->get_items();
foreach ($items as $item_id => $product) {
$key_id = "TESTING123"; //testing purpose of course, will call a function later
wc_add_order_item_meta($item_id, 'custom_key', $key_id);
}
}
add_action( 'woocommerce_email_order_meta', 'add_email_order_meta', 10, 3 );
//Trying to edit the email order infos
function add_email_order_meta($order_obj, $sent_to_admin, $plain_text){
$order = wc_get_order( $order_obj->get_order_number() );
$items = $order->get_items();
foreach ( $order->get_items() as $item_id => $item ) {
$key = wc_get_order_item_meta( $item_id, 'custom_key', true );
if ( $plain_text === false ) {
echo "<h2>Custom Information</h2><p>$key</p>";
} else {
echo "CUSTOM INFORMATION : $key";
}
}
}
I am missing something. I have seen several articles about how to update an items meta data but I can't get any one of them to work. I need to get the item_id but I can't figure out how to do that.
$your_phone = $item->get_meta('dinner_phone'); // 1115559999
$update_phone = wdc_format_phone($your_phone); // comes back (111) 555-9999
wc_update_order_item_meta($item_id,'dinner_phone', $update_phone); //I want to update with new format
$new_phone = $item->get_meta('dinner_phone'); // doesn't work I still get 1115559999
I have tried to pull the Item_id by the following
foreach ( $items as $item ) {
$product_id = $item->get_product_id();
$item_id = $item['item_id'];
break;
}
Also tried this
foreach ($items as $key => $product ) {
$item_id = $key;
}
You will use the following from an existing WC_Order Object $order variable:
foreach ( $order->get_items() as $item-id => $item ) {
$dinner_phone = $item->get_meta('dinner_phone'); // 1115559999
if ( ! empty( $dinner_phone ) ) {
$formatted_diner_phone = wdc_format_phone( $dinner_phone ); // comes back (111) 555-9999
$item->update_meta_data('dinner_phone', $formatted_diner_phone);
$item->save(); // Save item
$new_phone = $item->get_meta('dinner_phone');
echo $new_phone; // Check that items is updated
}
$order->calculate_totals(); // Recalculate Order totals and save
}
It should work.
I am creating an online shop with WooCommerce and I'm adding a function which will update the bonus point to my database into absract-wc-payment-gateway.php.
Here is what I am doing:
Firstly, on the checkout page, the users will click the place order button and then the method will get the users bonus points and minus the bonus points with the get-total(), and then update to the database and go to the thank you page.
Then, the thank you page will get the user's bonus points from the database. And I set the bonus points value to 2000. So in this case, the bonus points should be minus by total Points($50.00)
Here is my code. It will be ran when the user clicks the place order button:
global $woocommerce;
$order = new WC_Order($order_id);
$total = $order->get_total();
$bonusPoint -= (int)$total; //minus total price and calculate the latest bonus point
$updateSql = "UPDATE userdata02 SET bonusPoint ='" .$bonusPoint. "' WHERE userID = 2147483647";
mysqli_query($link, $updateSql);// update to an int column
if(mysqli_query($link, $updateSql)) {
echo "Record updated successfully";
} else {
echo "Error update record: <>" . mysqli_error($link);
}
Call the method when the user clicks place button:
public function get_return_url( $order = null ) {
if ( $order ) {
//$message = "wrong answer";
//echo "<script type='text/javascript'>alert('$message');</script>";
$return_url = $order->get_checkout_order_received_url();
} else {
$return_url = wc_get_endpoint_url( 'order-received', '', wc_get_page_permalink( 'checkout' ) );
}
if ( is_ssl() || get_option('woocommerce_force_ssl_checkout') == 'yes' ) {
$return_url = str_replace( 'http:', 'https:', $return_url );
}
self::reducePoints(); //Call reducePoints();
return apply_filters( 'woocommerce_get_return_url', $return_url, $order );
}
The source code: reducePoints() lines 89 from abstract-WC-Payment-Gateway.php
The get_total() doesn't work and it returns zero.
What I am doing wrong?
You need to create an object for $order to use it with get_total(). Try this:
global $woocommerce;
$order = new WC_Order($order_id);
$total = $order->get_total(); //Get the total price of the order.
$bonusPoints -= (int)$total; //calculate the new bonusPoints
Update1: This is just solving the internal data error. We need to get the $order_id to get it work…
Note: You can remove global $woocommerce;before $order = new WC_Order($order_id); because is already included in public function reducePoints( ){
Update2 - The good track:
Remove my code:
global $woocommerce;
$order = new WC_Order($order_id);
Then at line 89 of your code just add $order in:
public function reducePoints( $order ){
global $woocommerce;
// ...
Really happy that this works… It was a long search...
I'm attempting to set meta data on an item when it's added to the cart, persist it through each page reload and when checkout is successful retrieve the meta data to pass to a seperate API.
The below code is successful in the ense that it echos the meta data after a page reload so I'm considering that to be a success.
add_action('woocommerce_order_status_completed', 'order_system');
add_filter('woocommerce_add_cart_item_data', 'nick_add_cart_item_data', 10, 2);
add_filter('woocommerce_get_cart_item_from_session', 'nick_get_cart_item_from_session', 10, 2);
function nick_add_cart_item_data($cart_item_meta, $product_id) {
global $woocommerce;
$nick_form_data = get_post_meta($product_id, '_nick_form_data', true);
$cart_item_meta['_nick_form_data'] = $nick_form_data;
$cart_item_meta['_nick_credential_data']['username'] = ( isset( $_POST['username'] ) && $_POST['username'] != '') ? $_POST['username'] : '';
$cart_item_meta['_nick_credential_data']['password'] = ( isset( $_POST['password'] ) && $_POST['password'] != '') ? $_POST['password'] : '';
return $cart_item_meta;
}
function nick_get_cart_item_from_session($cart_item, $values) {
if (isset($values['_nick_form_data'])) {
$cart_item['_nick_form_data'] = $values['_nick_form_data'];
}
if (isset($values['_nick_credential_data'])) {
$cart_item['_nick_credential_data'] = $values['_nick_credential_data'];
echo $values['_nick_credential_data']['username'] . $values['_nick_credential_data']['password'] ;
}
return $cart_item;
}
When I call this function, which fires when the order is completed I'm unable to retain any of the item meta data.
function order_system($order_id)
{
global $woocommerce;
try {
// do something that can go wrong
// instantiate new order from WooCommerce
$order = new WC_Order($order_id);
$userid = $order->user_id;
foreach ($order->get_items() as $item_id => $values) :
if (isset($values['_nick_form_data'])) :
// Not getting inside this case statement
endif;
endforeach;
....
I'm unsure of what I'm doing wrong, any help is appreciated. Thank you!!
It's a little late, but: although you're attaching your metadata to the cart items, they're not subsequently being added to the order items when the order is created. To do that:
function nick_add_order_item_meta($itemID, $values) {
$nick_form_data = $values['_nick_form_data'];
if (!empty($nick_form_data)) {
wc_add_order_item_meta($itemID, '_nick_form_data', $nick_form_data);
}
}
add_action('woocommerce_add_order_item_meta','nick_add_order_item_meta', 1, 2);
At the point your order is created, your cart item meta _nick_form_data will be attached to each item. You'll then be able to see it in the backend of WooCommerce when viewing an order: each order item should have a [?] next to it which will show you the attached metadata.
I believe you are hooking in too late with the 'order_system' function.
Try hooking in to here instead:
add_action('woocommerce_checkout_process', array(&$this, 'nick_checkout_field_process') );
function nick_checkout_field_process() {
global $woocommerce;
try {
// do something that can go wrong
// instantiate new order from WooCommerce
$order = new WC_Order($order_id);
$userid = $order->user_id;
foreach ($order->get_items() as $item_id => $values) :
if (isset($values['_nick_form_data'])) :
// Do Something here
// echo $values['_nick_credential_data']['username'] . $values['_nick_credential_data']['password'] ;
endif;
endforeach;
....