Closed vaclavgreif closed 4 years ago
I have the same issue, I need to work with WC session in my custom Rest API and suddenly, it doesn't work with the new WordPress version. Is there any workaround, please?
Hi @vasikgreif
Thank you for submitting the issue, to help us evaluate this issue can you please provide a copy of your WooCommerce System Status Report The System Status Report is found in your WordPress admin under WooCommerce > Status. Please select “Get system report”, then “Copy for support”, and then paste it here.
@vasikgreif @mejta Based on your error description seems like your code is trying to get something from the cart before its loaded. Note that woocommerce_is_rest_api_request
is a general filter which is called by method is_rest_api_request
, and there is no guarantee that it will be called after cart is loaded. My guess is, somewhere we or some other plugin is now calling this function before initializing of cart or session, and that's valid usage.
I would recommend that instead of woocommerce_is_rest_api_request
, you use the woocommerce_init
action to hook your function and use is_rest_api_request
inside an if statement to return early. Code could be something like:
add_action( 'woocommerce_init', 'my_function' );
function my_function() {
if ( ! WC()->is_rest_api_request() ) {
return;
}
WC()->frontend_includes();
if ( null === WC()->cart && function_exists( 'wc_load_cart') ) {
wc_load_cart();
}
/**
* My custom logic.
*/
}
Feel free to write back if there is any issues.
I think this solves only part of the problem.
First, the frontend functions seem to not to be loaded in the REST API, which I somehow fixed by calling WC()->frontend_includes();
.
The session still does not seem to persist the data.
In any case, something had to change, because this was working perfectly fine before. There really should be an easy way to enable the frontend functions in the REST API's, as the solutions provided seem more like a hack than a proper solution.
EDIT: I had the filter originally hooked on init
, after it stopped working, I moved that directly to the main plugin file, because the filter was not called at all when it was on init
.
The session still does not seem to persist the data.
I tested by adding the following in above snippet:
echo "\n Previous session: " . WC()->session->get( 'some_key' );
WC()->session->set( 'some_key', rand(0, 999) );
and seems to be working fine for me.
We save the session data in save_data
method in includes/class-wc-session-handler.php
, can you help debug by modifying this function to add some print statements and see if this method is being called at all.
@vedanshujain Thanks. To make it easier to debug for me, as the app is really complex, can you please tell me what exactly do I need to have all the frontend functions (cart, session, customer) included in the REST API? Does the wc_load_cart
function load everything?
Thanks
I'm curious what/why you all need to do custom REST API for the cart when CoCart is available and works. I'm always looking to improve so please let me know. You can even submit an enhanced issue on the repository. Thanks.
@seb86 I need only a very small portion of the functionality for the React wizard- I need to be able to add item to cart with custom data, add some customer info to session. CoCart is great for sure, but it's an overkill for what I need.
Same here.
Latest WooCommerce v4.3.1 Using a very bog standard WP REST API to remove an item from cart results in undefined cart functions.
What happened? Is this a bug or on purpose? Because it would be a backward compatibility nightmare to not allow standard WP REST API to access Cart and session...
what exactly do I need to have all the frontend functions (cart, session, customer) included in the REST API? Does the wc_load_cart function load everything?
You would also need to do WC()->frontend_includes
but that's it. (I am contemplating adding it inside wc_load_cart itself).
@justanotherco We do not load Cart, customer and sessions in REST API unless we need to for performance reasons. WooCommerce has generally supported API in the backend but not in the frontend (although this can change in future) and that's why there is no standard documented API for Cart yet.
Technically speaking, if we were infact loading cart for normal API requests, then that's a bug. If an extension is writing a frontend API then they need to include whatever they need, because as you can see, loading things that API won't need is a performance problem.
(This was initially added in #23792 #23102)
But this was working before v4.3, meaning you guys changed something.
Considering the change, is there official documentation on this topic? I'm sure it's very common use for themes/plugins to want to add ajax functionality to a site. All I'm trying to do is remove an item from a cart via a WP REST API call with a bog standard call with a simple PHP that uses WC() to identify, remove the item from the cart and then in the ajax success call, the wc_fragment_refresh is triggered.
Is there an official way to load cart only for a specific WP REST API call? That would be ideal.
@seb86 does CoCart allow us to define our own custom plugin wp-json/
Rest APIs and access the WooCommerce cart? It seems to just be an advanced Rest API for manipulating your cart, which is clearly not what the issue at hand is about.
@lostpebble No it does not let you define your own plugin. I clearly miss read the issue and thought users were trying to build something that was already available and working.
@vasikgreif @mejta Based on your error description seems like your code is trying to get something from the cart before its loaded. Note that
woocommerce_is_rest_api_request
is a general filter which is called by methodis_rest_api_request
, and there is no guarantee that it will be called after cart is loaded. My guess is, somewhere we or some other plugin is now calling this function before initializing of cart or session, and that's valid usage.I would recommend that instead of
woocommerce_is_rest_api_request
, you use thewoocommerce_init
action to hook your function and useis_rest_api_request
inside an if statement to return early. Code could be something like:add_action( 'woocommerce_init', 'my_function' ); function my_function() { if ( ! WC()->is_rest_api_request() ) { return; } WC()->frontend_includes(); if ( null === WC()->cart && function_exists( 'wc_load_cart') ) { wc_load_cart(); } /** * My custom logic. */ }
Feel free to write back if there is any issues. @vedanshujain Thankyou soo much, its working fine.
@vasikgreif Yes, it's just awful that the session has stopped working for the REST API. I also had problems after the update. But here in this topic there was a very simple solution. In my case, this helped me:
<?php
namespace IconicJew\RestAPI;
/**
* Class RestApi.
*/
class RestApi implements AutoloadInterface
{
public function load()
{
// ...
add_action('rest_api_init', [$this, 'create_rest_routes']);
// ...
}
public function create_rest_routes()
{
// ...
if ( null === WC()->cart && function_exists( 'wc_load_cart') ) {
wc_load_cart();
}
// ...
}
/**
* ...
*/
}
that is it is simple enough to call wc_load_cart
function on a hook rest_api_init
.
I hope this helps:)
I am closing this issue because it does not look like there is a bug that needs to be fixed. But please feel free to write for any suggestions.
I've been using
woocommerce_is_rest_api_request
filter without any issues, but after updating from 4.2 to 4.3.0 this suddenly stopped working, Cart and Session are no longer defined.Did anything change? I tried this:
wc_load_cart()
throwsCall to undefined function wc_get_cart_item_data_hash()
WC()->frontend_includes();
, which fixed that issueI need to have all the frontend functions available in the REST API as it was before 3.6, as I use the API for adding items to cart, saving customer data to session etc. Is there a preffered way to have all the frontend methods available in REST requests?
Thanks Václav