wcpos_request = $request; add_filter( 'woocommerce_rest_prepare_product_brand', array( $this, 'wcpos_product_brands_response' ), 10, 3 ); add_filter( 'woocommerce_rest_product_brand_query', array( $this, 'wcpos_product_brand_query' ), 10, 2 ); /* * Check if the request is for all brands and if the 'posts_per_page' is set to -1. * Optimised query for getting all brand IDs. */ if ( -1 == $request->get_param( 'posts_per_page' ) && null !== $request->get_param( 'fields' ) ) { return $this->wcpos_get_all_posts( $request ); } return $dispatch_result; } /** * Filter the brand response. * * @param WP_REST_Response $response The response object. * @param object $item The original term object. * @param WP_REST_Request $request Request object. * * @return WP_REST_Response $response The response object. */ public function wcpos_product_brands_response( WP_REST_Response $response, object $item, WP_REST_Request $request ): WP_REST_Response { $data = $response->get_data(); // Make sure the term has a uuid. $data['uuid'] = $this->get_term_uuid( $item ); // Reset the new response data. $response->set_data( $data ); return $response; } /** * Filter the brand query. * * @param array $args Query arguments. * @param WP_REST_Request $request Request object. */ public function wcpos_product_brand_query( array $args, WP_REST_Request $request ): array { // Check for wcpos_include/wcpos_exclude parameter. if ( isset( $request['wcpos_include'] ) || isset( $request['wcpos_exclude'] ) ) { // Add a custom WHERE clause to the query. add_filter( 'terms_clauses', array( $this, 'wcpos_terms_clauses_include_exclude' ), 10, 3 ); } return $args; } /** * Filters the terms query SQL clauses. * * @param string[] $clauses Associative array of the clauses for the query. * @param string[] $taxonomies An array of taxonomy names. * @param array $args An array of term query arguments. * * @return string[] $clauses */ public function wcpos_terms_clauses_include_exclude( array $clauses, array $taxonomies, array $args ) { global $wpdb; // Handle 'wcpos_include'. if ( ! empty( $this->wcpos_request['wcpos_include'] ) ) { $include_ids = array_map( 'intval', $this->wcpos_request['wcpos_include'] ); $ids_format = implode( ',', array_fill( 0, \count( $include_ids ), '%d' ) ); $clauses['where'] .= $wpdb->prepare( " AND t.term_id IN ($ids_format) ", $include_ids ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $ids_format is a safe placeholder string. } // Handle 'wcpos_exclude'. if ( ! empty( $this->wcpos_request['wcpos_exclude'] ) ) { $exclude_ids = array_map( 'intval', $this->wcpos_request['wcpos_exclude'] ); $ids_format = implode( ',', array_fill( 0, \count( $exclude_ids ), '%d' ) ); $clauses['where'] .= $wpdb->prepare( " AND t.term_id NOT IN ($ids_format) ", $exclude_ids ); // phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared -- $ids_format is a safe placeholder string. } return $clauses; } /** * Returns array of all product brand ids. * * @param WP_REST_Request $request Full details about the request. * * @return WP_Error|WP_REST_Response */ public function wcpos_get_all_posts( $request ) { // Start timing execution. $start_time = microtime( true ); $modified_after = $request->get_param( 'modified_after' ); $args = array( 'taxonomy' => 'product_brand', 'hide_empty' => false, 'fields' => 'ids', ); try { /** * Get all term IDs for the taxonomy. * * @TODO - terms don't have a modified date, it would be good to add a term_meta for last_update * - ideally WooCommerce would provide a modified_after filter for terms * - for now we'll just return empty for modified terms */ $results = $modified_after ? array() : get_terms( $args ); // Format the response. $formatted_results = array_map( function ( $id ) { return array( 'id' => (int) $id ); }, $results ); // Get the total number of brands for the given criteria. $total = \count( $formatted_results ); // Collect execution time and server load. $execution_time = microtime( true ) - $start_time; $execution_time_ms = number_format( $execution_time * 1000, 2 ); $server_load = $this->get_server_load(); $response = rest_ensure_response( $formatted_results ); $response->header( 'X-WP-Total', (string) $total ); $response->header( 'X-Execution-Time', $execution_time_ms . ' ms' ); $response->header( 'X-Server-Load', json_encode( $server_load ) ); return $response; } catch ( Exception $e ) { Logger::log( 'Error fetching product brand IDs: ' . $e->getMessage() ); return new \WP_Error( 'woocommerce_pos_rest_cannot_fetch', 'Error fetching product brand IDs.', array( 'status' => 500 ) ); } } }