woocommerce / woocommerce-blocks

(Deprecated) This plugin has been merged into woocommerce/woocommerce
https://wordpress.org/plugins/woo-gutenberg-products-block/
GNU General Public License v3.0
406 stars 219 forks source link

PHP Error Uncaught Error: Call to undefined function wc_empty_cart() // class-wc-session-handler.php #7537

Closed CodeAdminDe closed 1 year ago

CodeAdminDe commented 2 years ago

Describe the bug

When calling the API page "/wp-json/wp/v2/pages/223", the following error is issued at irregular intervals (about every 10 to 20 reloads):

2022-10-07T08:32:25+00:00 CRITICAL Uncaught Error: Call to undefined function wc_empty_cart() in /www/htdocs/[REDACTED]/wp-content/plugins/woocommerce/includes/class-wc-session-handler.php:372
Stack trace:
#0 /www/htdocs/[REDACTED]/wp-content/plugins/woocommerce/includes/class-wc-session-handler.php(363): WC_Session_Handler->forget_session()
#1 /www/htdocs/[REDACTED]/wp-content/plugins/woocommerce/includes/class-wc-session-handler.php(99): WC_Session_Handler->destroy_session()
#2 /www/htdocs/[REDACTED]/wp-content/plugins/woocommerce/includes/class-wc-session-handler.php(71): WC_Session_Handler->init_session_cookie()
#3 /www/htdocs/[REDACTED]/wp-content/plugins/woocommerce/includes/class-woocommerce.php(857): WC_Session_Handler->init()
#4 /www/htdocs/[REDACTED]/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Utilities/DraftOrderTrait.php(17): WooCommerce->initialize_session()
#5 /www/htdocs/[REDACTED] in /www/htdocs/[REDACTED]/wp-content/plugins/woocommerce/includes/class-wc-session-handler.php in Zeile 372

Apparently this is a problem related to the shopping cart and woocoomerce-blocks. The problem already occurred in WooCommerce version 6.9.4 and is still present in the current version.

It feels like the error appears more often when changes were made in the cart directly before (items added / deleted). But this is absolutely not technically justifiable.

To reproduce

Steps to reproduce the behavior

  1. Go to 'https://[SHOPDOMAIN.TLD]/wp-json/wp/v2/pages/223'
  2. Click on Reload multiple times.
  3. See error (Enable WP_DEBUG beforehand or take a look at the logs /wp-admin/admin.php?page=wc-status&tab=logs)

Expected behavior

Expected behavior would be that the page loads without a critical issue anytime it's loaded.

Environment

WordPress

Desktop

Tested on (but not really related due to server side error):

Thanks for help!

Kind regards, CodeAdminDe

wavvves commented 2 years ago

Hi @CodeAdminDe, thank you for reporting this. Can you provide more details about that page (id: 223)? What contents does it have specifically? Blocks, shortcodes, etc Or, if you can provide that, a live link to it.

Thanks

CodeAdminDe commented 2 years ago

HI @wavvves, no problem. unfortunately I can't post the specific content of the page, because it's a customer project that hasn't been published yet.

However, the general overview of the used blocks from the list view may help. image

The blue colored blocks are added via the Spectra plugin which comes out-of-the-box with the Astra Pro theme. The issue occurs sporadically, so that I spontaneously did not manage to reproduce it again and therefore cannot estimate whether it would also occur on other pages.

I hope these - unfortunately few - infos help nevertheless. Thanks in advance! :-)

jmslbam commented 1 year ago

Hi @CodeAdminDe I encountered this issues also and traced it back to the add_to_cart data in the get_item_response() method here https://github.com/woocommerce/woocommerce-blocks/blob/trunk/src/StoreApi/Schemas/V1/ProductSchema.php#L475-L481

And specifily the QuantityLimits call which goes to https://github.com/woocommerce/woocommerce-blocks/blob/423ff5b23a72ea737e19d6d93c3e0b3de9038106/src/StoreApi/Utilities/QuantityLimits.php#L177

Which is this method get_draft_order_id https://github.com/woocommerce/woocommerce-blocks/blob/95e460409816f5dcd896cd81c5c7ab100ef5f817/src/StoreApi/Utilities/DraftOrderTrait.php#L15

Error logs

Just encountered this fatal error when inserting a Woocommerce Highlighted Product Block.

  1. Create a page
  2. Insert a Woo Hightlight Product Block
  3. Get error.
