From aeb7e3377521ce0713c43a46d13bd59be2339477 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Albert=20Juh=C3=A9=20Lluveras?= Date: Mon, 29 Jul 2019 11:13:24 +0200 Subject: [PATCH] Reduce the number of dependencies used in Reviews by Product --- assets/js/blocks/reviews-by-product/block.js | 43 ++++++++----------- .../js/blocks/reviews-by-product/frontend.js | 4 +- assets/js/blocks/reviews-by-product/utils.js | 20 +++++---- assets/js/utils/uniqueid.js | 17 ++++++++ src/RestApi/Controllers/ProductReviews.php | 19 ++++---- 5 files changed, 60 insertions(+), 43 deletions(-) create mode 100644 assets/js/utils/uniqueid.js diff --git a/assets/js/blocks/reviews-by-product/block.js b/assets/js/blocks/reviews-by-product/block.js index 6926868eed1..f71353e59f7 100644 --- a/assets/js/blocks/reviews-by-product/block.js +++ b/assets/js/blocks/reviews-by-product/block.js @@ -3,16 +3,15 @@ */ import { __ } from '@wordpress/i18n'; import apiFetch from '@wordpress/api-fetch'; -import { addQueryArgs } from '@wordpress/url'; -import { Component, Fragment } from '@wordpress/element'; +import { Component } from '@wordpress/element'; import { debounce } from 'lodash'; import PropTypes from 'prop-types'; -import { withInstanceId } from '@wordpress/compose'; /** * Internal dependencies */ import { renderReview } from './utils'; +import uniqueID from '../../utils/uniqueid'; /** * Component to handle edit mode of "Reviews by Product". @@ -31,6 +30,7 @@ class ReviewsByProduct extends Component { this.onChangeOrderby = this.onChangeOrderby.bind( this ); this.getReviews = this.getReviews.bind( this ); this.appendReviews = this.appendReviews.bind( this ); + this.id = uniqueID( '', 'wc-block-reviews-by-product' ); } componentDidMount() { @@ -100,14 +100,15 @@ class ReviewsByProduct extends Component { return; } + const args = { + order, + orderby, + page, + per_page: parseInt( perPage, 10 ) || 1, + product_id: productId, + }; apiFetch( { - path: addQueryArgs( `/wc/blocks/products/reviews`, { - order, - orderby, - page, - per_page: parseInt( perPage, 10 ) || 1, - product_id: productId, - } ), + path: '/wc/blocks/products/reviews?' + Object.entries( args ).map( ( arg ) => arg.join( '=' ) ).join( '&' ), parse: false, } ).then( ( response ) => { if ( response.json ) { @@ -149,10 +150,10 @@ class ReviewsByProduct extends Component { return null; } - const { attributes, instanceId, isPreview } = this.props; + const { attributes, isPreview } = this.props; const { orderby } = this.state; - const selectId = `wc-block-reviews-by-product__orderby__select-${ instanceId }`; + const selectId = `wc-block-reviews-by-product__orderby__select-${ this.id }`; const selectProps = isPreview ? { readOnly: true, value: attributes.orderby, @@ -224,13 +225,11 @@ class ReviewsByProduct extends Component { } render() { - return ( - - { this.renderOrderBySelect() } - { this.renderReviewsList() } - { this.renderLoadMoreButton() } - - ); + return [ + this.renderOrderBySelect(), + this.renderReviewsList(), + this.renderLoadMoreButton(), + ]; } } @@ -239,14 +238,10 @@ ReviewsByProduct.propTypes = { * The attributes for this block. */ attributes: PropTypes.object.isRequired, - /** - * A unique ID for identifying the label for the select dropdown. - */ - instanceId: PropTypes.number, /** * Whether this is the block preview or frontend display. */ isPreview: PropTypes.bool, }; -export default withInstanceId( ReviewsByProduct ); +export default ReviewsByProduct; diff --git a/assets/js/blocks/reviews-by-product/frontend.js b/assets/js/blocks/reviews-by-product/frontend.js index 126b136eecc..51ad19fa022 100644 --- a/assets/js/blocks/reviews-by-product/frontend.js +++ b/assets/js/blocks/reviews-by-product/frontend.js @@ -1,7 +1,6 @@ /** * External dependencies */ -import { forEach } from 'lodash'; import { render } from '@wordpress/element'; /** @@ -14,7 +13,8 @@ const containers = document.querySelectorAll( ); if ( containers.length ) { - forEach( containers, ( el ) => { + // Use Array.forEach for IE11 compatibility + Array.prototype.forEach.call( containers, ( el ) => { const attributes = { orderby: el.dataset.orderby, perPage: el.dataset.perPage, diff --git a/assets/js/blocks/reviews-by-product/utils.js b/assets/js/blocks/reviews-by-product/utils.js index 52d5faa204c..09b77800bbe 100644 --- a/assets/js/blocks/reviews-by-product/utils.js +++ b/assets/js/blocks/reviews-by-product/utils.js @@ -2,9 +2,16 @@ * External dependencies */ import { __, sprintf } from '@wordpress/i18n'; -import { format } from '@wordpress/date'; -import classNames from 'classnames'; +function getReviewClasses( isLoading ) { + const classArray = [ 'wc-block-reviews-by-product__item' ]; + + if ( isLoading ) { + classArray.push( 'is-loading' ); + } + + return classArray.join( ' ' ); +} /** * Render a review for the Reviews by Product block * @@ -15,13 +22,10 @@ import classNames from 'classnames'; */ export function renderReview( attributes, review = {}, i = 0 ) { const { showAvatar, showProductRating: showProductRatingAttr, showReviewDate, showReviewerName } = attributes; - const { id = null, date_created: dateCreated, rating, review: text = '', reviewer = '', reviewer_avatar_urls: avatarUrls = {} } = review; + const { id = null, date_created: dateCreated, formatted_date_created: formattedDateCreated, rating, review: text = '', reviewer = '', reviewer_avatar_urls: avatarUrls = {} } = review; const isLoading = ! Object.keys( review ).length > 0; const showProductRating = Number.isFinite( rating ) && showProductRatingAttr; - - const classes = classNames( 'wc-block-reviews-by-product__item', { - 'is-loading': isLoading, - } ); + const classes = getReviewClasses( isLoading ); const starStyle = { width: ( rating / 5 * 100 ) + '%', }; @@ -61,7 +65,7 @@ export function renderReview( attributes, review = {}, i = 0 ) { ) } { showReviewDate && ( - + ) } ) } diff --git a/assets/js/utils/uniqueid.js b/assets/js/utils/uniqueid.js new file mode 100644 index 00000000000..0342efd0ca9 --- /dev/null +++ b/assets/js/utils/uniqueid.js @@ -0,0 +1,17 @@ +const ids = []; + +/** + * Returns a unique ID. + * + * This is an alternative for withInstanceId from @wordpress/compose to avoid using that dependency on the frontend. + * + * @param {string} prefix Prefix for the ID. Should be the component name. + * @param {string} group ID group. + */ +export default function( prefix = 'id', group = '' ) { + if ( ! ids[ group ] ) { + ids[ group ] = 0; + } + ids[ group ]++; + return `${ prefix }${ ids[ group ] }`; +} diff --git a/src/RestApi/Controllers/ProductReviews.php b/src/RestApi/Controllers/ProductReviews.php index e040a1d5c29..778c5e6062f 100644 --- a/src/RestApi/Controllers/ProductReviews.php +++ b/src/RestApi/Controllers/ProductReviews.php @@ -219,15 +219,16 @@ public function prepare_item_for_response( $review, $request ) { $context = ! empty( $request['context'] ) ? $request['context'] : 'view'; $rating = get_comment_meta( $review->comment_ID, 'rating', true ) === '' ? null : (int) get_comment_meta( $review->comment_ID, 'rating', true ); $data = array( - 'id' => (int) $review->comment_ID, - 'date_created' => wc_rest_prepare_date_response( $review->comment_date ), - 'date_created_gmt' => wc_rest_prepare_date_response( $review->comment_date_gmt ), - 'product_id' => (int) $review->comment_post_ID, - 'reviewer' => $review->comment_author, - 'review' => $review->comment_content, - 'rating' => $rating, - 'verified' => wc_review_is_from_verified_owner( $review->comment_ID ), - 'reviewer_avatar_urls' => rest_get_avatar_urls( $review->comment_author_email ), + 'id' => (int) $review->comment_ID, + 'date_created' => wc_rest_prepare_date_response( $review->comment_date ), + 'formatted_date_created' => get_comment_date( 'F j, Y', $review->comment_ID ), + 'date_created_gmt' => wc_rest_prepare_date_response( $review->comment_date_gmt ), + 'product_id' => (int) $review->comment_post_ID, + 'reviewer' => $review->comment_author, + 'review' => $review->comment_content, + 'rating' => $rating, + 'verified' => wc_review_is_from_verified_owner( $review->comment_ID ), + 'reviewer_avatar_urls' => rest_get_avatar_urls( $review->comment_author_email ), ); if ( 'view' === $context ) {