I have a problem in wordpress.
So at the end of a payment in woocommerce, I would like to make a query and insert in a table in the database the name of the user, the type of subscription and the days required.
How do you think I could do that?
So far, I've written this
function wpglorify_change_role_on_purchase( $order_id ) {
global $wpdb;
$order = new WC_Order( $order_id );
$items = $order->get_items();
$product_id = 193; // that's a specific product ID
foreach ( $items as $item ) {
if( $product_id == $item['product_id'] && $order->user_id ) {
$user = new WP_User( $order->user_id );
// Remove old role
$user->remove_role( 'Author' );
// Add new role
$user->add_role( 'Subscriber' );
$query = $wpdb->insert('wp_pms_member_subscriptions', array(
'id' => 1,
'user_id' => $user->id,
'subscribtion_plan_id' => 233,
'status' => 'active'
));
$wpdb->query($query);
}
}
}
But it doesn't really do what I want and I would like to make a query in this table and insert the member directly in the subscription table
And the name of table is
wp_pms_member_subscriptions
Related
My issue is similar to this question. The answers are however failing for me.
When a new user subscribes to the website, the automatic code fails, as can be read on this log:
Screenshot of log from woocommerce
Specifically, i think the code failing is:
// Get an instance of the customer WP_User Object
$user = $order->get_user();
This is the whole code block:
// Custom function for your settings - Variation id per user role
function variation_id_per_user_role_settings(){
// Settings: set the variation ID as key with the related user role as value
return array(
//Free subscriptions
'1023' => 'free',
//Favorit subscriptions
'995' => 'favorit',
'996' => 'favorit',
'1811' => 'favorit',
'1812' => 'favorit',
'1814' => 'favorit',
'1815' => 'favorit',
'1816' => 'favorit',
'1818' => 'favorit',
//Unlimited subscriptions
'1013' => 'unlimited',
'1014' => 'unlimited',
//Partner subscriptions
'1016' => 'partner',
'1017' => 'partner',
);
}
// Custom function that check item and change user role based on variation ID
function check_order_item_and_change_user_role( $item, $user, $settings ){
$product = $item->get_product(); // The product object
// Only for variation subscriptions
if( $product->is_type('subscription_variation') ) {
$variation_id = $item->get_variation_id(); // the variation ID
$user_role = $settings[$variation_id]; // The right user role for the current variation ID
// If current user role doesn't match with the right role
if( ! in_array( $user_role, $user->roles) ) {
// Remove "subscriber" user role (if it is set)
if( in_array('subscriber', $user->roles) ) {
$user->remove_role( 'subscriber' );
}
// Remove other user roles (if they are set)
foreach ( $settings as $key_id => $value_role ) {
if( in_array($value_role, $user->roles) && $user_role !== $value_role ) {
$user->remove_role( $value_role );
}
}
// Set the right user role (if it is not set yet)
$user->set_role( $user_role );
}
}
}
// On first purchase (if needed)
add_action( 'woocommerce_subscription_status_updated', 'active_subscription_change_user_role', 100, 3 );
function active_subscription_change_user_role( $subscription, $new_status, $old_status ) {
// When subscrition status is updated to "active"
if ( $new_status === 'active' ) {
// Get the WC_Order Object from subscription
$order = wc_get_order( $subscription->get_parent_id() );
// Get an instance of the customer WP_User Object
$user = $order->get_user();
// Check that it's not a guest customer
if( is_a( $user, 'WP_User' ) && $user->ID > 0 ) {
// Load settings
$settings = variation_id_per_user_role_settings();
// Loop through order items
foreach ( $subscription->get_items() as $item ) {
check_order_item_and_change_user_role( $item, $user, $settings );
}
}
}
}
// On switched purchased subscription
add_action( 'woocommerce_order_status_changed', 'switched_subscription_change_user_role_on_order_status_change', 100, 4 );
function switched_subscription_change_user_role_on_order_status_change( $order_id, $old_status, $new_status, $order ) {
// When order status is updated to 'processing' or 'completed' status
if ( in_array( $new_status, array('processing','completed') ) ) {
// Get an instance of the customer WP_User Object
$user = $order->get_user();
// Check that it's not a guest customer
if( is_a( $user, 'WP_User' ) && $user->ID > 0 ) {
// Load settings
$settings = variation_id_per_user_role_settings();
// Loop through order items
foreach ( $order->get_items() as $item ) {
check_order_item_and_change_user_role( $item, $user, $settings );
}
}
}
}
What i'm trying to do is:
check if the order has a subscription, change the role from "subscriber" to a role fitting the subscription.
change role when subscription ends or is changed.
I Want to show meta "email" of a customers each order, but this is throwing an error.
add_action( 'woocommerce_before_edit_account_address_form', 'save_billing_email_to_user', 12, 1 );
function save_billing_email_to_user( $user_id ) {
$query = new WC_Order_Query(
array(
'customer_id' => $user_id
)
);
$orders = $query->get_orders();
foreach($orders as $ro => $inn){
echo $ro['email'];
}
}
What Im doing wrong here?
Use instead the following revisited code that will query one order to get the billing email:
add_action( 'woocommerce_before_edit_account_address_form', 'save_billing_email_to_user', 12 );
function save_billing_email_to_user( $user_id ) {
$orders = wc_get_orders( array( 'customer_id' => $user_id , 'limit' => '1' ) );
if ( ! empty( $orders ) ) {
$order = reset( $orders );
$order_id = $order->get_id();
$billing_email = $order->get_billing_email();
echo $billing_email;
}
}
Code goes in functions.php file of the active child theme (or active theme). Tested and works.
Or you can show the billing email address from each order of a customer like:
add_action( 'woocommerce_before_edit_account_address_form', 'save_billing_email_to_user', 12 );
function save_billing_email_to_user( $user_id ) {
$orders = wc_get_orders( array( 'customer_id' => $user_id ) );
foreach( $orders as $order ){
$order_id = $order->get_id();
echo $order->get_billing_email() . '<br>';
}
}
I'm trying to implement a feature where customers receive a new user role after a certain amount of orders have been made, but all those orders must have been made within the same year.
I was able to assign the user role based on nth number of orders but can't seem to go beyond to where the date needs to be taken into consideration, can someone point me in the right direction or point out what I might be missing.
This is what I have tried so far.
function change_user_role_on_order_status_completed( $order_id ) {
$order = new WC_Order( $order_id );
$user_id = $order->user_id;
$order_this_year = false;
$current_date = date('Y');
$total_orders = get_posts( array(
'numberposts' => -1,
'meta_key' => '_customer_user',
'meta_value' => $user_id,
'post_type' => 'shop_order',
) );
if ( $total_orders > 1 ) {
foreach ($order->get_items() as $item_key => $item_values):
// Get the item date
if ($item_date = $item_values->get_date_completed()->format ('Y') == $current_date) {
$order_this_year = true;
}
endforeach;
if ($order_this_year) {
$user = new WP_User( $order->user_id );
// Set role editor
$user->set_role( 'customer_club' );
}
}
}
add_action( 'woocommerce_order_status_completed', 'change_user_role_on_order_status_completed', 10, 1 );
Using WC_Order_Query here is a much lighter and simple way to change the user role based on yearly orders count:
add_action( 'woocommerce_order_status_completed', 'change_user_role_on_order_status_completed', 10, 2 );
function change_user_role_on_order_status_completed( $order_id, $order ) {
// Here set the minimal order count
$min_orders_count = 3;
// The WC_Order_Query
$queried_orders = wc_get_orders( array(
'limit' => -1,
'customer_id' => $order->get_customer_id(),
'date_paid' => '>=' . date('Y') . '-01-01', // or 'date_created'
'return' => 'ids'
) );
if ( sizeof($queried_orders) >= $min_orders_count ) {
// Get an instance of the customer WP_User Object
$user = $order->get_user();
// Change the user role
$user->set_role( 'customer_club' );
}
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
WooCommerce 3.0 broke my app and I cannot figure out how to fix it now.
I have an action for when a subscription is added/changed running here:
Inside the function I was getting the order details and finding the line item for a variable subscription to update my custom DB with the option as well as getting custom order meta that I added via woocommerce_form_field:
This no longer works and everything appears protected? How can I update this to work with 3.0?
add_action( 'woocommerce_subscription_status_changed', 'update_subscription', 10, 3 );
function update_subscription( $id, $old_status, $new_status ) {
$sitelink_db = new SSLA_DB_Sitelink();
$order = new WC_Order( $id );
$items = $order->get_items();
$subscription_type = '';
$user_id = $order->get_user_id();
$sitelink_domain = get_post_meta( $order->id, 'ssla_sitelink_url', true );
foreach ($items as $item) {
if( "SiteLink Subscription" === $item['name'] ) {
$subscription_type = $item['brand'];
}
}
$customer_data = array(
'user_id' => $user_id,
'subscription_type' => $subscription_type,
'domain_referrer' => $sitelink_domain,
'active_subscription' => $new_status,
'date_modified' => date( 'Y-m-d H:i:s' ),
);
$sitelink_db->add( $customer_data );
}
Basically I need to get that variation name of the subscription to store in my DB, as well as that custom meta field I made. Which does not work anymore either
Here's my best guess. It's impossible to test since I don't have the same setup as you.
Few notes:
The $subscription object is passed to the woocommerce_subscription_status_changed hook so let's use it.
$order->id should be replaced by $order->get_id() in WC3.0, but we're going to use the the $subscription object (the subscription order class extends the order class so it's similar).
getters must be used on the WC_Order_Item_Product object that is returned when looping through get_items() so $item['name'] becomes $item->get_name()
Here's the full code block:
add_action( 'woocommerce_subscription_status_changed', 'update_subscription', 10, 4 );
function update_subscription( $subscription_id, $old_status, $new_status, $subscription ) {
$match_this_id = 99; // Change this to the product ID of your special subscription
$sitelink_db = new SSLA_DB_Sitelink();
$items = $subscription->get_items();
$subscription_type = '';
$user_id = $subscription->get_user_id();
$sitelink_domain = $subscription->get_meta( 'ssla_sitelink_url' );
foreach ($items as $item) {
if( $match_this_id === $item->get_product_id() ) {
$product = $item->get_product();
if( $product->is_type( 'variation' ) ){
$subscription_type = $product->get_attribute( 'brand' );
}
}
}
$customer_data = array(
'user_id' => $user_id,
'subscription_type' => $subscription_type,
'domain_referrer' => $sitelink_domain,
'active_subscription' => $new_status,
'date_modified' => date( 'Y-m-d H:i:s' ),
);
$sitelink_db->add( $customer_data );
}
I have a product loop in Woocommerce. If a customer has purchased a product before, I would like to replace the purchase product button with a message and the date of the order. For example.
"You purchased this product on Jan. 15, 2016"
I can get the product id and I can get the current user id, but can't figure out how to use those pieces of info to pull order ids.
$postid = get_the_ID();
$current_user = wp_get_current_user();
$has_product = wc_customer_bought_product( $current_user->user_email, $current_user->ID, $product->id);
Ideas?
You can use this function below
function _cmk_check_ordered_product( $id ) {
// Get All order of current user
$orders = get_posts( array(
'numberposts' => -1,
'meta_key' => '_customer_user',
'meta_value' => get_current_user_id(),
'post_type' => wc_get_order_types( 'view-orders' ),
'post_status' => array_keys( wc_get_order_statuses() )
) );
if ( !$orders ) return false; // return if no order found
$all_ordered_product = array(); // store products ordered in an array
foreach ( $orders as $order => $data ) { // Loop through each order
$order_data = new WC_Order( $data->ID ); // create new object for each order
foreach ( $order_data->get_items() as $key => $item ) { // loop through each order item
// store in array with product ID as key and order date a value
$all_ordered_product[ $item['product_id'] ] = $data->post_date;
}
}
if ( isset( $all_ordered_product[ $id ] ) ) { // check if defined ID is found in array
return 'You purchased this product on '. date('M. d, Y', strtotime( $all_ordered_product[ $id ] ) );
} else {
return 'Product Never Purchased';
}
}
e.g.
Showing message on single product page echo _cmk_check_ordered_product( get_the_ID() );