query_vars['adscaleCategories'] = sanitize_key( wp_unslash( $_GET['adscaleCategories'] ) ); } // make sure endpoint request if ( ! isset( $wp->query_vars['adscaleCategories'] ) ) { return; } try { ob_start(); // Error handler self::setErrorHandler(); Helper::nocache_headers(); // Check Request (Guards) self::checkRequest(); ob_end_clean(); // Handle Request self::handleRequest(); // Default error Helper::send_response_formatted_error( self::makeErrorBody() ); } catch ( PluginApiException $ex ) { Helper::send_response_formatted_error( self::makeErrorBody( $ex->getApiErrorCode(), $ex->getMessage(), $ex->getApiErrorDetails() ) ); } catch ( \Exception $ex ) { Helper::send_response_formatted_error( self::makeErrorBody( $ex->getCode(), $ex->getMessage() ) ); } } public static function checkRequest() { parent::checkRequest(); self::initParams(); // last id from the previous page if ( ! self::checkParamAfter() ) { Helper::send_response_formatted_error( self::makeErrorBody('I001','Invalid argument value', 'after' ) ); } // Number of items per page, min if ( ! self::checkParamLimitForMin() ) { Helper::send_response_formatted_error( self::makeErrorBody('I001','Invalid argument value', 'limit' ) ); } // Number of items per page, max if ( ! self::checkParamLimitForMax() ) { Helper::send_response_formatted_error( self::makeErrorBody('I001','Invalid argument value', 'limit' ) ); } } public static function initParams() { self::$requestParams['after'] = Helper::get_post_body_data_value( 'after' ,'absint'); self::$requestParams['limit'] = Helper::get_post_body_data_value( 'limit' , 'absint' ); self::$requestParams['ids'] = Helper::get_post_body_data_value( 'ids' ); // Set default params if not exists if ( null === self::$requestParams['after'] ) { self::$requestParams['after'] = 0; } if ( null === self::$requestParams['limit'] ) { self::$requestParams['limit'] = self::$defaultLimit; } if ( null === self::$requestParams['ids'] ) { self::$requestParams['ids'] = self::$defaultIds; } // Params Type Hinting self::$requestParams['after'] = (int) self::$requestParams['after']; self::$requestParams['limit'] = (int) self::$requestParams['limit']; self::$requestParams['ids'] = self::resolveIds( self::$requestParams['ids'] ); } /** * Last id from the previous page, check if is valid * * @return bool is valid */ public static function checkParamAfter() { return self::$requestParams['after'] >= 0; } /** * Check min Number of items per page * * @return bool is valid */ public static function checkParamLimitForMin() { return self::$requestParams['limit'] > 0; } /** * Check max Number of items per page * * @return bool is valid */ public static function checkParamLimitForMax() { return self::$requestParams['limit'] <= self::$maxLimit; } /** * Resolve Ids * * @param mixed $ids * * @return array */ private static function resolveIds( $ids ) { if ( is_float( $ids ) ) { Helper::send_response_formatted_error( self::makeErrorBody('I001','Invalid argument value', 'ids' ) ); } if ( is_numeric( $ids ) ) { $ids = [ (int) $ids ]; } if ( ! is_array( $ids ) ) { Helper::send_response_formatted_error( self::makeErrorBody('I001','Invalid argument value', 'ids' ) ); } $filteredIds = []; foreach ( $ids as $id ) { if ( ! is_numeric( $id ) || is_float( $id ) ) { Helper::send_response_formatted_error( self::makeErrorBody('I001','Invalid argument value', 'ids' ) ); } $filteredIds[] = (int) $id; } return $filteredIds; } /** * Handle API request * */ public static function handleRequest() { $categories_data = []; $args = [ 'taxonomy' => [ 'product_cat' ], 'hide_empty' => false, 'orderby' => 'id', 'order' => 'ASC', ]; if ( self::$requestParams['limit'] ) { $args['number'] = self::$requestParams['limit']; } if ( self::$requestParams['ids'] ) { $args['include'] = self::$requestParams['ids']; } if ( self::$requestParams['after'] ) { $args['_adscale_after'] = self::$requestParams['after']; // added custom filter } add_filter( 'terms_clauses', [ self::class, 'queryFilter' ], 777, 3 ); $terms = get_terms( $args ); remove_filter( 'terms_clauses', [ self::class, 'queryFilter' ], 777 ); if ( is_wp_error( $terms ) ) { Helper::send_response_formatted_error( self::makeErrorBody('S000','Unknown error', 'A product categories taxonomy could not be found' ) ); } foreach ( $terms as $term ) { $categories_data[] = self::getCategoryData( $term ); } Helper::send_response_formatted_success( [ 'categories' => $categories_data, ] ); } /** * Filters the terms query SQL clauses. * * @param string[] $pieces Array of query SQL clauses. * @param string[] $taxonomies An array of taxonomy names. * @param array $args An array of term query arguments. * * @return string[] $pieces Filtered Array of query SQL clauses. */ public static function queryFilter( $pieces, $taxonomies, $args ) { global $wpdb; $pieces['orderby']= 'ORDER BY t.term_id'; if ( ! isset( $args['_adscale_after'] ) ) { return $pieces; } $pieces['where'] .= ' AND ' . $wpdb->prepare( 't.term_id > %d', (int) $args['_adscale_after'] ); return $pieces; } /** * Get the product category data for the given term * * @param \WP_Term $term product category term * * @return array */ public static function getCategoryData( $term ) { try { if ( is_wp_error( $term ) || is_null( $term ) ) { Helper::send_response_formatted_error( self::makeErrorBody('S000','A product category could not be found' ) ); } $term_id = (int) $term->term_id; // Get category image url $image_url = ''; $image_id = get_term_meta( $term_id, 'thumbnail_id', true ); if ( $image_id ) { $image_url = wp_get_attachment_url( $image_id ); } // Get category url $term_url = get_term_link( $term, $taxonomy = '' ); if ( is_wp_error( $term ) ) { Helper::send_response_formatted_error( self::makeErrorBody('S000','A product category url could not be found' ) ); } // Get products ids for category $products_ids = get_posts( [ 'post_type' => 'product', 'posts_per_page' => - 1, 'post_status' => 'publish', 'fields' => 'ids', 'orderby' => 'ID', 'order' => 'ASC', 'ignore_sticky_posts' => 1, 'tax_query' => [ 'relation' => 'AND', [ 'taxonomy' => 'product_cat', 'field' => 'term_id', 'terms' => $term_id, ], ], ] ); // Get children category ids for current category $args = [ 'taxonomy' => [ 'product_cat' ], 'hide_empty' => false, 'orderby' => 'id', 'order' => 'ASC', 'child_of' => $term_id, 'fields' => 'ids', ]; $children_ids = get_terms( $args ); if ( is_wp_error( $children_ids ) ) { Helper::send_response_formatted_error( self::makeErrorBody('S000','Error getting the product category children' ) ); } return [ 'id' => $term_id, 'title' => $term->name, 'url' => $term_url, 'keywords' => '', 'image_url' => $image_url ? esc_url( $image_url ) : '', 'products' => $products_ids, 'parent_id' => $term->parent, 'children_ids' => $children_ids, ]; } catch ( \Exception $ex ) { Helper::send_response_formatted_error( self::makeErrorBody('S000','Unknown error', $ex->getMessage() ) ); } } }