authenticator = new Twokcs_Authenticator(); $this->exporter = new Twokcs_Products_Exporter(); $this->taxonomy_exporter = new Twokcs_Taxonomy_Exporter(); $this->variations_exporter = new Twokcs_Variations_Exporter(); $this->orders_handler = new Twokcs_Orders_Handler(); if (strpos(site_url(), 'localhost') !== false) { add_filter('http_request_args', [$this, 'allow_localhost_http_requests']); } add_action('rest_api_init', [$this, 'register_routes']); add_filter('rest_authentication_errors', [$this, 'check_rest_auth_error'], PHP_INT_MAX); add_filter('woocommerce_rest_check_permissions', [$this, 'check_wc_permission']); add_filter('woocommerce_rest_prepare_product_object', [$this, 'apply_discount_rules_pricing'], 10, 3); add_filter('woocommerce_rest_prepare_product_variation_object', [$this, 'apply_discount_rules_pricing'], 10, 3); } /** * Allow outbound HTTP requests on localhost during development. * * @param array $args HTTP request arguments. * @return array */ public function allow_localhost_http_requests($args) { $args['reject_unsafe_urls'] = false; return $args; } /** * Register Twokcs REST API routes. */ public function register_routes() { register_rest_route(Twokcs_Constants::REST_NAMESPACE, '/version', [ 'methods' => 'GET', 'callback' => [$this, 'api_version'], 'permission_callback' => [$this, 'check_permission'], ]); register_rest_route(Twokcs_Constants::REST_NAMESPACE, '/products', [ 'methods' => 'GET', 'callback' => [$this, 'products_list'], 'permission_callback' => [$this, 'check_permission'], ]); register_rest_route(Twokcs_Constants::REST_NAMESPACE, '/categories', [ 'methods' => 'GET', 'callback' => [$this, 'categories_list'], 'permission_callback' => [$this, 'check_permission'], ]); register_rest_route(Twokcs_Constants::REST_NAMESPACE, '/attributes', [ 'methods' => 'GET', 'callback' => [$this, 'attributes_list'], 'permission_callback' => [$this, 'check_permission'], ]); register_rest_route(Twokcs_Constants::REST_NAMESPACE, '/attribute-terms', [ 'methods' => 'GET', 'callback' => [$this, 'attribute_terms_list'], 'permission_callback' => [$this, 'check_permission'], ]); register_rest_route(Twokcs_Constants::REST_NAMESPACE, '/variants', [ 'methods' => 'GET', 'callback' => [$this, 'variants_list'], 'permission_callback' => [$this, 'check_permission'], ]); register_rest_route(Twokcs_Constants::REST_NAMESPACE, '/variant', [ 'methods' => 'GET', 'callback' => [$this, 'variant_by_id'], 'permission_callback' => [$this, 'check_permission'], ]); register_rest_route(Twokcs_Constants::REST_NAMESPACE, '/orders', [ 'methods' => 'POST', 'callback' => [$this, 'orders_create'], 'permission_callback' => [$this, 'check_permission'], ]); register_rest_route(Twokcs_Constants::REST_NAMESPACE, '/order', [ 'methods' => 'GET', 'callback' => [$this, 'order_track'], 'permission_callback' => [$this, 'check_permission'], ]); register_rest_route(Twokcs_Constants::REST_NAMESPACE, '/order/cancel', [ 'methods' => 'POST', 'callback' => [$this, 'order_cancel'], 'permission_callback' => [$this, 'check_permission'], ]); register_rest_route(Twokcs_Constants::REST_NAMESPACE, '/order/update', [ 'methods' => 'POST', 'callback' => [$this, 'order_update'], 'permission_callback' => [$this, 'check_permission'], ]); } /** * Permission callback for Twokcs REST routes. * * @return true|WP_Error */ public function check_permission() { return $this->authenticator->verify(); } /** * Bypass default REST authentication when Twokcs auth succeeds. * * @param WP_Error|null $result Existing authentication error. * @return WP_Error|null */ public function check_rest_auth_error($result) { if ($this->authenticator->verify() === true) { return null; } return $result; } /** * Grant WooCommerce REST permissions when Twokcs auth succeeds. * * @param bool $permission Existing permission result. * @return bool */ public function check_wc_permission($permission) { if ($this->authenticator->verify() === true) { return true; } return $permission; } /** * Apply Discount Rules for WooCommerce pricing to REST responses. * * @param WP_REST_Response $response REST response. * @param WC_Product $object Product or variation object. * @param WP_REST_Request $request Request object. * @return WP_REST_Response */ public function apply_discount_rules_pricing($response, $object, $request) { if (class_exists('Wdr\App\Controllers\ManageDiscount')) { $discount = new \Wdr\App\Controllers\ManageDiscount(); $prices = $discount->calculateInitialAndDiscountedPrice($object, 1); if (isset($prices['initial_price'])) { $response->data['regular_price'] = $prices['initial_price']; } if (isset($prices['discounted_price'])) { $response->data['sale_price'] = $prices['discounted_price']; $response->data['price'] = $prices['discounted_price']; } } return $response; } /** * Return the plugin version. * * @return WP_REST_Response */ public function api_version() { return new WP_REST_Response(['version' => Twokcs_Constants::VERSION], 200); } /** * Export paginated products. * * @param WP_REST_Request $request Request object. * @return WP_REST_Response|WP_Error */ public function products_list(WP_REST_Request $request) { return $this->exporter->export($request); } /** * Export paginated product categories. * * @param WP_REST_Request $request Request object. * @return WP_REST_Response|WP_Error */ public function categories_list(WP_REST_Request $request) { return $this->taxonomy_exporter->export_categories($request); } /** * Export paginated product attributes. * * @param WP_REST_Request $request Request object. * @return WP_REST_Response|WP_Error */ public function attributes_list(WP_REST_Request $request) { return $this->taxonomy_exporter->export_attributes($request); } /** * Export paginated attribute terms. * * @param WP_REST_Request $request Request object. * @return WP_REST_Response|WP_Error */ public function attribute_terms_list(WP_REST_Request $request) { return $this->taxonomy_exporter->export_attribute_terms($request); } /** * Export variants by product_ids or ids query parameter. * * @param WP_REST_Request $request Request object. * @return WP_REST_Response|WP_Error */ public function variants_list(WP_REST_Request $request) { return $this->variations_exporter->export($request); } /** * Export a single variant by ID. * * @param WP_REST_Request $request Request object. * @return WP_REST_Response|WP_Error */ public function variant_by_id(WP_REST_Request $request) { return $this->variations_exporter->export_by_id($request); } /** * Create a WooCommerce order. * * @param WP_REST_Request $request Request object. * @return WP_REST_Response|WP_Error */ public function orders_create(WP_REST_Request $request) { return $this->orders_handler->create($request); } /** * List WooCommerce orders with optional id, external_order_id, and status filters. * * @param WP_REST_Request $request Request object. * @return WP_REST_Response|WP_Error */ public function order_track(WP_REST_Request $request) { return $this->orders_handler->track($request); } /** * Cancel a 2khat WooCommerce order. * * @param WP_REST_Request $request Request object. * @return WP_REST_Response|WP_Error */ public function order_cancel(WP_REST_Request $request) { return $this->orders_handler->cancel($request); } /** * Update line items (quantities, additions, removals) of a 2khat order. * * @param WP_REST_Request $request Request object. * @return WP_REST_Response|WP_Error */ public function order_update(WP_REST_Request $request) { return $this->orders_handler->update($request); } }