Viewed   195 times

I am trying to read from thankyou.php orders and populate order_id, sku, price, quantity to a javascript snipper. The problem for me is how to "catch" the loop in php and pass those variables to JavaScript Snipper.

<?php

function CustomReadOrder ( $order_id ) {
    // Lets grab the order
    $order = wc_get_order( $order_id );
    // This is the order total
    $order->get_total();

    // This is how to grab line items from the order 
    $line_items = $order->get_items();

    // This loops over line items
    foreach ( $line_items as $item ) {
        // This will be a product
        $product = $order->get_product_from_item( $item );

        // This is the products SKU
        $sku = $product->get_sku();

        // This is the qty purchased
        $qty = $item['qty'];

        // Line item total cost including taxes and rounded
        $total = $order->get_line_total( $item, true, true );

        // Line item subtotal (before discounts)
        $subtotal = $order->get_line_subtotal( $item, true, true );

        echo $order_id."-";
        echo $sku."-";
        echo $qty;
    }
}
?>

<?php add_action( 'woocommerce_thankyou', 'CustomReadOrder' ); ?>

<script type="text/javascript">
order.purchase = {
    currency: 'EUR',
    transactionId: '<?php echo $order->id ?>',
    products: [{
        id: '{{PRODUCT_SKU}}',
        category: '{{PRODUCT_CATEGORY}}',
        brand: '{{PRODUCT_BRAND}}',
        price: '{{PRODUCT_PRICE}}',
        quantity: '{{PRODUCT_QUANTITY}}'
    }, {
        id: '{{PRODUCT_SKU}}',
        category: '{{PRODUCT_CATEGORY}}',
        brand: '{{PRODUCT_BRAND}}',
        price: '{{PRODUCT_PRICE}}',
        quantity: '{{PRODUCT_QUANTITY}}'
    }]
};
</script>

 Answers

3

UPDATED
As you are finding hard to locate functions.php file you can created a plugin. Create a PHP file as wh-thankyou-tracking.php under /wp-content/plugins/ and copy paste the below code to it and save it. And form admin panel Activate WH Order Tracking JS plugin

<?php
/**
 * Plugin Name: WH Order Tracking JS
 * Version: 0.1
 * Description: This plugin will add a JS tracking code to WooCommerce Thankyou page.
 * Author: Raunak Gupta
 * Author URI: https://www.webhat.in/
 * Text Domain: wh
 */
if (!defined('ABSPATH'))
{
    exit;
} // Exit if accessed directly

if (!class_exists('WooCommerce'))
{
    exit;
}// Exit if WooCommerce is not active

function wh_CustomReadOrder($order_id)
{
    //getting order object
    $order = wc_get_order($order_id);

    $items = $order->get_items();
    $product_js = [];

    foreach ($items as $item_id => $item_data)
    {
        //getting product object
        $_product = wc_get_product($item_data['item_meta']['_product_id'][0]);

        //getting all the product category
        $pro_cat_array = wp_get_post_terms($_product->ID, 'product_cat');

        $sku = $sku = $_product->get_sku();
        $qty = $item_data['item_meta']['_qty'][0];
        $pro_cat = implode(',', $pro_cat_array);
        $pro_brand = $_product->get_attribute('pa_brand'); //replace it with your brand attribute slug
        $pro_price = $item_data['item_meta']['_line_total'][0];

        //storing all the line item as a string form
        $product_js[] = '{id: "' . $sku . '",category:"' . $pro_cat . '",brand:"' . $pro_brand . '",price: "' . $pro_price . '"quantity:"' . $qty . '"}';
    }

    ?>
    <script type="text/javascript">
        order.purchase = {
            currency: 'EUR',
            transactionId: '<?= $order->id ?>',
            products: [<?= implode(',', $product_js) ?>]
        };
    </script>
    <?php
}

add_action('woocommerce_thankyou', 'wh_CustomReadOrder');

Hope this helps!

Friday, November 18, 2022
2

The following code will redirect from checkout page to an external link passing few variables after 5 seconds using php and javascript:

 add_action( 'woocommerce_thankyou', 'thankyou_delated_external_redirection', 10, 1 );
