Cancel all user orders on subscription cancelled/expired - woocommerce

I want to develop a setup/code in which all the orders made by the user gets cancelled when the his subscription gets cancelled or expired. I am using Wordpress, Woocommerce and Woocommerce Subscriptions plugin.
I am trying to do by using something like this:
function my_cancelled_subscription( $user_id, $subscription_key ) {
//what code should I use here????
}
add_action( 'woocommerce_subscription_status_cancelled', 'my_cancelled_subscription', 10, 2 );
Please help mee.....

I figured it out..........
function my_cancelled_subscription( $subscription ) {
$order_id = $subscription->get_parent_id();
$order = wc_get_order( $order_id );
$user_id = $order->get_user_id();
$order->update_status( 'cancelled' );
$args = array(
'customer_id' => $user_id,
'status' => 'wc-completed',
);
$arrorders = wc_get_orders( $args );
foreach ($arrorders as $ord) {
$ord->update_status( 'cancelled' );
}
}
add_action( 'woocommerce_subscription_status_cancelled', 'my_cancelled_subscription' );

Related

Woocommerce action `woocommerce_order_status_completed` not executing

We have a problem as I am not a woocommerce developer. The client wants to make a product out of stock once the order is completed (and payment received).
I added an action in functions.php
add_action( 'woocommerce_order_status_completed', 'set_product_out_of_stock', 10, 1 );
function set_product_out_of_stock( $order_id ) {
error_log( "This is a test: set product out of stock $order_id ^^", 0 );
//if ( 'completed' == $order_status) {
$order = new WC_Order( $order_id );
$items = $order->get_items();
foreach ( $items as $item ) {
$status = 'outofstock';
update_post_meta($item['item_id'], '_stock', 0);
update_post_meta( $item['item_id'], '_stock_status', wc_clean( $status ) );
wp_set_post_terms($item['item_id'], 'outofstock', 'product_visibility', true );
}
// }
}
The problem is that this action is not even triggered, The error_log doesn't show in the logs.. what may be the issue?
The website uses woocommerce v 4.7 .
Thank you !

How to change user rol after buying in Woocommerce

thank you for any of you guys wanted to help me, I just want to know how to change the user role in WordPress when users buy something. I'm using WooCommerce. Regards
You can use Woocommerce action hooks. check my below code.
add_action( 'woocommerce_thankyou', 'change_user_role_afte_buying' );
function change_user_role_afte_buying( $order_id ) {
$order = wc_get_order( $order_id );
$items = $order->get_items();
$products_to_check = array( '1', '2', '3' ); // your product ids for checking someting buy
foreach ( $items as $item ) {
if ( $order->user_id > 0 && in_array( $item['product_id'], $products_to_check ) ) {
$user = new WP_User( $order->user_id ); // get user Object
$user->remove_role( 'customer' ); // remove old role
$user->add_role( 'new-role' ); // add new role
break; // Exit the loop
}
}
}

Updating GEO my WP fields using frontend Advanced custom fields form - WordPress

