admin管理员组

文章数量:1122832

I'm trying to add an item to cart inside a WordPress REST API.

This is my code so far:

add_action( 'rest_api_init', function () {
  register_rest_route( 'lufc/v1', '/add-to-cart', array(
    'methods' => 'GET',
    'callback' => [ 'add_to_cart' ],
  ) );
} );

function add_to_cart() {
  global $woocommerce;
  $woocommerce->cart->add_to_cart( 15 );
  die();
}

But it fails because $woocommerce->cart is always null.

Any suggestions?

I'm trying to add an item to cart inside a WordPress REST API.

This is my code so far:

add_action( 'rest_api_init', function () {
  register_rest_route( 'lufc/v1', '/add-to-cart', array(
    'methods' => 'GET',
    'callback' => [ 'add_to_cart' ],
  ) );
} );

function add_to_cart() {
  global $woocommerce;
  $woocommerce->cart->add_to_cart( 15 );
  die();
}

But it fails because $woocommerce->cart is always null.

Any suggestions?

Share Improve this question asked Jun 25, 2019 at 16:07 Jack RobsonJack Robson 1351 silver badge4 bronze badges
Add a comment  | 

2 Answers 2

Reset to default 9

Yes, this is true because WooCommerce cart is only initialized on the front-end (or if it's a front-end request):

But it fails because $woocommerce->cart is always null.

So in WooCommerce 3.6.4 (current release as of writing) or later, you can manually initialize the cart like so:

// Load cart functions which are loaded only on the front-end.
include_once WC_ABSPATH . 'includes/wc-cart-functions.php';
include_once WC_ABSPATH . 'includes/class-wc-cart.php';

// wc_load_cart() does two things:
// 1. Initialize the customer and cart objects and setup customer saving on shutdown.
// 2. Initialize the session class.
if ( is_null( WC()->cart ) ) {
    wc_load_cart();
}

So your add_to_cart() might look like so:

function add_to_cart() {
    defined( 'WC_ABSPATH' ) || exit;

    // Load cart functions which are loaded only on the front-end.
    include_once WC_ABSPATH . 'includes/wc-cart-functions.php';
    include_once WC_ABSPATH . 'includes/class-wc-cart.php';

    if ( is_null( WC()->cart ) ) {
        wc_load_cart();
    }

    // I'm simply returning the cart item key. But you can return anything you want...
    return WC()->cart->add_to_cart( 15 );
}

Notes

  1. For older WooCommerce 3.6.x releases, this article might help you.

  2. As you could see, the above code is simple (and it worked well for me); however, there's actually an existing solution that you can try: CoCart.

  3. You should always use WC() to access the global $woocommerce variable/object.

  4. I'm assuming this is just a typo in the question: 'callback' => [ 'add_to_cart' ] because that results in an error, and it should be one of these:

    'callback' => 'add_to_cart'
    'callback' => [ $this, 'add_to_cart' ]
    'callback' => [ $my_class, 'add_to_cart' ]
    'callback' => [ 'My_Class', 'add_to_cart' ]
    

For any future travelers an update on Sally's answer for WooCommerce 9.0.0 and up:

function handle_rest_route( WP_REST_Request $request) {
  defined( 'WC_ABSPATH' ) || exit;

  if ( is_null( WC()->cart ) ) {
    /**
     * wc_load_cart() will:
     * - initialize session
     * - initialize customer data from session
     * - initialize empty cart
     *
     * Note, wc()->customer is session based. 
     *  Changes to customer data via this property are 
     *  not persisted to the database automatically.
     */
    wc_load_cart();

    /**
     * wc_load_cart() will initialize the cart with 
     *  a new session, meaning we don't actually
     *  get any existing session data. To have it load
     *  any existing cart session, we call this.
     */
    WC()->cart->get_cart_from_session();
  }

  // If you send your params along with the request in body
  //  you can get them like this.
  $product_id = $request->get_param( 'product_id' );
  $quantity = $request->get_param( 'quantity' );

  // Finally we can now use the cart.
  try {
    WC()->cart->add_to_cart( $product_id, $quantity );
  } catch ( \Exception $e ) {
    return new WP_REST_Response( [ 'success' => false, 'message' => $e->getMessage() ], 500 );
  }

  return new WP_REST_Response( [ 'success' => true ], 200 );
}

There's no need to include cart functions because wc_load_cart() already does that for you. Finally as reminder, if you work with the REST API, to include the nonce wp_create_nonce( 'wp_rest' ) under header X-WP-Nonce.

本文标签: pluginswoocommercegtcart is null inside WordPress Rest API