function thankyou_delated_external_redirection( $order_id ){
    if( ! $order_id ){
        return;
    }

    $order          = wc_get_order( $order_id ); // Instannce of the WC_Order Object
    $order_total    = $order->get_total(); // Order total amount

    $link_redirect  = 'http://www.example.com/'; // Base url
    $link_redirect .= '?order_id='.$order_id.'&order_ammount='.$order_total; // passed variables

    ?>
    <script>
    jQuery(function($){
        // Redirect with a delay of 5 seconds
        setTimeout(function(){
            window.location.href = '<?php echo $link_redirect; ?>';
        }, 5000);
    });
    </script>
    <?php;
}

Code goes in function.php file of your active child theme (or active theme). tested and works.

The redirection link is like http://example.com/path/?order_id=1420&order_ammount=136.20

Tuesday, August 9, 2022
 
3

The action(s) you want are these:

add_action('woocommerce_update_product', 'productPublished');

add_action('woocommerce_new_product', 'productPublished');

function productPublished($product_id){
    //...
}

You can find them both (where they are triggered from) in the Woo source code here:

https://docs.woocommerce.com/wc-apidocs/source-class-WC_Product_Data_Store_CPT.html#237

I actually looked them up backwards by first finding where the source code for saving products was, and then looked for hooks in those methods (create/update).

 //found on Line 134 method create
 do_action( 'woocommerce_new_product', $id );


 //found on Line 237 method update
 do_action( 'woocommerce_update_product', $product->get_id() );

You'll also have to change this line:

function productPublished ($ID , $post , $update){
    $product = wc_get_product( $post->ID);
}

To

function productPublished($product_id){
    $product = wc_get_product( $product_id);
   //....
}

I don't think the other arguments (that are missing) matter to your code. Such as if it's an update or a new product, I also don't see $post used except to get the product ID, which we already have.

UPDATE (determine args for callback)

If you are not sure about the callback's arguments, you can look in the source code (as I did above) Or if you can find it in documentation Or as a last resort you can simply output them. The best way to output them is one of these 3

  • func_get_args() - "Returns an array comprising a function's argument list" http://php.net/manual/en/function.func-get-args.php
  • debug_print_backtrace() - "Prints a backtrace (similar to stacktrace)" https://secure.php.net/manual/en/function.debug-print-backtrace.php
  • Exception::getTraceAsString() try/catch and throw an exception to output the stacktrace http://php.net/manual/en/exception.gettraceasstring.php

Here is an example I built with a minimally/simplified working hook system modeled after WordPress's. For testing reasons and because it's really not that hard to build when you know how it works:

//global storage (functions, not classes)
global $actions;
$actions = [];

//substitute wordpress add_action function (for testing only) 
function add_action($action, $callback, $priorty=10, $num_args=1){
    global $actions;
    $actions[$action][] = [
         'exec' => $callback,
         'priorty'=>$priorty,
         'num_args' => $num_args
    ];

}
//substitute wordpress do_action function (for testing only) 
function do_action($action, ...$args){
    // PHP5.6+ variadic (...$args) wraps all following arguments in an array inside $args (sort of the opposite of func_get_args)
    global $actions;

    if(empty($actions[$action])) return;
    //sort by priory
    usort($actions[$action], function($a,$b){
       //PHP7+ "spaceship" comparison operator (<=>)
       return $b['priorty']<=>$a['priorty'];
    });

    foreach($actions[$action] as $settings){
        //reduce the argument list
        call_user_func_array($settings['exec'], array_slice($args, 0, $settings['num_args']));
    }
}

//test callback
function callback1(){
     echo "nn".__FUNCTION__."n";
    print_r(func_get_args());
}

//test callback
function callback2(){
    echo "nn".__FUNCTION__."n";
    try{
        //throw an empty exception
        throw new Exception;
    }catch(Exception $e){
         //pre tags preserve whitespace (white-space : pre)
        echo "<pre>";
        //output the stacktrace of the callback
        echo $e->getTraceAsString();
        echo "nn</pre>";
   }
}

//Register Hook callbacks, added in opposite order, sorted by priority
add_action('someaction', 'callback2', 5, 4);
add_action('someaction', 'callback1', 1, 5);

//execute hook
do_action('someaction', 1234, 'foo', ['one'=>1], new stdClass, false);

Output:

callback2
<pre>#0 [...][...](25): callback2(1234, 'foo', Array, Object(stdClass))
#1 [...][...](52): do_action('someaction', 1234, 'foo', Array, Object(stdClass), false)
#2 {main}

