I am making changes to some data after the order. Transactions are taking place in the database. There is no problem. But the problem is recalculating the order amount.
If I run the relevant function (calculate_totals) elsewhere, the calculation takes place. But it is not happening in example_function. There are no errors in the code. It works without problems.
My code is as follows:
//...
add_action( 'template_redirect', [ $this, 'example_function' ], 10 );
//...
function example_function() {
foreach ($order->get_items() as $item_id => $item) {
wc_update_order_item_meta( $item_id, '_line_tax', $new_value1));
wc_update_order_item_meta( $item_id, '_line_total',$value2));
//...
}
//Save and finish
$order->calculate_totals();
$order->save();
wc_add_notice( __( 'Successful', 'text-domain' ), 'success' );
wp_redirect( wc_get_account_endpoint_url( 'new-page' ) );
exit();
}
For example, then, calculation occurs later with a definition like the following.
add_action( 'woocommerce_view_order', 'example_view_order', 20 );
function example_view_order($order_id){
$order = wc_get_order($order_id);
//Save and finish
$order->calculate_totals();
}
Update:
A few hours later I found a thread like this: StackOverLink
I guess the order_item_meta functions are running asynchronously. Probably the problem is caused by that. However, a solution has not been found.
Related
For a custom post type in WordPress, I want to automatically use the post ID as a slug for the post. For this, I use the following code:
add_action( 'wp_insert_post', 'change_slug', 10, 3 );
function change_slug( $post_id, $post, $update ) {
if ( $post->post_type != 'custom_post_type' ) {
return;
}
wp_update_post(
array(
'ID' => $post_id,
'post_name' => $post_id, // slug
)
);
}
This code is based on a previous answer on so: https://wordpress.stackexchange.com/a/160483/181877
However, using this code I cannot even open the new post page for this CPT in WordPress. instead, I get a 503 Service unavailable message, which I believe is caused by a timeout.
I'm not sure what's wrong with my code. Any pointers?
Ok, I figured it out.
It seems like it resulted in an infinite loop, not sure why. But I included an extra if statement to check for the $update variable, making sure the code is not run during the update of a post and only when a new one is published. This seemed to have resolved it.
Below is my final code:
add_action( 'wp_insert_post', 'change_slug', 10, 3 );
function change_slug( $post_id, $post, $update ) {
if ( $post->post_type != 'custom_post_type' ) {
return;
}
if ( $update ) { // added this
return;
}
wp_update_post(
array(
'ID' => $post_id,
'post_name' => $post_id,
)
);
}
I read several questions here and from Google search results, but I wasn't able to make it work. I have a function I want to run once every day which will fetch data from external source and store it on options page.
add_action( 'wp', 'update_stock_market' );
add_action( 'get_stock_market_daily_data', 'get_stock_market_data', 1, 1 );
function update_stock_market() {
if ( ! wp_next_scheduled( 'get_stock_market_daily_data' ) ) {
wp_schedule_event( time(), 'daily', 'get_stock_market_daily_data', array($company) );
}
}
function get_stock_market_data($company ) {
//do something here to get $data;
update_option( 'stock_market_data', $data);
}
However, no matter what happens, I cannot find the scheduled cron in the wp-options table under the option-name of cron
This code is working for me on a clean instance of WordPress, instead of looking directly in the database have you tried using the plugin WP Crontrol? Alternatively, with debug enabled, try adding a log entry to you update_stock_market function to check that the sechudled event is being called.
add_action( 'wp', 'update_stock_market' );
add_action( 'get_stock_market_daily_data', 'get_stock_market_data', 1, 1 );
function update_stock_market() {
error_log( 'triggered' );
if ( ! wp_next_scheduled( 'get_stock_market_daily_data' ) ) {
wp_schedule_event( time(), 'daily', 'get_stock_market_daily_data', array($company) );
}
}
function get_stock_market_data($company ) {
//do something here to get $data;
update_option( 'stock_market_data', $data);
}
I am trying to run some code everytime after the order is updated using 'woocommerce_update_order' action hook as you can see below:
add_action( 'woocommerce_update_order', 'update_order' );
After some time spent on developing 'update_order' function I realized that it is not called only once as I supposed but it is called multiple times.
So for testing I rewrite 'update order' function as you can see below:
function update_order( $order_id ) {
$order = wc_get_order( $order_id );
$current_count = get_post_meta( $order_id, '_edit_sale_count', true );
$new_count = 1;
if( $current_count ) $new_count = $current_count + 1;
$order->update_meta_data( '_edit_sale_count', $new_count );
$order->save();
}
After updating a single order and checking database, I realized that function 'update_order' is called 1500 times...
So my question is why is this the case? And how I can prevent multiple times execution on single update and force it to run once only?
Thanks
I am having difficulty doing this and have checked over previous questions however they do not seem to be working.
So far i have disabled the default wordpress cron by adding below to my wp-config.php:
define('DISABLE_WP_CRON', true);
Then i have attempted to schedule my task to run every 5 mins from within my plugins main php file:
function my_cron_schedules($schedules){
if(!isset($schedules["5min"])){
$schedules["5min"] = array(
'interval' => 5*60,
'display' => __('Once every 5 minutes'));
}
if(!isset($schedules["30min"])){
$schedules["30min"] = array(
'interval' => 30*60,
'display' => __('Once every 30 minutes'));
}
return $schedules;
}
add_filter('cron_schedules','my_cron_schedules');
function schedule_my_cron(){
wp_schedule_event(time(), '5min', 'fivemin_schedule_hook');
}
if(!wp_get_schedule('fivemin_schedule_hook')){
add_action('init', 'schedule_my_cron',10);
}
function fivemin_schedule_hook() {
get_feed();
}
So the above appears to be scheduling my event within database however have 100's of entries when checking cron schedule with:
<?php print_r(get_option('cron')); ?>
I have also made sure to update my crontab with below:
* * * * * wget -q -O - http://wordpress.com/wp-cron.php?doing_wp_cron
However my task does not appear to be running and am concerned about the amount of entries within database for this 5min job.
Each entry looks like below:
Array ( [1524308364] => Array ( [fivemin_schedule_hook] => Array ( [40cd750bba9870f18aada2478b24840a] => Array ( [schedule] => 5min [args] => Array ( ) [interval] => 300 ) ) )
I have tried debugging wp-cron.php by echoing out the $hook when it tries to fire and my hook is shown when i visit wp-cron.php directly. The actual function however just does not seem to fire.
Try this:
Replace this:
function schedule_my_cron(){
wp_schedule_event(time(), '5min', 'fivemin_schedule_hook');
}
if(!wp_get_schedule('fivemin_schedule_hook')){
add_action('init', 'schedule_my_cron',10);
}
..with this:
function schedule_my_cron(){
// Schedules the event if it's NOT already scheduled.
if ( ! wp_next_scheduled ( 'my_5min_event' ) ) {
wp_schedule_event( time(), '5min', 'my_5min_event' );
}
}
// Registers and schedules the my_5min_event cron event.
add_action( 'init', 'schedule_my_cron' );
// Runs fivemin_schedule_hook() function every 5 minutes.
add_action( 'my_5min_event', 'fivemin_schedule_hook' );
//add_action( 'my_5min_event', 'another_function_to_call' );
//add_action( 'my_5min_event', 'another_function_to_call2' );
But a more appropriate/preferred way is to add this in the activation function for your plugin:
wp_schedule_event( time(), '5min', 'my_5min_event' );
Example:
register_activation_hook( __FILE__, 'my_plugin_activation' );
function my_plugin_activation() {
if ( ! wp_next_scheduled ( 'my_5min_event' ) ) {
wp_schedule_event( time(), '5min', 'my_5min_event' );
}
}
..which would be used in place of the following:
function schedule_my_cron(){
// Schedules the event if it's NOT already scheduled.
if ( ! wp_next_scheduled ( 'my_5min_event' ) ) {
wp_schedule_event( time(), '5min', 'my_5min_event' );
}
}
// Registers and schedules the my_5min_event cron event.
add_action( 'init', 'schedule_my_cron' );
And add this somewhere in the deactivation function for your plugin:
wp_clear_scheduled_hook( 'my_5min_event' );
Example:
register_deactivation_hook( __FILE__, 'my_plugin_deactivation' );
function my_plugin_deactivation() {
wp_clear_scheduled_hook( 'my_5min_event' );
}
See https://codex.wordpress.org/Function_Reference/wp_schedule_event#Examples for more details.
I am using WC v. 2.3.9.
woocommerce_add_order_item_meta gets fired but my callback function only gets one parameter, three expected.
I want to add order item meta at the creation of the order.
Is this hook really available? Some rumour say that it's deprecated.
Edit : after a few research it's the function woocommerce_add_order_item_meta() that is deprecated.
Anyway I can find it in woocommerce/includes/class-wc-checkout.php. And the "do_action()" on this hook seems straightforward:
// Store the line items to the new/resumed order
foreach ( WC()->cart->get_cart() as $cart_item_key => $values ) {
$item_id = $order->add_product(
$values['data'],
$values['quantity'],
array(
'variation' => $values['variation'],
'totals' => array(
'subtotal' => $values['line_subtotal'],
'subtotal_tax' => $values['line_subtotal_tax'],
'total' => $values['line_total'],
'tax' => $values['line_tax'],
'tax_data' => $values['line_tax_data'] // Since 2.2
)
)
);
if ( ! $item_id ) {
throw new Exception( sprintf( __( 'Error %d: Unable to create order. Please try again.', 'woocommerce' ), 402 ) );
}
// Allow plugins to add order item meta
do_action( 'woocommerce_add_order_item_meta', $item_id, $values, $cart_item_key );
}
my custom plugin code:
public function __construct(){
add_action('woocommerce_add_order_item_meta', array($this, 'charlie_ajoute_un_order_item_meta'));
}
public function charlie_ajoute_un_order_item_meta($item_id, $values, $cart_item_key){
if (isset($values['cred_meta']['cred_post_id'])){
$annonce_id = $values['cred_meta']['cred_post_id'];
}
elseif(isset($values['annonce_concernee'])){
$annonce_id = $values['annonce_concernee'];
}
else{
$annonce_id = 'turlututu';
/* as $values as well as $$cart_item_key are not set, my order item meta is always "turlututu".*/
}
wc_add_order_item_meta( $item_id, 'annonce_concernee', $annonce_id, true );
}
Thanks for your help !
Charles
Shame on me!I had not found necessary to add the last two arguments of the add_action() function. So the default number of argument being one, only one was passed to my callback.
so the right code for the add_action() function is:
add_action('woocommerce_add_order_item_meta', array($this, 'charlie_ajoute_un_order_item_meta'), 10, 3);
Hope it may help someone.
Charles