Show number of reviews in each category in Reviews per Category block (https://github.com/woocommerce/woocommerce-blocks/pull/1177)

* Add reviews to Category endpoint

* add option to show categories with reviews

* update label text if we're using reviews for counting

* update reviews count to use raw sql

* add flag before querying review count

* add review_count to collection data & schema

* fix PR code review problems

* update tests to it expects the new collection param

* add note about review_count is schema
This commit is contained in:
Seghir Nadir 2019-11-19 16:22:16 +01:00 committed by GitHub
parent dceb2c6a0f
commit bb0227edb1
6 changed files with 105 additions and 19 deletions

View File

@ -150,6 +150,7 @@ const ReviewsByCategoryEditor = ( {
const ids = value.map( ( { id } ) => id );
setAttributes( { categoryIds: ids } );
} }
showReviewCount={ true }
/>
<Button isDefault onClick={ onDone }>
{ __( 'Done', 'woo-gutenberg-products-block' ) }

View File

@ -24,6 +24,7 @@ const ProductCategoryControl = ( {
operator,
selected,
isSingle,
showReviewCount,
} ) => {
const renderItem = ( args ) => {
const { item, search, depth = 0 } = args;
@ -39,12 +40,18 @@ const ProductCategoryControl = ( {
? item.name
: `${ item.breadcrumbs.join( ', ' ) }, ${ item.name }`;
return (
<SearchListItem
className={ classes.join( ' ' ) }
{ ...args }
showCount
aria-label={ sprintf(
const listItemAriaLabel = showReviewCount
? sprintf(
_n(
'%s, has %d review',
'%s, has %d reviews',
item.review_count,
'woo-gutenberg-products-block'
),
accessibleName,
item.review_count
)
: sprintf(
_n(
'%s, has %d product',
'%s, has %d products',
@ -53,7 +60,34 @@ const ProductCategoryControl = ( {
),
accessibleName,
item.count
) }
);
const listItemCountLabel = showReviewCount
? sprintf(
_n(
'%d Review',
'%d Reviews',
item.review_count,
'woo-gutenberg-products-block'
),
item.review_count
)
: sprintf(
_n(
'%d Product',
'%d Products',
item.count,
'woo-gutenberg-products-block'
),
item.count
);
return (
<SearchListItem
className={ classes.join( ' ' ) }
{ ...args }
showCount
countLabel={ listItemCountLabel }
aria-label={ listItemAriaLabel }
/>
);
};

View File

@ -129,10 +129,11 @@ export const getCategory = ( categoryId ) => {
/**
* Get a promise that resolves to an array of category objects from the API.
*/
export const getCategories = () => {
export const getCategories = ( queryArgs ) => {
return apiFetch( {
path: addQueryArgs( `${ ENDPOINTS.products }/categories`, {
per_page: -1,
...queryArgs,
} ),
} );
};

View File

@ -49,7 +49,9 @@ describe( 'withCategories Component', () => {
it( 'getCategories is called on mount', () => {
const { getCategories } = mockUtils;
expect( getCategories ).toHaveBeenCalledWith();
expect( getCategories ).toHaveBeenCalledWith( {
show_review_count: false,
} );
expect( getCategories ).toHaveBeenCalledTimes( 1 );
} );
} );

View File

@ -29,7 +29,9 @@ const withCategories = createHigherOrderComponent( ( OriginalComponent ) => {
loadCategories() {
this.setState( { loading: true } );
getCategories()
getCategories( {
show_review_count: this.props.showReviewCount || false,
} )
.then( ( categories ) => {
this.setState( {
categories,

View File

@ -107,16 +107,36 @@ class ProductCategories extends WC_REST_Product_Categories_Controller {
*/
public function prepare_item_for_response( $item, $request ) {
$data = array(
'id' => (int) $item->term_id,
'name' => $item->name,
'slug' => $item->slug,
'parent' => (int) $item->parent,
'count' => (int) $item->count,
'description' => $item->description,
'image' => null,
'permalink' => get_term_link( $item->term_id, 'product_cat' ),
'id' => (int) $item->term_id,
'name' => $item->name,
'slug' => $item->slug,
'parent' => (int) $item->parent,
'count' => (int) $item->count,
'description' => $item->description,
'image' => null,
'review_count' => null,
'permalink' => get_term_link( $item->term_id, 'product_cat' ),
);
if ( $request->get_param( 'show_review_count' ) ) {
global $wpdb;
$products_of_category_sql = $wpdb->prepare(
"SELECT SUM( DISTINCT comment_count) as review_count
FROM {$wpdb->posts} AS posts
INNER JOIN {$wpdb->term_relationships} AS term_relationships ON posts.ID = term_relationships.object_id
INNER JOIN {$wpdb->term_taxonomy} AS term_taxonomy USING( term_taxonomy_id )
INNER JOIN {$wpdb->terms} AS terms USING( term_id )
WHERE terms.term_id=%d
AND term_taxonomy.taxonomy='product_cat'",
$item->term_id
);
$review_count = $wpdb->get_var( $products_of_category_sql ); // phpcs:ignore WordPress.DB.PreparedSQL.NotPrepared
$data['review_count'] = (int) $review_count;
}
$image_id = get_term_meta( $item->term_id, 'thumbnail_id', true );
if ( $image_id ) {
@ -144,6 +164,25 @@ class ProductCategories extends WC_REST_Product_Categories_Controller {
return $response;
}
/**
* Update the collection params.
*
* Adds new options for 'show_review_count'.
*
* @return array
*/
public function get_collection_params() {
$params = parent::get_collection_params();
$params['show_review_count'] = array(
'description' => __( 'Should we return how many reviews in a category?', 'woo-gutenberg-products-block' ),
'type' => 'boolean',
'default' => false,
);
return $params;
}
/**
* Get the Product's schema, conforming to JSON Schema.
*
@ -165,7 +204,14 @@ class ProductCategories extends WC_REST_Product_Categories_Controller {
$schema['properties']['count'] = $raw_schema['properties']['count'];
$schema['properties']['description'] = $raw_schema['properties']['description'];
$schema['properties']['image'] = $raw_schema['properties']['image'];
$schema['properties']['permalink'] = array(
// review_count will return null unless show_review_count param is trus.
$schema['properties']['review_count'] = array(
'description' => __( 'Number of reviews in the category.', 'woo-gutenberg-products-block' ),
'type' => 'integer',
'context' => array( 'view', 'edit' ),
'readonly' => true,
);
$schema['properties']['permalink'] = array(
'description' => __( 'Category URL.', 'woo-gutenberg-products-block' ),
'type' => 'string',
'format' => 'uri',