Get all WooCommerce subscriptions - php

I a need to create a wordpress template to collect all Woocommerce subscriptions, but I'm having trouble with the documentation. I need to know which files to import and which function to call.
Thank you in advice.

Update - You can use multiple ways:
1) The built in function wcs_get_subscriptions() which accepts specific arguments. In your case, to get all subscriptions, you will use:
$subscriptions = wcs_get_subscriptions(['subscriptions_per_page' => -1]);
You will get an array of Subscription protected objects where you can use on each object the WC_Data get_data() method, to access the data:
$subscriptions = wcs_get_subscriptions(['subscriptions_per_page' => -1]);
// Loop through subscriptions protected objects
foreach ( $subscriptions as $subscription ) {
// Unprotected data in an accessible array
$data = $subscription->get_data();
print_r( $data ); // Display the subscription raw data array
}
Related: Get Subscription Product author of a Woocommerce subscription
2) You can also use a SQL query to get all subscriptions
A SQL query can be lighter and allows more filtering. This way you can get only the required data in a more effective way.
As subscriptions are a Wordpress custom post type, You can get all subscriptions IDs first. Then in a foreach loop you will be able to get the WC_subscription object.
global $wpdb;
// get all subscriptions IDS
$subscriptions_ids = $wpdb->get_col("
SELECT ID FROM {$wpdb->prefix}posts
WHERE post_type LIKE 'shop_subscription'
");
// Loop through subscriptions Ids
foreach($subscriptions_ids as $subscription_id){
// Get an instance of the WC_Subscription object
$subscription = new WC_Subscription( $subscription_id );
$data = $subscriptions->get_data();
print_r( $data ); Display the subscription raw data (unprotected accessible array)
}
Then with the $subscription object and the $subscription_id you will be able to do what you want, using WC_Subscription methods to get the desired data or the using subscription ID on dedicated functions.
Official developer Documentation:
Introduction to Subscriptions Developer Documentation
Subscriptions Data Structures & Storage

You can use the built in function wcs_get_subscriptions($args) and pass the following $args
$args = array( 'subscriptions_per_page' => -1 );
$subscriptions = wcs_get_subscriptions( $args );
You can even filter by subscription status also in the arguments.

Related

How to get a Woocommerce order by meta_value in Wordpress

I am building a custom Wordpress plugin to integrate with Woocommerce Orders. This plugin receives a string as input. Upon receiving this string input, the plugin must search Woocommerce for an order that matches the passed in value. The Woocommerce Orders have a custom field my_number which stores the values I am searching. I read about WP_Query class. I read about get_posts function. Both takes a list of args as a parameter. All these do not answer my problem. The problem is that running queries using all these Wordpress built-in capabilities are not returning a result! What is fun to me is that if I use the same meta_key on a normal Wordpress post, I do get a result back. So, why am I not getting the same result back on a Wocommerce Order. You will see, I have tried even to remove post_type filter and all other fields and only left the meta_key. This is just one example:
$args = array(
'meta_key' => 'my_number',
);
$posts = get_posts( $args );
foreach ( $posts as $post ) {
return ("<pre>".print_r( $post,true)."</pre>");
}
So, my question is how to a search an Order in Woocomerce Wordpress using the existing functionalities.
I can see the record in MySQL when I run
SELECT * FROM `wordpressTable_postmeta` WHERE meta_key = 'my_number'
Attached screenshot shows this order, with the custom field.
Okay, so I came across this article. To query Woocommerce order, you need to use the Woocomerce class WC_Order_Query.
https://pluginrepublic.com/querying-woocommerce-orders/
Now my fixed query looks like this and it is returning something:
$args = array(
'meta_key' => 'my_number',
);
$query = new WC_Order_Query( $args );
$orders = $query->get_orders();
foreach ( $orders as $order ) {
return ("<pre>".print_r( $order,true)."</pre>");
}

How to Subscription details from the wcs_get_subscriptions_for_order() function

I have this variable:
$subscriptions = wcs_get_subscriptions_for_order($order_id, array('order_type' => 'parent'));
Using this print_r() I can see lots of data:
echo '<pre>';
print_r($subscriptions);
echo '</pre>';
How can I get some specific data like when the next payment date, when a user purchased the product, which product etc?
Is there any way?
$subscriptions-> get_date_created() , $subscriptions->get_items(), $subscriptions->get_status() $subscription->get_date( 'next_payment' )
Subscription is extended from WC_Order class. All the functions available for the order object are also available for the subscription object
https://woocommerce.com/document/subscriptions/develop/functions/

Woocommerce | Export Order Items to JSON | External API

Scenraio: using woocommerce and am required to serialize the order object and send to external api.
Issue: Unable to get the JSON of items in the order.
$order = new WC_Order( $order_id );
$items = $order->get_items();
I tried the following:
The implode($items); method returns the JSON but it has escaped quotes and does not separate the array items by a ",".
Tried foreach on $items to add each item to another array array_push($order_items,$item); but json_encode($order_items); return an array of nulls
Is there a way to inspect each property of the $item and assign it to a custom object, create an array and the serialize the same array?
PHP NOOB.

Get Woocommerce last order id from database using php

In Woocommerce, I am trying to get the last order id using the following code:
<?php $order = new WC_Order($post->ID);echo $order->id;//to escape # from order id $order_id = trim(str_replace('#', '', $order->get_order_number())); ?>
But it doesn't work as I am getting a zero value.
The purpose is to add 1 to this last order ID, to get the new usable order ID.
Any help is appreciated.
It seems that you would like to get the next usable POST ID (Order Id), to save it, for example, as new Order in database with some related data.
This is absolutely not the way to do it and you need to think it different... Now you can use one of the 3 following ways:
Using the WordPress dedicated function wp_insert_post() that returns the post ID (Order ID).
Using the Woocommerce dedicated function wc_create_order() that returns the WC_Order Object.
Then from the the order object, you can get the order ID using $order->get_id().
Using the Woocommerce empty WC_Order object instance and the save() method:
// Get an empty instance of the `WC_Order` Object
$order = new WC_Order();
// Save the order to the database
$order->save();
// Get the Order ID
$order_id = $order->get_id();
Addition - Get the last Order ID in Woocommerce:
To get and display the last order ID in woocommerce use a WC_Order_Query in this two simple line:
<?php
$last_order_id = wc_get_orders(array('limit' => 1, 'return' => 'ids')); // Get last Order ID (array)
echo (string) reset($last_order_id); // Displaying last order ID
?>
Tested and works

Link between Gravity Forms and Woocommerce APIs

I have a Woocommerce site, and I use Gravity Forms to further expand each order.
I am coding a management tool that consumes both APIs to make some statistics and other administration tools.
I can get a list of the Gravity Forms entries, and also a list of the orders. The problem I have is that I don't know how can I get the entry that is related to a particular order.
Is there a way to do this?
have you tried with the woocomerce history plugin or fetching the raw metadata out the item¿?
wc_get_order_item_meta($order_item_id, "_gravity_forms_history");
wc_get_order_item_meta($order_item_id, "_gravity_form_data");
keep in mind that this will require a new endpoint to be created is not put of the box.
The last time I worked with the WooCommerce Gravity Forms Product Addons (a year or so ago) it did not store the order ID in the entry (would have to happen after the entry is created and after the order is created), or the entry ID in the order. The latter probably makes more sense but both would require custom code.
Again, it's been some time since I worked with the add-on. I'd ping WC support and see if they any tips on implementing support for this.
This is where I found the link between WooCommerce and the gravity forms product addon:
In the database, find the order in the table your_table_prefix_posts, and grab its ID. I was filtering for the post_type "shop_order."
In the table your_table_prefix_woocommerce_order_items, find the ID just found and filter for "line_item" in the "order_item_type" column, and grab the "order_item_id."
Use that "order_item_id" to find the order's meta in the table your_table_prefix_woocommerce_order_itemmeta.
All of the order's gravity forms data is in there. It looks like there is no actual tie between what woo does and gravity, except that the form is filled out and it data is grabbed and stuck into your_table_prefix_woocommerce_order_itemmeta. I cannot find anything that ties a particular order to a particular gf entry, but you can get the data from Woo, and at least use that to search GF entries.
I was able to do this using Gravity Forms, Gravity Forms Product Addons, and Woocommerce using a three step process:
STEP 1: Get GF Entry ID/s as the entry is made and store it in a session. This happens before checkout is complete and sometimes before the user is logged in.
add_action( 'gform_after_submission', 'blb_get_lead_entry_id', 10, 2 );
function blb_get_lead_entry_id( $entry, $form ) {
$meta_value = $entry['id'];
//session array with all the entries because GF creates 2 entries each time for validation purposes apparently
if (!isset($_SESSION['entryclump'])) {
$_SESSION['entryclump'] = array();
}
$_SESSION['entryclump'][] = $meta_value;
//also an array with just the current entry which will end up be the later of the two entries added by GF
$_SESSION[ 'gf-entry-id' ] = $meta_value;
}
STEP 2: Include the entry you just gathered ($_SESSION[ 'gf-entry-id' ]) with the Cart Item Meta and then save it.
In this case, i am saving a field called "_gf_entry_ID" which will get added to the woocommerce_order_itemmeta table with the correct order_item_id and the later of the two GF entries as the meta_value.
//add cart item data
add_filter( 'woocommerce_add_cart_item_data', 'blb_add_gfentry_to_cart_data', 10, 3 );
function blb_add_gfentry_to_cart_data( $cartItemData, $productId, $variationId ) {
$entryid=$_SESSION[ 'gf-entry-id' ];
$cartItemData['GFentryID'] = $entryid;
return $cartItemData;
unset($_SESSION[ 'gf-entry-id' ]);
}
//add cart item data: session stuff
add_filter( 'woocommerce_get_cart_item_from_session', 'blb_cart_item_session', 10, 3 );
function blb_cart_item_session( $cartItemData, $cartItemSessionData, $cartItemKey ) {
if ( isset( $cartItemSessionData['GFentryID'] ) ) {
$cartItemData['GFentryID'] = $cartItemSessionData['GFentryID'];
}
return $cartItemData;
}
//save the data
add_action( 'woocommerce_add_order_item_meta', 'blb_save_gfentry', 10, 3 );
function blb_save_gfentry( $itemId, $values, $key ) {
if ( isset( $values['GFentryID'] ) ) {
wc_add_order_item_meta( $itemId, '_gf_entry_ID', $values['GFentryID'] );
}
}
STEP 3 (optional): Update the GF Form to reflect the correct created_by user ID. Now that checkout is complete and the user is logged in, we can do that.
function blb_woocommerce_thankyou( $order_id ) {
//Current User
$currentUserID = wp_get_current_user()->ID;
//GF Entry Array for Order
$order = new WC_Order( $order_id );
$items = $order->get_items();
$order_item_ids = array();
$gf_entry_ids = array();
foreach ( $items as $key=>$item ) {
$gf_entry_ids[] = $item['item_meta']['_gf_entry_ID'][0];
}
//First real quick clear all the entries in the entry clump (in case the user was already logged in)
//This is important because GF creates two forms for product add ons with Woocommerce and we only want one to show up in the list and edit plugin
$entryclump = $_SESSION[ 'entryclump' ];
foreach ( $entryclump as $entry ) {
global $wpdb;
$wpdb->update('wp_rg_lead', array('created_by' => null), array('id' => $entry));
}
//Update wp_rg_lead
if (($currentUserID!=0) && (isset($_SESSION[ 'entryclump' ])) ) {
foreach ( $gf_entry_ids as $gf_entry_id ) {
global $wpdb;
$wpdb->update('wp_rg_lead', array('created_by' => $currentUserID), array('id' => $gf_entry_id));
} //foreach
} //if
unset($_SESSION[ 'entryclump' ]);
};
add_action( 'woocommerce_thankyou', 'blb_woocommerce_thankyou', 10, 1 );

Categories