JezK
Edit File: ProductControllerV2.php
<?php namespace WeDevs\Dokan\REST; use WP_Error; use WP_REST_Response; use WP_REST_Server; use WP_REST_Request; use WeDevs\Dokan\ProductCategory\Helper; /** * Products API Controller V2 * * @package dokan * * @author weDevs <info@wedevs.com> */ class ProductControllerV2 extends ProductController { /** * Endpoint namespace * * @var string */ protected $namespace = 'dokan/v2'; /** * Class Constructor. * * @since 4.1.3 * * @return void */ public function __construct() { parent::__construct(); add_filter( 'dokan_rest_product_listing_exclude_type', [ $this, 'reset_exclude_product_type' ], 99, 2 ); } /** * Register all routes related with stores * * @since 3.7.10 * * @return void */ public function register_routes() { parent::register_routes(); register_rest_route( $this->namespace, '/' . $this->base, [ [ 'methods' => WP_REST_Server::READABLE, 'callback' => [ $this, 'get_items' ], 'permission_callback' => [ $this, 'get_product_permissions_check' ], 'args' => $this->get_collection_params(), ], 'schema' => [ $this, 'get_item_schema' ], ] ); register_rest_route( $this->namespace, '/' . $this->base . '/filter-by-data', [ [ 'methods' => WP_REST_Server::READABLE, 'callback' => [ $this, 'get_items' ], 'permission_callback' => [ $this, 'get_product_permissions_check' ], ], 'schema' => [ $this, 'get_filter_data_schema' ], ] ); } /** * Saves product. * * @since 3.7.16 * * @param WP_REST_Request $request * * @return void */ public function create_item( $request ) { $response = parent::create_item( $request ); $this->set_chosen_categories( $response ); return $response; } /** * Updates product. * * @since 3.7.16 * * @param WP_REST_Request $request * * @return void */ public function update_item( $request ) { $response = parent::update_item( $request ); $this->set_chosen_categories( $response ); return $response; } /** * Save chosen category to database. * * @param WP_Error|WP_REST_Response $response * * @return void */ private function set_chosen_categories( $response ) { if ( ! is_wp_error( $response ) ) { $product = $response->get_data(); $chosen_cat = ! empty( $request['chosen_cat'] ) && is_array( $request['chosen_cat'] ) ? array_map( 'absint', $request['chosen_cat'] ) : []; $product['chosen_cat'] = $chosen_cat; $response->set_data( $product ); Helper::generate_and_set_chosen_categories( $product['id'], $chosen_cat ); } } /** * Product API query parameters collections. * * @since 3.7.10 * * @return array Query parameters. */ public function get_collection_params() { $params = parent::get_collection_params(); $params['author'] = array( 'description' => __( 'Products author id', 'dokan-lite' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', 'required' => false, ); $params['post_status'] = array( 'description' => __( 'Product status publish, pending, draft etc.', 'dokan-lite' ), 'type' => 'array', 'sanitize_callback' => 'wc_clean', 'validate_callback' => 'rest_validate_request_arg', 'required' => false, ); $params['date'] = array( 'description' => __( 'Products publish month', 'dokan-lite' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', 'required' => false, ); $params['product_cat'] = array( 'description' => __( 'Products category.', 'dokan-lite' ), 'type' => 'integer', 'sanitize_callback' => 'absint', 'validate_callback' => 'rest_validate_request_arg', 'required' => false, ); $params['product_type'] = array( 'description' => __( 'Products type all, simple, variable, grouped product etc.', 'dokan-lite' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', 'required' => false, ); $params['stock_status'] = array( 'description' => __( 'Products stock status in stock or out of stock.', 'dokan-lite' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', 'required' => false, ); $params['filter_by_other'] = array( 'description' => __( 'Best selling, featured products etc.', 'dokan-lite' ), 'type' => 'string', 'sanitize_callback' => 'sanitize_text_field', 'validate_callback' => 'rest_validate_request_arg', 'required' => false, ); $params['include'] = array( 'description' => __( 'Limit result set to specific ids.', 'dokan-lite' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), 'sanitize_callback' => 'wp_parse_id_list', ); $params['exclude'] = array( 'description' => __( 'Ensure result set excludes specific IDs.', 'dokan-lite' ), 'type' => 'array', 'items' => array( 'type' => 'integer', ), 'default' => array(), 'sanitize_callback' => 'wp_parse_id_list', ); $params['include_variations'] = array( 'description' => __( 'If true matched product variations will be added to the collection', 'dokan-lite' ), 'type' => 'boolean', 'default' => false, ); return $params; } /** * Returns data by which products can be filtered. * * @since 3.7.10 * * @return array */ public function get_product_filter_by_data() { global $wp_locale; $months = dokan_get_products_listing_months_for_vendor( dokan_get_current_user_id() ); foreach ( $months as $key => $arc_row ) { $month = zeroise( $arc_row->month, 2 ); // translators: 1: month name, 2: 4-digit year $months [ $key ]->title = sprintf( esc_html__( '%1$s %2$d', 'dokan-lite' ), esc_html( $wp_locale->get_month( $month ) ), esc_html( $arc_row->year ) ); } return [ 'allDates' => $months, ]; } /** * Preparing query parameters array to fetch products from database. * * @param WP_REST_Request $request * * @return array */ protected function prepare_objects_query( $request ) { $args = parent::prepare_objects_query( $request ); unset( $args['author'] ); $args = array_merge( $args, array( 'posts_per_page' => isset( $request['per_page'] ) ? $request['per_page'] : 10, 'paged' => isset( $request['page'] ) ? $request['page'] : 1, 'orderby' => isset( $request['orderby'] ) ? $request['orderby'] : 'date', 'post_type' => 'product', 'date_query' => [], 'tax_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_tax_query array( 'taxonomy' => 'product_type', 'field' => 'slug', 'terms' => apply_filters( 'dokan_rest_product_listing_exclude_type', array(), $request ), 'operator' => 'NOT IN', ), ), ) ); $stock_statuses = apply_filters( 'dokan_product_stock_statuses', [ 'instock', 'outofstock' ] ); $product_types = apply_filters( 'dokan_product_types', [ 'simple' => __( 'Simple', 'dokan-lite' ) ] ); // If any vendor it trying to access other products then we need to replace author id by current user id. if ( ! current_user_can( dokan_admin_menu_capability() ) ) { $args['author'] = dokan_get_current_user_id(); } elseif ( $request->get_param( 'author' ) ) { $args['author'] = $request->get_param( 'author' ); } // Pagination page number. if ( $request->get_param( 'page' ) ) { $args['paged'] = $request->get_param( 'page' ); } // Products publish month. if ( $request->get_param( 'date' ) ) { $args['m'] = $request->get_param( 'date' ); } // Products category. if ( $request->get_param( 'product_cat' ) && intval( $request->get_param( 'product_cat' ) ) !== -1 ) { $args['tax_query'][] = array( 'taxonomy' => 'product_cat', 'field' => 'id', 'terms' => intval( $request->get_param( 'product_cat' ) ), 'include_children' => false, ); } // Products type. if ( $request->get_param( 'product_type' ) ) { $product_type = $request->get_param( 'product_type' ); if ( array_key_exists( $product_type, $product_types ) ) { $args['tax_query'][] = [ 'taxonomy' => 'product_type', 'field' => 'slug', 'terms' => $product_type, ]; } } // Product stock status. if ( isset( $request['stock_status'] ) && in_array( $request['stock_status'], $stock_statuses, true ) ) { $args['meta_query'][] = array( 'key' => '_stock_status', 'value' => sanitize_text_field( wp_unslash( $request['stock_status'] ) ), 'compare' => ' = ', ); } // Include variations but exclude parent variable products when requested. if ( isset( $request['include_variations'] ) && true === wc_string_to_bool( $request['include_variations'] ) ) { $args['post_type'] = [ $this->post_type, 'product_variation' ]; // Exclude parent variable products so only variations (and other non-variable products) are included. // Variations are a different post type and won't be affected by this taxonomy filter. $args['tax_query'][] = array( 'taxonomy' => 'product_type', 'field' => 'slug', 'terms' => array( 'variable' ), 'operator' => 'NOT IN', ); } return apply_filters( 'dokan_rest_pre_product_listing_args', $args, $request ); } /** * Returns filter data items schema. * * @since DOKAN_LITE * * @return array array of the schema. */ public function get_filter_data_schema() { return array( '$schema' => 'http://json-schema.org/draft-04/schema#', 'title' => 'filter-by-data', 'type' => 'object', 'properties' => array( 'allDates' => array( 'description' => esc_html__( 'All product created months.', 'dokan-lite' ), 'type' => 'array', 'readonly' => true, 'items' => array( 'type' => 'object', 'properties' => array( 'year' => array( 'description' => esc_html__( 'Product publish year.', 'dokan-lite' ), 'type' => 'integer', ), 'month' => array( 'description' => esc_html__( 'Product publish month.', 'dokan-lite' ), 'type' => 'integer', ), 'title' => array( 'description' => esc_html__( 'Product publish month and year full title.', 'dokan-lite' ), 'type' => 'string', ), ), ), ), ), ); } /** * Reset exclude product type. * * @since 4.1.3 * * @param array $exclude_product_type Exclude product type. * @param WP_REST_Request $request Request object. * * @return array */ public function reset_exclude_product_type( $exclude_product_type, $request ) { $exclude_product_type = apply_filters( 'dokan_product_listing_exclude_type', $exclude_product_type ); $product_type = $request->get_param( 'product_type' ); if ( 'all' === $product_type ) { $exclude_product_type = []; } return $exclude_product_type; } }