在 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 的发布,我会尽量让这篇文章保持最新。 如果您在下面的评论中发现任何问题或对代码有任何改进,请告诉我。

查看  如何在冠状病毒危机中处理缺货的 WooCommerce 产品

类似文章