I am trying to prepare an API for the WooCommerce shopping cart. My issue is that for certain products, if there is already a product in the cart and the product I am trying to add does not have stock management (i.e., the ‘manage stock’ option is disabled), I cannot add the new product to the cart. It seems to prevent me from adding products without stock tracking if there is already an item in the cart.
My code :
index.php:
<?php
/*
Plugin Name: Umut API
Description: WooCommerce API deneme eklentisi.
Version: 1.0
Author: Umut
Text Domain: @@@
Domain Path: /lang
*/
require_once (__DIR__).'/Controllers/CartController.php';
add_filter('woocommerce_rest_api_get_rest_namespaces', 'woo_custom_api');
function woo_custom_api( $controllers ) {
$controllers['wc/v3']['cart'] = 'CartController';
return $controllers;
}
?>
Controllers/WC_REST_API_Controller.php :
<?php
const PATH = ABSPATH . 'wp-content/plugins/woocommerce/includes/rest-api/Controllers/Version3/';
include_once PATH . 'class-wc-rest-controller.php';
include_once PATH . 'class-wc-rest-posts-controller.php';
include_once ABSPATH . 'wp-content/plugins/woocommerce/includes/wc-cart-functions.php';
abstract class WC_REST_API_Controller extends WC_REST_Posts_Controller{
const NAMESPACE = 'wc/v3';
protected $post_type = 'post';
public abstract function define_route($method, $callback, $arg);
}
?>
Controllers/CartController.php :
<?php
const PLUGINS_DIR = ABSPATH . 'wp-content/plugins/';
require_once (__DIR__).'/WC_REST_API_Controller.php';
// include PLUGINS_DIR . 'woocommerce/includes/class-wc-cart.php';
class CartController extends WC_REST_API_Controller{
public $endpoint = '/cart';
public function define_route( $method, $callback, $arg ) {
register_rest_route(
parent::NAMESPACE,
$this->endpoint . $arg,
[
'methods' => $method,
'callback' => $callback,
'permission_callback' => [ $this, 'get_items_permissions_check' ],
]
);
}
public function register_routes() {
$this->define_route('GET' , [ $this, 'getCart' ] , '/get/user_id/(?P<userID>d+)' );
$this->define_route('PATCH' , [ $this, 'updateCart' ] , '/updateCart/user_id/(?P<userID>d+)/product_id/(?P<productID>d+)/quantity/(?P<quantity>d+)' );
$this->define_route('DELETE', [ $this, 'deleteProductInCart' ] , '/delete/user_id/(?P<userID>d+)/product_id/(?P<productID>d+)/quantity/(?P<quantity>d+)' );
$this->define_route('DELETE', [ $this, 'deleteAllProductsInCart' ] , '/delete/user_id/(?P<userID>d+)' );
}
public function getCart( $request ) {
$userID = json_decode( $request->get_param('userID') );
$metaKey = '_woocommerce_persistent_cart_' . get_current_blog_id() ;
$cartMeta = get_user_meta( $userID, $metaKey );
$cartMeta = $cartMeta[0][ 'cart' ];
if (count( $cartMeta ) < 1) {
return [ 'status' => false, 'message' => 'Shopping cart is empty', 'cart' => null ];
}
$cart = [];
foreach ($cartMeta as $item) {
$id = 0;
if ($item[ 'variation_id' ] !== 0) {
$id = $item[ 'variation_id' ];
}
else{
$id = $item[ 'product_id' ];
}
$currentProduct = wc_get_product( $id );
$currentProductData = $currentProduct->get_data();
$image = wp_get_attachment_image_src( get_post_thumbnail_id( $id ));
$currentProductData[ 'image' ] = $image;
$item[ 'productData' ] = $currentProductData;
$item[ 'final_total' ] = $item[ 'quantity' ] * $item[ 'productData' ][ 'price' ];
$cart[] = $item;
}
return ['status' => true, 'message' => 'Shopping cart is brought', 'cart' => $cart];
}
public function updateCart( $request ){
global $wpdb;
$userID = json_decode($request->get_param('userID'));
$quantity = json_decode($request->get_param('quantity'));
$productID = json_decode($request->get_param('productID'));
$currentProduct = false;
$isUserDefined = false;
$backOrderNotify = false;
$allUsers = get_users();
foreach ( $allUsers as $user ) {
if ( json_decode( $user->data->ID ) === $userID ) {
$isUserDefined = true;
break;
}
}
if ( ! $isUserDefined ){
return [ 'status' => false, 'message' => 0 ];
}
$currentProduct = wc_get_product( $productID );
if ( ! $currentProduct ) {
return [ 'status' => false, 'message' => 1 ];
}
$currentProductData = $currentProduct->get_data();
if ( $currentProductData[ 'backorders' ] === 'notify' ) {
$backOrderNotify = true;
if ( $currentProductData[ 'manage_stock' ] === true ) {
if ( $quantity < json_decode($currentProductData[ 'stock_quantity' ] ) ) {
$backOrderNotify = false;
}
}
else if( $currentProductData[ 'manage_stock' ] === false && json_decode($currentProductData[ 'parent_id' ] ) !== 0 ) {
$mainProduct = wc_get_product( json_decode($currentProductData[ 'parent_id' ] ) );
$mainProductData = $mainProduct->get_data();
if ( $mainProductData[ 'manage_stock' ] === true && $quantity < json_decode( $mainProductData[ 'stock_quantity' ] ) ) {
$backOrderNotify = false;
}
}
}
else if( $currentProductData[ 'backorders' ] === 'no' ) {
if ( $currentProductData[ 'stock_status' ] !== 'instock' ) {
return new WP_REST_Response( [ 'status' => false], 200 );
}
if ( $currentProductData[ 'manage_stock' ] === true ) {
if ( $quantity > json_decode($currentProductData[ 'stock_quantity' ] ) ) {
return new WP_REST_Response( [ 'status' => false], 200 );
}
}
else if( $currentProductData[ 'manage_stock' ] === false && json_decode($currentProductData[ 'parent_id' ] ) !== 0 ){
$mainProduct = wc_get_product( json_decode($currentProductData[ 'parent_id' ] ) );
$mainProductData = $mainProduct->get_data();
if ( $mainProductData[ 'backorders' ] === 'notify' ) {
$backOrderNotify = true;
}
else if( $mainProductData[ 'backorders' ] === 'no' ){
if ( $mainProductData[ 'stock_status' ] !== 'instock' ) {
return new WP_REST_Response( [ 'status' => false ], 200 );
}
if ( $mainProductData[ 'manage_stock' ] === true && $quantity > json_decode( $mainProductData[ 'stock_quantity' ] ) ) {
return new WP_REST_Response( [ 'status' => false ], 200 );
}
}
}
}
wc_load_cart();
WC()->cart->add_to_cart( $productID, $quantity );
return new WP_REST_Response( [ 'status' => true, 'message' => "Products successfully added to cart, new item quantity = $quantity"], 200 );
}
public function deleteProductInCart( $request ) {
$userID = $request->get_param( 'userID' );
$quantity = $request->get_param( 'quantity' );
$productID = $request->get_param( 'productID' );
return [ 'message' => 'deleteProductInCart', 'params' => [ 'userID' => $userID, 'productID' => $productID, 'quantity' => $quantity ] ];
}
public function deleteAllProductsInCart( $request ) {
$userID = $request->get_param( 'userID' );
return [ 'message' => 'deleteAllProductsInCart', 'params' => [ 'userID' => $userID ] ];
}
}
?>