diff --git a/assets/js/blocks/reviews-by-product/index.js b/assets/js/blocks/reviews-by-product/index.js index 3ee393c67a7..ff6fb3bdd07 100644 --- a/assets/js/blocks/reviews-by-product/index.js +++ b/assets/js/blocks/reviews-by-product/index.js @@ -2,12 +2,12 @@ * External dependencies */ import { __ } from '@wordpress/i18n'; -// import { InnerBlocks } from '@wordpress/editor'; import { registerBlockType } from '@wordpress/blocks'; /** * Internal dependencies */ +import './style.scss'; import Block from './block'; import ReviewsByProductIcon from '../../components/icons/reviews-by-product'; diff --git a/assets/js/blocks/reviews-by-product/style.scss b/assets/js/blocks/reviews-by-product/style.scss new file mode 100644 index 00000000000..ba9ec83fb7a --- /dev/null +++ b/assets/js/blocks/reviews-by-product/style.scss @@ -0,0 +1,102 @@ +.wc-block-reviews-by-product { + .wc-block-reviews-by-product__list { + list-style: none; + margin: 0; + } + + .wc-block-reviews-by-product__item { + margin-bottom: $gap-larger; + } + + .wc-block-reviews-by-product__info { + display: grid; + grid-template-columns: 1fr; + margin-top: $gap-small; + + > .avatar { + grid-column: 1; + grid-row: 1 / 3; + } + + .wc-block-reviews-by-product__meta { + grid-column: 1; + grid-row: 1; + + .wc-block-reviews-by-product__author { + font-size: 1.4em; + } + + .wc-block-reviews-by-product__author + .wc-block-reviews-by-product__rating { + margin-left: $gap-smaller; + } + + .wc-block-reviews-by-product__rating { + display: inline; + + .star-rating { + display: inline-block; + top: 5px; + overflow: hidden; + position: relative; + height: 1.618em; + line-height: 1.618; + font-size: 1em; + width: 5.3em; + font-family: star; + font-weight: 400; + } + + .star-rating::before { + content: '\53\53\53\53\53'; + opacity: .25; + float: left; + top: 0; + left: 0; + position: absolute; + } + + .star-rating span { + overflow: hidden; + float: left; + top: 0; + left: 0; + position: absolute; + padding-top: 1.5em; + } + + .star-rating span::before { + content: '\53\53\53\53\53'; + top: 0; + position: absolute; + left: 0; + color: #e6a237; + } + } + } + + .wc-block-reviews-by-product__published-date { + color: #808080; + font-size: 0.9em; + grid-column: 1; + grid-row: 1; + } + } + + &.has-picture { + .wc-block-reviews-by-product__info { + grid-template-columns: #{60px + $gap-small} 1fr; + } + + .wc-block-reviews-by-product__meta, + .wc-block-reviews-by-product__published-date { + grid-column: 2; + } + } + + &.has-name, + &.has-rating { + .wc-block-reviews-by-product__published-date { + grid-row: 2; + } + } +} diff --git a/src/BlockTypes/ReviewsByProduct.php b/src/BlockTypes/ReviewsByProduct.php index ee5daed496f..8dddd40fea1 100644 --- a/src/BlockTypes/ReviewsByProduct.php +++ b/src/BlockTypes/ReviewsByProduct.php @@ -93,33 +93,148 @@ protected static function get_schema_reviews_orderby() { } /** - * Render the review meta (author and date). + * Loads the reviews * - * @param array $comment Comment attributes. + * @return array Array of comments. */ - public function review_display_meta( $comment ) { - $verified = wc_review_is_from_verified_owner( $comment->comment_ID ); + protected function get_reviews() { + $args = array( + 'number' => $this->attributes['reviewsShown'], + 'order_by' => $this->attributes['orderby'], + 'order' => $this->attributes['order'], + 'post_id' => $this->attributes['productId'], + 'status' => 'approve', + 'type' => 'review', + ); + if ( array_key_exists( 'meta_key', $this->attributes ) ) { + $args['meta_key'] = $this->attributes['meta_key']; // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key + } + + return get_comments( $args ); + } + + /** + * Render the reviewer picture + * + * @param object $comment Comment. + * @return string HTML code of the reviewer picture. + */ + protected function get_reviewer_picture_html( $comment ) { + if ( ! $this->attributes['showReviewerPicture'] ) { + return ''; + } + + return get_avatar( $comment, apply_filters( 'woocommerce_review_gravatar_size', '60' ), '' ); + } + + /** + * Render the reviewer name + * + * @param integer $comment_id Id of the comment. + * @return string HTML code of the reviewer name. + */ + protected function get_reviewer_name_html( $comment_id ) { + if ( ! $this->attributes['showReviewerName'] ) { + return ''; + } + + $author = get_comment_author( $comment_id ); + + return "{$author}"; + } + + /** + * Render the review rating + * + * @param integer $comment_id Id of the comment. + * @return string HTML code of the review rating. + */ + protected function get_review_rating_html( $comment_id ) { + $rating = intval( get_comment_meta( $comment_id, 'rating', true ) ); + + if ( ! $this->attributes['showProductRating'] || ! $rating || ! wc_review_ratings_enabled() ) { + return ''; + } + + $rating_html = wc_get_rating_html( $rating ); + + return "
{$rating_html}
"; + } + + /** + * Render the review date + * + * @param integer $comment_id Id of the comment. + * @return string HTML code of the review date. + */ + protected function get_review_date_html( $comment_id ) { + if ( ! $this->attributes['showReviewDate'] ) { + return ''; + } + + $datetime = esc_attr( get_comment_date( 'c', $comment_id ) ); + $date = esc_html( get_comment_date( wc_date_format(), $comment_id ) ); + return ""; + } + + /** + * Render the review date + * + * @param object $comment Comment. + * @return string HTML code of the review info. + */ + protected function get_review_info_html( $comment ) { + $review_info = $this->get_reviewer_picture_html( $comment ); + if ( $this->attributes['showReviewerName'] || $this->attributes['showProductRating'] ) { + $reviewer_name = $this->get_reviewer_name_html( $comment->comment_ID ); + $reviewer_rating = $this->get_review_rating_html( $comment->comment_ID ); + $review_info .= "
{$reviewer_name}{$reviewer_rating}
"; + } + $review_info .= $this->get_review_date_html( $comment->comment_ID ); + + return $review_info; + } + + /** + * Render a single review. + * + * @param object $comment Comment. + * @return string HTML code of the review. + */ + protected function get_review_html( $comment ) { + $text = get_comment_text( $comment->comment_ID ); + $info = $this->get_review_info_html( $comment ); + + return "
  • {$text}
    {$info}
  • "; + } + + /** + * Get the list of classes to apply to this block. + * + * @return string space-separated list of classes. + */ + protected function get_container_classes() { + $classes = array( + 'wc-block-reviews-by-product', + ); - if ( ! $this->attributes['showReviewerName'] && ! $this->attributes['showReviewDate'] ) { - return; + if ( $this->attributes['showReviewerPicture'] ) { + $classes[] = 'has-picture'; } - $html = '

    '; if ( $this->attributes['showReviewerName'] ) { - $html .= '' . get_comment_author() . ''; - if ( 'yes' === get_option( 'woocommerce_review_rating_verification_label' ) && $verified ) { - $html .= '(' . esc_attr__( 'verified owner', 'woo-gutenberg-products-block' ) . ') '; - } + $classes[] = 'has-name'; } - if ( $this->attributes['showReviewerName'] && $this->attributes['showReviewDate'] ) { - $html .= ''; + + if ( $this->attributes['showProductRating'] ) { + $classes[] = 'has-rating'; } + if ( $this->attributes['showReviewDate'] ) { - $html .= ''; + $classes[] = 'has-date'; } - $html .= '

    '; - echo $html; // phpcs:ignore WordPress.Security.EscapeOutput.OutputNotEscaped + return implode( ' ', $classes ); } /** @@ -131,40 +246,10 @@ public function review_display_meta( $comment ) { */ public function render( $attributes = array(), $content = '' ) { $this->attributes = $this->parse_attributes( $attributes ); + $reviews = $this->get_reviews(); + $reviews_html = implode( '', array_map( array( $this, 'get_review_html' ), $reviews ) ); + $classes = $this->get_container_classes(); - $get_comments_args = array( - 'number' => $this->attributes['reviewsShown'], - 'order_by' => $this->attributes['orderby'], - 'order' => $this->attributes['order'], - 'post_id' => $this->attributes['productId'], - 'status' => 'approve', - 'type' => 'review', - ); - if ( array_key_exists( 'meta_key', $this->attributes ) ) { - $get_comments_args['meta_key'] = $this->attributes['meta_key']; // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_key - } - $comments = get_comments( $get_comments_args ); - $args = array( - 'callback' => 'woocommerce_comments', - 'echo' => false, - ); - remove_action( 'woocommerce_review_meta', 'woocommerce_review_display_meta', 10 ); - add_action( 'woocommerce_review_meta', array( $this, 'review_display_meta' ), 10 ); - if ( ! $this->attributes['showProductRating'] ) { - remove_action( 'woocommerce_review_before_comment_meta', 'woocommerce_review_display_rating', 10 ); - } - if ( ! $this->attributes['showReviewerPicture'] ) { - remove_action( 'woocommerce_review_before', 'woocommerce_review_display_gravatar', 10 ); - } - $list_comments = wp_list_comments( apply_filters( 'woocommerce_product_review_list_args', $args ), $comments ); - add_action( 'woocommerce_review_meta', 'woocommerce_review_display_meta', 10 ); - remove_action( 'woocommerce_review_meta', array( $this, 'review_display_meta' ), 10 ); - if ( ! $this->attributes['showProductRating'] ) { - add_action( 'woocommerce_review_before_comment_meta', 'woocommerce_review_display_rating', 10 ); - } - if ( ! $this->attributes['showReviewerPicture'] ) { - add_action( 'woocommerce_review_before', 'woocommerce_review_display_gravatar', 10 ); - } - return '
    '; + return '
    '; } }