Skip to content

Commit

Permalink
feat: collectionStats query added
Browse files Browse the repository at this point in the history
  • Loading branch information
kidunot89 committed Sep 22, 2023
1 parent ac5fa6b commit 786efef
Show file tree
Hide file tree
Showing 5 changed files with 301 additions and 0 deletions.
2 changes: 2 additions & 0 deletions includes/class-type-registry.php
Original file line number Diff line number Diff line change
Expand Up @@ -60,6 +60,7 @@ public function init() {
Type\WPInputObject\Product_Taxonomy_Filter_Input::register();
Type\WPInputObject\Product_Taxonomy_Input::register();
Type\WPInputObject\Orderby_Inputs::register();
Type\WPInputObject\Collection_Stats_Query_Input::register();

/**
* Interfaces.
Expand Down Expand Up @@ -104,6 +105,7 @@ public function init() {
Type\WPObject\Cart_Error_Types::register();
Type\WPObject\Payment_Token_Types::register();
Type\WPObject\Country_State_Type::register();
Type\WPObject\Collection_Stats_Type::register();

/**
* Object fields.
Expand Down
2 changes: 2 additions & 0 deletions includes/class-wp-graphql-woocommerce.php
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ private function includes() {
require $include_directory_path . 'type/object/class-variation-attribute-type.php';
require $include_directory_path . 'type/object/class-payment-token-types.php';
require $include_directory_path . 'type/object/class-country-state-type.php';
require $include_directory_path . 'type/object/class-collection-stats-type.php';

// Include input type class files.
require $include_directory_path . 'type/input/class-cart-item-input.php';
Expand All @@ -293,6 +294,7 @@ private function includes() {
require $include_directory_path . 'type/input/class-product-taxonomy-input.php';
require $include_directory_path . 'type/input/class-shipping-line-input.php';
require $include_directory_path . 'type/input/class-tax-rate-connection-orderby-input.php';
require $include_directory_path . 'type/input/class-collection-stats-query-input.php';

// Include mutation type class files.
require $include_directory_path . 'mutation/class-cart-add-fee.php';
Expand Down
38 changes: 38 additions & 0 deletions includes/type/input/class-collection-stats-query-input.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
<?php
/**
* WPInputObjectType - CollectionStatsQueryInput
*
* @package WPGraphQL\WooCommerce\Type\WPInputObject
* @since TBD
*/

namespace WPGraphQL\WooCommerce\Type\WPInputObject;

/**
* Class Collection_Stats_Query_Input
*/
class Collection_Stats_Query_Input {
/**
* Registers type
*
* @return void
*/
public static function register() {
register_graphql_input_type(
'CollectionStatsQueryInput',
[
'description' => __( 'Taxonomy query', 'wp-graphql-woocommerce' ),
'fields' => [
'taxonomy' => [
'type' => [ 'non_null' => 'ProductTaxonomyEnum' ],
'description' => __( 'Product Taxonomy', 'wp-graphql-woocommerce' ),
],
'relation' => [
'type' => [ 'non_null' => 'RelationEnum' ],
'description' => __( 'Taxonomy relation to query', 'wp-graphql-woocommerce' ),
],
],
]
);
}
}
168 changes: 168 additions & 0 deletions includes/type/object/class-collection-stats-type.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,168 @@
<?php
/**
* WPObject Type - Collection_Stats_Type
*
* @package WPGraphQL\WooCommerce\Type\WPObject
* @since TBD
*/

namespace WPGraphQL\WooCommerce\Type\WPObject;

use WPGraphQL\Data\Connection\TermObjectConnectionResolver;

/**
* Class Collection_Stats_Type
*/
class Collection_Stats_Type {
/**
* Register CollectionStats type to the WPGraphQL schema
*
* @return void
*/
public static function register() {
register_graphql_object_type(
'PriceRangeStats',
[
'eagerlyLoadType' => true,
'description' => __( 'Price range stats', 'wp-graphql-woocommerce' ),
'fields' => [
'minPrice' => [
'type' => 'Float',
'description' => __( 'Minimum price', 'wp-graphql-woocommerce' ),
'resolve' => function( $source ) {
return ! empty( $source['min_price'] ) ? $source['min_price'] : null;
}
],
'maxPrice' => [
'type' => 'Float',
'description' => __( 'Maximum price', 'wp-graphql-woocommerce' ),
'resolve' => function( $source ) {
return ! empty( $source['max_price'] ) ? $source['max_price'] : null;
}
],
],
]
);

register_graphql_object_type (
'AttributeCount',
[
'eagerlyLoadType' => true,
'description' => __( 'Attribute count', 'wp-graphql-woocommerce' ),
'fields' => [
'termId' => [
'type' => [ 'non_null' => 'ID' ],
'description' => __( 'Term ID', 'wp-graphql-woocommerce' ),
],
'count' => [
'type' => 'Int',
'description' => __( 'Filtered Term Count', 'wp-graphql-woocommerce' ),
],
],
'connections' => [
'term' => [
'toType' => 'TermNode',
'oneToOne' => true,
'resolve' => static function ( $source, $args, $context, $info ) {
$term_id = ! empty ( $source->termId ) ? $source->termId : 0;
$taxonomy = ! empty ( $source->taxonomy ) ? $source->taxonomy : null;
$resolver = new TermObjectConnectionResolver( $source, $args, $context, $info, $taxonomy );

return $resolver->one_to_one()
->set_query_arg( 'include', [ $term_id ] )
->get_connection();
},
],
]
]
);

register_graphql_object_type(
'RatingCount',
[
'eagerlyLoadType' => true,
'description' => __( 'Rating count', 'wp-graphql-woocommerce' ),
'fields' => [
'rating' => [
'type' => [ 'non_null' => 'Int' ],
'description' => __( 'Rating', 'wp-graphql-woocommerce' ),
],
'count' => [
'type' => 'Int',
'description' => __( 'Filtered Rating Count', 'wp-graphql-woocommerce' ),
],
],
]
);

register_graphql_object_type(
'CollectionStats',
[
'description' => __( '', 'wp-graphql-woocommerce' ),
'fields' => [
'priceRange' => [
'type' => 'PriceRangeStats',
'description' => __( 'Price range', 'wp-graphql-woocommerce' ),
'resolve' => function( $source ) {
$min_price = ! empty( $source['min_price'] ) ? $source['min_price'] : null;
$max_price = ! empty( $source['max_price'] ) ? $source['max_price'] : null;
return compact( 'min_price', 'max_price' );
}
],
'attributeCounts' => [
'type' => [ 'list_of' => 'AttributeCount' ],
'args' => [
'page' => [
'type' => 'Int',
'description' => __( 'Page of results to return.', 'wp-graphql-woocommerce' ),
],
'perPage' => [
'type' => 'Int',
'description' => __( 'Number of results to return per page.', 'wp-graphql-woocommerce' ),
],
],
'description' => __( 'Attribute counts', 'wp-graphql-woocommerce' ),
'resolve' => function ( $source, $args ) {
$page = ! empty( $args['page'] ) ? $args['page'] : 1;
$per_page = ! empty( $args['perPage'] ) ? $args['perPage'] : 0;
$attribute_counts = ! empty( $source['attribute_counts'] ) ? $source['attribute_counts'] : [];
$attribute_counts = array_slice(
$attribute_counts,
( $page - 1 ) * $per_page,
0 < $per_page ? $per_page : null
);

return $attribute_counts;
}
],
'ratingCounts' => [
'type' => [ 'list_of' => 'RatingCount' ],
'args' => [
'page' => [
'type' => 'Int',
'description' => __( 'Page of results to return.', 'wp-graphql-woocommerce' ),
],
'perPage' => [
'type' => 'Int',
'description' => __( 'Number of results to return per page.', 'wp-graphql-woocommerce' ),
],
],
'description' => __( 'Rating counts', 'wp-graphql-woocommerce' ),
'resolve' => function ( $source, $args ) {
$page = ! empty( $args['page'] ) ? $args['page'] : 1;
$per_page = ! empty( $args['perPage'] ) ? $args['perPage'] : 0;
$rating_counts = ! empty( $source['rating_counts'] ) ? $source['rating_counts'] : [];
$rating_counts = array_slice(
$rating_counts,
( $page - 1 ) * $per_page,
0 < $per_page ? $per_page : null
);

return $rating_counts;
}
],
],
]
);
}
}
91 changes: 91 additions & 0 deletions includes/type/object/class-root-query.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,7 @@

namespace WPGraphQL\WooCommerce\Type\WPObject;

use Automattic\WooCommerce\StoreApi\Utilities\ProductQueryFilters;
use Automattic\WooCommerce\Utilities\OrderUtil;
use GraphQL\Error\UserError;
use GraphQL\Type\Definition\ResolveInfo;
Expand Down Expand Up @@ -515,6 +516,96 @@ public static function register_fields() {
return [];
},
],
'collectionStats' => [
'type' => 'CollectionStats',
'args' => [
'calculatePriceRange' => [
'type' => 'Boolean',
],
'calculateRatingCounts' => [
'type' => 'Boolean',
],
'taxonomies' => [
'type' => [ 'list_of' => 'CollectionStatsQueryInput' ],
],
],
'description' => __( 'Statistics for a product taxonomy query', 'wp-graphql-woocommerce' ),
'resolve' => function ( $_, $args ) {
$data = [
'min_price' => null,
'max_price' => null,
'attribute_counts' => null,
'stock_status_counts' => null,
'rating_counts' => null,
];
$filters = new ProductQueryFilters();
$request = new \WP_REST_Request();
$request->set_param( 'calculate_attribute_counts', ! empty( $args['taxonomies'] ) ? $args['taxonomies'] : null );
$request->set_param( 'calculate_price_range', ! empty( $args['calculatePriceRange'] ) );
$request->set_param( 'calculate_stock_status_counts', ! empty( $args['calculateStockStatusCounts'] ) );
$request->set_param( 'calculate_rating_counts', ! empty( $args['calculateRatingCounts'] ) );


if ( ! empty( $request['calculate_price_range'] ) ) {
$filter_request = clone $request;
$filter_request->set_param( 'min_price', null );
$filter_request->set_param( 'max_price', null );

$price_results = $filters->get_filtered_price( $filter_request );
$data['min_price'] = $price_results->min_price;
$data['max_price'] = $price_results->max_price;
}

if ( ! empty( $request['calculate_stock_status_counts'] ) ) {
$filter_request = clone $request;
$counts = $filters->get_stock_status_counts( $filter_request );

$data['stock_status_counts'] = [];

foreach ( $counts as $key => $value ) {
$data['stock_status_counts'][] = (object) [
'status' => $key,
'count' => $value,
];
}
}

if ( ! empty( $request['calculate_attribute_counts'] ) ) {
foreach ( $request['calculate_attribute_counts'] as $attributes_to_count ) {
if ( ! isset( $attributes_to_count['taxonomy'] ) ) {
continue;
}

$counts = $filters->get_attribute_counts( $request, $attributes_to_count['taxonomy'] );

foreach ( $counts as $key => $value ) {
$data['attribute_counts'][] = (object) [
'taxonomy' => $attributes_to_count['taxonomy'],
'termId' => $key,
'count' => $value,
];
}
}
}

if ( ! empty( $request['calculate_rating_counts'] ) ) {
$filter_request = clone $request;
$counts = $filters->get_rating_counts( $filter_request );
$data['rating_counts'] = [];

foreach ( $counts as $key => $value ) {
$data['rating_counts'][] = (object) [
'rating' => $key,
'count' => $value,
];
}
}

//wp_send_json( $data );

return $data;
},
]
]
);

Expand Down

0 comments on commit 786efef

Please sign in to comment.