I’ve created a frontend form using the advanced custom fields (ACF) plugin. Within this form I’ve added some location fields such as postcode and city.
Below is the function used to update the post
global $post_id;
add_filter('acf/pre_save_post' , 'tsm_do_pre_save_post' );
function tsm_do_pre_save_post( $post_id ) {
// Bail if not logged in or not able to post
if ( ! ( is_user_logged_in() ) ) {
return;
}
// check if this is to be a new post
if( $post_id != 'new_job' ) {
return $post_id;
}
$profile_id = um_profile_id();
$userID = 'user_'.$profile_id;
$user_id = get_current_user_id();
// Create a new post
$post = array(
'ID'=> $post_id,
'post_type' => 'members',
'post_status' => 'publish',
'post_title' => $userID,
'post_author' => $user_id,
'category' => $_POST['acf']['field_594d0ffc2a66d'],
);
// insert the post
$post_id = wp_insert_post( $post );
// Save the fields to the post
do_action( 'acf/save_post' , $post_id );
return $post_id;
exit;
}
Once this form has been submitted, the custom post type is updated with no issues.
How can I add the submitted location data (postcode, city etc) into the GEO MY WP information for the post?
I’ve tried to follow the information in the docs secetion (http://docs.geomywp.com/gmw_pt_update_location/) but not having much luck.
GEO my WP function fron docs below:
function gmw_update_post_type_post_location( $post_id ) {
// Return if it's a post revision
if ( false !== wp_is_post_revision( $post_id ) )
return;
// check autosave //
if ( defined( 'DOING_AUTOSAVE' ) && DOING_AUTOSAVE ) {
return;
}
//check if user can edit post
if ( !current_user_can( 'edit_post', $post_id ) )
return;
//get the address from the custom field "address"
$address = get_post_meta( $post_id, 'address', true );
//varify that address exists. Otherwise abort the function.
if ( empty( $address ) )
return;
//include the update location file file
include_once( GMW_PT_PATH .'/includes/gmw-pt-update-location.php' );
//make sure the file included and the function exists
if ( !function_exists( 'gmw_pt_update_location' ) )
return;
//Create the array that will pass to the function
$args = array(
'post_id' => $post_id, //Post Id of the post
'address' => $address // the address we pull from the custom field above
);
//run the udpate location function
gmw_pt_update_location( $args );
}
//execute the function whenever post type is being updated
add_action( 'save_post_post', 'gmw_update_post_type_post_location' );
I believe I need to somehow combine the two functions so when the ACF form is updated, it also needs to update the GEO my wp meta data also.
I've tried combining the two functions but not having much luck.
If someone can point me in the right direction it will be very much appreciated
Thanks
Updated code.....
I've tried to add the gmw_update_post_type_post_location() function within the ACF function (code below) but still not having much luck...
global $post_id;
add_filter('acf/pre_save_post' , 'tsm_do_pre_save_post' );
function tsm_do_pre_save_post( $post_id ) {
// Bail if not logged in or not able to post
if ( ! ( is_user_logged_in() ) ) {
return;
}
// check if this is to be a new post
if( $post_id != 'new_job' ) {
return $post_id;
}
$profile_id = um_profile_id();
$userID = 'user_'.$profile_id;
$user_id = get_current_user_id();
$profilePostcode = get_post_meta( $post_id, 'location_postcode', true );
// Create a new post
$post = array(
'ID'=> $post_id,
'post_type' => 'members', // Your post type ( post, page, custom post type )
'post_status' => 'publish', // You can use -> publish, draft, private, etc.
'post_title' => $userID, // Post Title ACF field key
'post_author' => $user_id,
'category' => $_POST['acf']['field_594d0ffc2a66d'], // Post Content ACF field key
);
// insert the post
$post_id = wp_insert_post( $post );
// Save the fields to the post
do_action( 'acf/save_post' , $post_id );
gmw_update_post_type_members_location($post_id);
return $post_id;
exit;
}
function gmw_update_post_type_members_location( $post_id ) {
$profilePostcode = get_post_meta( $post_id, 'profile_location_postcode', true );
if ( empty( $profilePostcode ) )
return;
$address = array(
//'street' => $_POST['location_address'],
//'city' => $_POST['location_town'],
//'state' => $_POST['location_state'],
'zipcode' => $profilePostcode,
//'country' => $_POST['location_country']
);
include_once( GMW_PT_PATH .'/includes/gmw-pt-update-location.php' );
if ( !function_exists( 'gmw_pt_update_location' ) )
return;
$profile_id = um_profile_id();
$userID = 'user_'.$profile_id;
$user_id = get_current_user_id();
$args = array(
'post_id' => $post_id, //Post Id of the post
'post_title' => $userID, // Post Title ACF field key
'post_author' => $user_id,
'post_type' => 'members',
'address' => $address
);
//run the udpate location function
gmw_pt_update_location( $args );
}

Before update post to save value using save_post hook?

Add new product to update product then set sku number permalinks before post title to set in permalinks. Product import then set sku number in permalinks before update product.
I tried the below code:
add_action('save_post', 'change_title');
function change_title($post_id) {
// unhook this function so it doesn't loop infinitely
remove_action('save_post', 'change_title');
$_sku = get_post_meta( $post_id, '_sku', true);
$args = array('ID'=>$post_id,'post_name'=>$_sku,);
// update the post, which calls save_post again
wp_update_post( $args );
// re-hook this function
add_action('save_post', 'change_title');
}
Try :
function change_title( $post_id ){
$_sku = get_post_meta( $post_id, '_sku', true);
global $wpdb;
$wpdb->update( $wpdb->posts, array( 'post_title' => $_sku ), array( 'ID' => $post_id ) );
}
add_action( 'save_post', 'change_title');
Try this
function update_product_link( $post_id, $post, $update ) {
if( $post->post_type != "product" ) {
return;
}
$_sku = get_post_meta( $post_id, '_sku', true);
//This will update post name to SKU
$post->post_name = $_sku;
}
add_action( 'save_post', 'update_product_link', 1, 3 );
Also set your product permalink base structure to /product/%postname%/

WooCommerce Create a downloadable product's order programmatically

I use wc_create_order to create an order and everything is fine except the user can't have the downloadable product's download link in My Downloads section.
$def_args = array('customer_id' => $user_id, 'status' => 'completed');
$order = wc_create_order( $def_args );
$targs['totals']['subtotal'] = $ord['pay_amount'];
$targs['totals']['total'] = $ord['pay_amount'];
$targs['totals']['subtotal_tax'] = 0;
$targs['totals']['tax'] = 0;
$sku_ = $ord['sku'];
$order->add_product( get_product_by_sku( $sku_ ) , 1, $targs ); //(get_product with id and next is for quantity)
$order->set_address( $address, 'billing' );
$order->set_address( $address, 'shipping' );
$order->set_total( $ord['pay_amount'] );
$order->calculate_totals();
// I took get_product_by_sku function in stackoverflow but I don't remember which question.
function get_product_by_sku( $sku ) {
global $wpdb;
$product_id = $wpdb->get_var( $wpdb->prepare( "SELECT post_id FROM $wpdb->postmeta WHERE meta_key='_sku' AND meta_value='%s' LIMIT 1", $sku ) );
if ( $product_id ) return new WC_Product( $product_id );
return null;
}
$ord variable has some information about the order.
Should I need to call a function or something like that to make order with download link?
I found the solution, when creating an order, make the status processing and after call update_status.
$def_args = array('customer_id' => $user_id, 'status' => 'processing');
...
$order->update_status('completed');
Then user have her/his download links.

Resources