[15-Dec-2022 15:50:55 UTC] PHP Fatal error:  Uncaught Error: Call to undefined function wc_empty_cart() in /Users/jm/local/iab/app/public/wp-content/plugins/woocommerce/includes/class-wc-session-handler.php:372
Stack trace:
#0 /Users/jm/local/iab/app/public/wp-content/plugins/woocommerce/includes/class-wc-session-handler.php(363): WC_Session_Handler->forget_session()
#1 /Users/jm/local/iab/app/public/wp-content/plugins/woocommerce/includes/class-wc-session-handler.php(99): WC_Session_Handler->destroy_session()
#2 /Users/jm/local/iab/app/public/wp-content/plugins/woocommerce/includes/class-wc-session-handler.php(71): WC_Session_Handler->init_session_cookie()
#3 /Users/jm/local/iab/app/public/wp-content/plugins/woocommerce/includes/class-woocommerce.php(862): WC_Session_Handler->init()
#4 /Users/jm/local/iab/app/public/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Utilities/DraftOrderTrait.php(17): WooCommerce->initialize_session()
#5 /Users/jm/local/iab/app/public/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Utilities/QuantityLimits.php(177): Automattic\WooCommerce\StoreApi\Utilities\QuantityLimits->get_draft_order_id()
#6 /Users/jm/local/iab/app/public/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Utilities/QuantityLimits.php(148): Automattic\WooCommerce\StoreApi\Utilities\QuantityLimits->get_remaining_stock(Object(WC_Product_Variable))
#7 /Users/jm/local/iab/app/public/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Utilities/QuantityLimits.php(55): Automattic\WooCommerce\StoreApi\Utilities\QuantityLimits->get_product_quantity_limit(Object(WC_Product_Variable))
#8 /Users/jm/local/iab/app/public/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Schemas/V1/ProductSchema.php(481): Automattic\WooCommerce\StoreApi\Utilities\QuantityLimits->get_add_to_cart_limits(Object(WC_Product_Variable))
#9 /Users/jm/local/iab/app/public/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/V1/Products.php(67): Automattic\WooCommerce\StoreApi\Schemas\V1\ProductSchema->get_item_response(Object(WC_Product_Variable))
#10 /Users/jm/local/iab/app/public/wp-content/plugins/woocommerce/packages/woocommerce-blocks/src/StoreApi/Routes/V1/AbstractRoute.php(109): Automattic\WooCommerce\StoreApi\Routes\V1\Products->get_route_response(Object(WP_REST_Request))
#11 /Users/jm/local/iab/app/public/wp-includes/rest-api/class-wp-rest-server.php(1171): Automattic\WooCommerce\StoreApi\Routes\V1\AbstractRoute->get_response(Object(WP_REST_Request))
#12 /Users/jm/local/iab/app/public/wp-includes/rest-api/class-wp-rest-server.php(1018): WP_REST_Server->respond_to_request(Object(WP_REST_Request), '/wc/store/v1/pr...', Array, NULL)
#13 /Users/jm/local/iab/app/public/wp-includes/rest-api/class-wp-rest-server.php(442): WP_REST_Server->dispatch(Object(WP_REST_Request))
#14 /Users/jm/local/iab/app/public/wp-includes/rest-api.php(410): WP_REST_Server->serve_request('/wc/store/v1/pr...')
#15 /Users/jm/local/iab/app/public/wp-includes/class-wp-hook.php(308): rest_api_loaded(Object(WP))
#16 /Users/jm/local/iab/app/public/wp-includes/class-wp-hook.php(332): WP_Hook->apply_filters(NULL, Array)
#17 /Users/jm/local/iab/app/public/wp-includes/plugin.php(565): WP_Hook->do_action(Array)
#18 /Users/jm/local/iab/app/public/wp-includes/class-wp.php(399): do_action_ref_array('parse_request', Array)
#19 /Users/jm/local/iab/app/public/wp-includes/class-wp.php(780): WP->parse_request('')
#20 /Users/jm/local/iab/app/public/wp-includes/functions.php(1332): WP->main('')
#21 /Users/jm/local/iab/app/public/wp-blog-header.php(16): wp()
#22 /Users/jm/local/iab/app/public/index.php(17): require('/Users/jm/...')
#23 {main}
  thrown in /Users/jm/local/iab/app/public/wp-content/plugins/woocommerce/includes/class-wc-session-handler.php on line 372
Screenshot 2022-12-15 at 20 00 24
jmslbam commented 1 year ago

Oh I should have tagged @wavvves as he's the Automattic developer :)

So wc_empty_cart is only added on the front-end of a site See https://github.com/woocommerce/woocommerce/blob/trunk/plugins/woocommerce/includes/class-woocommerce.php#L546-L548 & then https://github.com/woocommerce/woocommerce/blob/trunk/plugins/woocommerce/includes/class-woocommerce.php#L615

Fix

I added include_once WC_ABSPATH . 'includes/wc-cart-functions.php'; to test if everything started to work here https://github.com/woocommerce/woocommerce/blob/trunk/plugins/woocommerce/includes/class-wc-session-handler.php#L372 and yes it did.

     /**
       * Forget all session data without destroying it.
       */
    public function forget_session() {
        wc_setcookie( $this->_cookie, '', time() - YEAR_IN_SECONDS, $this->use_secure_cookie(), true );

        // Just added this line to test, and indeed, the error went away
        // include_once WC_ABSPATH . 'includes/wc-cart-functions.php';

        // Adding ! is_admin() might be a easier and better solution, because this also fixes it and the session handler can be used everywhere.
        if( ! is_admin() ) {
            wc_empty_cart();
        }

        $this->_data        = array();
        $this->_dirty       = false;
        $this->_customer_id = $this->generate_customer_id();
    }

@wavvves want me to open a PR on Woocommerce repo with the !is_admin() fix?

jmslbam commented 1 year ago

And with "Woo Hightlight Product Block" I meant "Featured Products"

wavvves commented 1 year ago

Hi @jmslbam, I see a fix was already merged on the WooCommerce repo. Going to close this issue now, thank you for all the help investigating this.