</pre>

callback1
Array
(
    [0] => 1234
    [1] => foo
    [2] => Array
        (
            [one] => 1
        )

    [3] => stdClass Object
        (
        )
    [4] =>
)

Sandbox

Stacktrace As you can see in the first output, we have a complete stacktrace of the application (minus the redacted info), including the function calls and the arguments used for those calls. Also note in this example, I registered it 2nd but the priority (set in add_action) made it execute first. Lastly, only 4 of the 5 arguments were used (also do to how add_action was called).

So do_action was called like this (with 'action' and 5 other args):

 do_action('someaction', 1234, 'foo', Array, Object(stdClass), false)

And the actual callback was called like this (without 'action' and only 4 other args):

 callback2(1234, 'foo', Array, Object(stdClass))

Function Arguments This is a bit more strait forward, but it doesn't give you the original call so you won't know the maximum number of args (which you can get from the call to do_action in the stacktrace). But if you just want a quick peek at the incoming data, it's perfect. Also I should mention this one uses all 5 args, which you can clearly see in the array for the second output. The [4] => is false, this is typically how print_r displays false (as just empty).

Debug Backtrace Unfortunately, debug_print_backtrace is disabled (for security reasons) in the sandbox, and Exception stacktrace is heavily redacted (typically it has file names and lines where functions are called from and located at) also for security reasons. Both of these can return arguments from things like connecting to the Database, which would contain the DB password in plain text, just for example. Anyway, debug_print_backtrace is pretty close to what an exception stack trace looks like anyway.

Summery

But in any case, this should give you an idea of what the data looks like. We can use functions like this (and Reflection) to interrogate the application at run time. I am sure there are other/more ways to do similar things too.

PS. It should go without saying, but I will say it anyway, these methods above work with any PHP function, and can be quite useful. Also as noted above, you should never show stacktraces on a live production machine.

Anyway, good luck.

Tuesday, August 30, 2022
 
1

You need simply the following (where "Free shipping" is the name of your free shipping method):

add_filter( 'woocommerce_thankyou_order_received_text', 'woo_change_order_received_text', 20, 2 );
function woo_change_order_received_text( $text, $order ) {
    if( $order->get_shipping_method() == 'Free shipping' ) {
        $text .= ' <div class="outside-delivery-checkout"><strong>'. __("PLEASE NOTE", "woocommerce") . ':</strong><br />'.__("Your shipping destination is outside of our normal delivery area. Our team will call you to calculate an additional fuel surcharge.", "woocommerce") . '</div>';
    }
    return $text;
}

Similar: Code goes in function.php file of your active child theme (or active theme). Tested and works.


Customize Order received page based on shipping method in WooCommerce

Monday, September 26, 2022
 
djsunny
 
2
  • Instead of using the cart object, the order object is used on the thankyou page. So we're going to use that object instead

  • You can use get_usage_limit_per_user() to get coupon usage limit per customer (for a single customer)

  • OR use get_usage_limit() to get coupon usage limit.

So you get:

function action_woocommerce_thankyou( $order_id ) {
    // Get $order object
    $order = wc_get_order( $order_id );

    foreach( $order->get_coupon_codes() as $coupon_code ) {
        // Get the WC_Coupon object
        $coupon = new WC_Coupon( $coupon_code );

        // Get usage count
        $count = $coupon->get_usage_count();
        
        // Get coupon usage limit per customer
        $limit = $coupon->get_usage_limit_per_user();
        
        // OR use this instead, to get coupon usage limit.
        // $limit = $coupon->get_usage_limit();
        
        // NOT empty
        if ( ! empty ( $count ) && ! empty ( $limit ) ) {
            // Calculate remaining
            $remaining = $limit - $count;
        
            // Output
            echo sprintf( '<span class="coupon-class">You used the <strong>%s</strong> coupon <strong>%d</strong> times and there are <strong>%d</strong> more left</span>', $coupon_code, $count, $remaining );
        }
    }
}
add_action( 'woocommerce_thankyou', 'action_woocommerce_thankyou', 10, 1 );
Tuesday, August 16, 2022
 
Only authorized users can answer the search term. Please sign in first, or register a free account.
Not the answer you're looking for? Browse other questions tagged :
 
Share