Automattic\WooCommerce\StoreApi\Utilities
ProductQuery::prepare_objects_query │ public │ WC 1.0
Prepare query args to pass to WP_Query for a REST API request.
Метод класса: ProductQuery{}
Хуков нет.
Возвращает
Массив.
Использование
$ProductQuery = new ProductQuery(); $ProductQuery->prepare_objects_query( $request );
- $request(WP_REST_Request) (обязательный)
- Request data.
Код ProductQuery::prepare_objects_query() ProductQuery::prepare objects query WC 10.8.1
public function prepare_objects_query( $request ) {
$args = array(
'offset' => $request['offset'],
'order' => $request['order'],
'orderby' => $request['orderby'],
'paged' => $request['page'],
'post__in' => $request['include'],
'post__not_in' => $request['exclude'],
'posts_per_page' => $request['per_page'] ? $request['per_page'] : -1,
'post_parent__in' => $request['parent'],
'post_parent__not_in' => $request['parent_exclude'],
'search' => $request['search'], // This uses search rather than s intentionally to handle searches internally.
'slug' => $request['slug'],
'fields' => 'ids',
'ignore_sticky_posts' => true,
'post_status' => ProductStatus::PUBLISH,
'date_query' => array(),
'post_type' => 'product',
);
// If searching for a specific SKU or slug, allow any post type.
if ( ! empty( $request['sku'] ) || ! empty( $request['slug'] ) ) {
$args['post_type'] = array( 'product', 'product_variation' );
}
// Taxonomy query to filter products by type, category, tag, shipping class, and attribute.
$tax_query = array();
// Filter product type by slug.
if ( ! empty( $request['type'] ) ) {
if ( ProductType::VARIATION === $request['type'] ) {
$args['post_type'] = 'product_variation';
} else {
$args['post_type'] = 'product';
$tax_query[] = array(
'taxonomy' => 'product_type',
'field' => 'slug',
'terms' => $request['type'],
);
}
}
if ( 'date' === $args['orderby'] ) {
$args['orderby'] = 'date ID';
}
// Set before into date query. Date query must be specified as an array of an array.
if ( isset( $request['before'] ) ) {
$args['date_query'][0]['before'] = $request['before'];
}
// Set after into date query. Date query must be specified as an array of an array.
if ( isset( $request['after'] ) ) {
$args['date_query'][0]['after'] = $request['after'];
}
// Set date query column. Defaults to post_date.
if ( isset( $request['date_column'] ) && ! empty( $args['date_query'][0] ) ) {
$args['date_query'][0]['column'] = 'post_' . $request['date_column'];
}
// Set custom args to handle later during clauses.
$custom_keys = array(
'sku',
'min_price',
'max_price',
'stock_status',
);
foreach ( $custom_keys as $key ) {
if ( ! empty( $request[ $key ] ) ) {
$args[ $key ] = $request[ $key ];
}
}
$operator_mapping = array(
'in' => 'IN',
'not_in' => 'NOT IN',
'and' => 'AND',
);
// Gets all registered product taxonomies and prefixes them with `tax_`.
// This is needed to avoid situations where a user registers a new product taxonomy with the same name as default field.
// eg an `sku` taxonomy will be mapped to `tax_sku`.
$all_product_taxonomies = array_map(
function ( $value ) {
return '_unstable_tax_' . $value;
},
get_taxonomies( array( 'object_type' => array( 'product' ) ), 'names' )
);
// Map between taxonomy name and arg key.
$default_taxonomies = array(
'product_cat' => 'category',
'product_tag' => 'tag',
'product_brand' => 'brand',
);
$taxonomies = array_merge( $all_product_taxonomies, $default_taxonomies );
// Set tax_query for each passed arg.
foreach ( $taxonomies as $taxonomy => $key ) {
if ( ! empty( $request[ $key ] ) ) {
$type = is_numeric( $request[ $key ][0] ) ? 'term_id' : 'slug';
$operator = $request->get_param( $key . '_operator' ) && isset( $operator_mapping[ $request->get_param( $key . '_operator' ) ] ) ? $operator_mapping[ $request->get_param( $key . '_operator' ) ] : 'IN';
$tax_query[] = array(
'taxonomy' => $taxonomy,
'field' => $type,
'terms' => $request[ $key ],
'operator' => $operator,
);
}
}
// Filter by attributes.
if ( ! empty( $request['attributes'] ) ) {
$att_queries = array();
foreach ( $request['attributes'] as $attribute ) {
if ( empty( $attribute['term_id'] ) && empty( $attribute['slug'] ) ) {
continue;
}
if ( in_array( $attribute['attribute'], wc_get_attribute_taxonomy_names(), true ) ) {
$operator = isset( $attribute['operator'], $operator_mapping[ $attribute['operator'] ] ) ? $operator_mapping[ $attribute['operator'] ] : 'IN';
$att_queries[] = array(
'taxonomy' => $attribute['attribute'],
'field' => ! empty( $attribute['term_id'] ) ? 'term_id' : 'slug',
'terms' => ! empty( $attribute['term_id'] ) ? $attribute['term_id'] : $attribute['slug'],
'operator' => $operator,
);
}
}
if ( 1 < count( $att_queries ) ) {
// Add relation arg when using multiple attributes.
$relation = $request->get_param( 'attribute_relation' ) && isset( $operator_mapping[ $request->get_param( 'attribute_relation' ) ] ) ? $operator_mapping[ $request->get_param( 'attribute_relation' ) ] : 'IN';
$tax_query[] = array(
'relation' => $relation,
$att_queries,
);
} else {
$tax_query = array_merge( $tax_query, $att_queries );
}
}
// Build tax_query if taxonomies are set.
if ( ! empty( $tax_query ) && 'product_variation' !== $args['post_type'] ) {
if ( ! empty( $args['tax_query'] ) ) {
$args['tax_query'] = array_merge( $tax_query, $args['tax_query'] ); // phpcs:ignore
} else {
$args['tax_query'] = $tax_query; // phpcs:ignore
}
} else {
// For product_variantions we need to convert the tax_query to a meta_query.
if ( ! empty( $args['tax_query'] ) ) {
$args['meta_query'] = $this->convert_tax_query_to_meta_query( array_merge( $tax_query, $args['tax_query'] ) ); // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
} else {
$args['meta_query'] = $this->convert_tax_query_to_meta_query( $tax_query ); // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
}
}
// Filter featured.
if ( is_bool( $request['featured'] ) ) {
$args['tax_query'][] = array(
'taxonomy' => 'product_visibility',
'field' => 'name',
'terms' => 'featured',
'operator' => true === $request['featured'] ? 'IN' : 'NOT IN',
);
}
// Filter by on sale products.
if ( is_bool( $request['on_sale'] ) ) {
$on_sale_key = $request['on_sale'] ? 'post__in' : 'post__not_in';
$on_sale_ids = wc_get_product_ids_on_sale();
// Use 0 when there's no on sale products to avoid return all products.
$on_sale_ids = empty( $on_sale_ids ) ? array( 0 ) : $on_sale_ids;
$args[ $on_sale_key ] += $on_sale_ids;
}
$catalog_visibility = $request->get_param( 'catalog_visibility' );
$rating = $request->get_param( 'rating' );
$visibility_options = wc_get_product_visibility_options();
if ( in_array( $catalog_visibility, array_keys( $visibility_options ), true ) ) {
$exclude_from_catalog = CatalogVisibility::SEARCH === $catalog_visibility ? '' : 'exclude-from-catalog';
$exclude_from_search = CatalogVisibility::CATALOG === $catalog_visibility ? '' : 'exclude-from-search';
$args['tax_query'][] = array(
'taxonomy' => 'product_visibility',
'field' => 'name',
'terms' => array( $exclude_from_catalog, $exclude_from_search ),
'operator' => CatalogVisibility::HIDDEN === $catalog_visibility ? 'AND' : 'NOT IN',
'rating_filter' => true,
);
}
if ( $rating ) {
$rating_terms = array();
foreach ( $rating as $value ) {
$rating_terms[] = 'rated-' . $value;
}
$args['tax_query'][] = array(
'taxonomy' => 'product_visibility',
'field' => 'name',
'terms' => $rating_terms,
);
}
$orderby = $request->get_param( 'orderby' );
$order = $request->get_param( 'order' );
$ordering_args = wc()->query->get_catalog_ordering_args( $orderby, $order );
$args['orderby'] = $ordering_args['orderby'];
$args['order'] = $ordering_args['order'];
if ( 'include' === $orderby ) {
$args['orderby'] = 'post__in';
} elseif ( 'id' === $orderby ) {
$args['orderby'] = 'ID'; // ID must be capitalized.
} elseif ( 'slug' === $orderby ) {
$args['orderby'] = 'name';
}
if ( $ordering_args['meta_key'] ) {
$args['meta_key'] = $ordering_args['meta_key']; // phpcs:ignore
}
// Filter by related products.
if ( ! empty( $request['related'] ) ) {
$product_id = absint( $request['related'] );
$related_product = wc_get_product( $product_id );
if ( ! $related_product || ! $related_product->is_visible() ) {
throw new RouteException(
'woocommerce_rest_product_not_found',
__( 'The related product ID is invalid or the product is not visible.', 'woocommerce' ), // phpcs:ignore WordPress.Security.EscapeOutput.ExceptionNotEscaped -- REST API JSON response, not HTML.
404
);
}
$limit = ! empty( $request['per_page'] ) ? (int) $request['per_page'] : 100;
$related = wc_get_related_products( $product_id, $limit );
if ( ! empty( $related ) ) {
$args['post__in'] = ! empty( $args['post__in'] )
? array_values( array_intersect( $args['post__in'], $related ) )
: array_values( $related );
} else {
// No related products found, return empty result.
$args['post__in'] = array( 0 );
}
}
return $args;
}