Search code examples
wordpresswoocommercewordpress-rest-apiwoocommerce-rest-api

Wordpress WooCommerce Rest-API override item schema


I'm trying to use WooCommerce with fractional stock quantities with the plugin [Quantities and Units for WooCommerce][1] and it works pretty good. My only Problem is, that the WooCommerce API rejects quantities with decimal points because the item schema in the Rest Products Controller (class-wc-rest-products-controller.php) defines it as integer (validation).

How can I override this schema in a plugin without modifieing the WooCommerce source?


Solution

  • The solution is, to create an subclass of the required WooCommerce Controller, reattach the rest route and override the get_item_schema function.

    For example (override the quantity type to number instead of integer):

    class WC_REST_Products_Quantity_Controller extends WC_REST_Products_Controller {
        public function __construct() {
            parent::__construct();
    
            add_action( 'rest_api_init', array( $this, 'register_rest_routes' ), 8 );
        }
    
        /**
         * Register the routes for products.
         */
        public function register_rest_routes() {
            register_rest_route(
                $this->namespace, '/' . $this->rest_base . '/(?P<id>[\d]+)', array(
                    'args'   => array(
                        'id' => array(
                            'description' => __( 'Unique identifier for the resource.', 'woocommerce' ),
                            'type'        => 'integer',
                        ),
                    ),
                    array(
                        'methods'             => WP_REST_Server::EDITABLE,
                        'callback'            => array( $this, 'update_item' ),
                        'permission_callback' => array( $this, 'update_item_permissions_check' ),
                        'args'                => $this->get_endpoint_args_for_item_schema( WP_REST_Server::EDITABLE ),
                    ),
                    'schema' => array( $this, 'get_public_item_schema' ),
                )
            );
        }
    
        public function update_item($request) {
            return parent::update_item($request);
        }
        public function get_item_schema()
        {
            $res = parent::get_item_schema();
    
            $res["properties"]["stock_quantity"]["type"] = "number";
    
            return $res;
        }
    }
    
    new WC_REST_Products_Quantity_Controller();