在 WooCommerce 3.6 之后使用 REST API 管理购物车
自从 WooCommerce 3.6,不再为 REST API 请求加载一些前端函数和类。 继续阅读以了解如何在您的主题或插件中手动加载这些内容。
WooCommerce 3.6(2019 年 4 月 7 日发布)包括一些相当 重大变化 从发展的角度来看。 性能改进之一是 删除购物车 和其他 REST API 请求的前端代码。 从 3.6 开始,它们只为“前端”请求加载,即那些在您的网站上显示实际页面的请求。
这是一个值得改进的地方,但也有一个缺点:如果你有一个插件或一些自定义代码通过 REST API 与购物车或前端代码交互,你会突然发现它不再有效。
我们的 WooCommerce Quick View Pro 插件受到此问题的影响。 在该插件中,我们允许将产品从灯箱添加到购物车,我们使用 REST API 来实现这一点。 在不希望重写插件以使用替代方法(例如 AJAX)的情况下,我们找到了一种解决方法,这可能对其他插件开发人员有所帮助。
首先是一些好消息:WooCommerce 自动加载器负责包含在您的 REST 请求期间引用的任何类。 因此,即使购物车类不再包含在前面,如果您参考 WC_Cart
在您的代码中,然后自动加载器将为您加载它。
如果您使用诸如 wc_add_to_cart_message
,您需要单独包含购物车功能(/woocommerce/includes/wc-cart-functions.php
) 因为这个文件不会被自动加载。 而且由于购物车经常会创建通知(例如将商品添加到购物车),您可能也希望包含这些功能:
include_once WC_ABSPATH . 'includes/wc-cart-functions.php'; include_once WC_ABSPATH . 'includes/wc-notice-functions.php';
如果您的请求输出 WooCommerce 模板之一,您可能还需要模板挂钩文件:
include_once WC_ABSPATH . 'includes/wc-template-hooks.php';
接下来,我们需要初始化会话类:
if ( null === WC()->session ) { $session_class = apply_filters( 'woocommerce_session_handler', 'WC_Session_Handler' ); WC()->session = new $session_class(); WC()->session->init(); }
这段代码基本上是 WooCommerce 本身在 WooCommerce->init()
.
接下来,我们需要初始化 customer 和 cart 对象,因为不再为 REST 请求创建这些对象:
if ( null === WC()->customer ) { WC()->customer = new WC_Customer( get_current_user_id(), true ); } if ( null === WC()->cart ) { WC()->cart = new WC_Cart(); }
最后,我们需要从会话中加载现有的购物车。 尽管此时我们已经创建了购物车,但购物车的内容将是空的。
推车存储由 WC_Cart_Session
班级。 如果您查看代码,您会看到购物车的初始读取是在 wp_loaded
钩。 当我们执行一个 REST 请求时,该请求在 parse_request
这个钩子会有 已经发生.
所以我们需要强制购物车从会话中刷新其内容。 最简单的方法是调用 get_cart()
方法:
WC()->cart->get_cart();
差不多就是这样。 在我们的快速查看插件中,我们把它放在一个 check_prerequisites()
在我们的 REST 请求开始时运行的函数。 这是我们使用的代码:
/** * Check any prerequisites for our REST request. */ private function check_prerequisites() { if ( defined( 'WC_ABSPATH' ) ) { // WC 3.6+ - Cart and other frontend functions are not included for REST requests. include_once WC_ABSPATH . 'includes/wc-cart-functions.php'; include_once WC_ABSPATH . 'includes/wc-notice-functions.php'; include_once WC_ABSPATH . 'includes/wc-template-hooks.php'; } if ( null === WC()->session ) { $session_class = apply_filters( 'woocommerce_session_handler', 'WC_Session_Handler' ); WC()->session = new $session_class(); WC()->session->init(); } if ( null === WC()->customer ) { WC()->customer = new WC_Customer( get_current_user_id(), true ); } if ( null === WC()->cart ) { WC()->cart = new WC_Cart(); // We need to force a refresh of the cart contents from session here (cart contents are normally refreshed on wp_loaded, which has already happened by this point). WC()->cart->get_cart(); } }
希望这个对你有帮助。 随着新版本 WooCommerce 的发布,我会尽量让这篇文章保持最新。 如果您在下面的评论中发现任何问题或对代码有任何改进,请告诉我。