WooCommerce: Display some reviews randomly on home page
With the comment WP_Comment_Query
, comments can't be in random order. so you need to use a simple lightweight SQL query instead, using dedicated WordPressWPDB
Class.
In the following code, you can change the styles and the html structure to get the desired output. You can also set the number of reviews you want to display in random order using available shortcode argument "limit" (default is set to 5):
add_shortcode('woo_reviews', 'get_random_woo_reviews');
function get_random_woo_reviews( $atts ){
// Shortcode Attributes
$atts = shortcode_atts( array(
'limit' => '5', // <== Set to 5 reviews by default
), $atts, 'woo_reviews' );
global $wpdb;
// The SQL random query on product reviews
$comments = $wpdb->get_results( $wpdb->prepare("
SELECT *
FROM {$wpdb->prefix}comments c
INNER JOIN {$wpdb->prefix}posts p ON c.comment_post_ID = p.ID
WHERE c.comment_type = 'review' AND p.post_status = 'publish'
ORDER BY RAND() LIMIT %d
", intval( esc_attr($atts['limit']) ) ) );
ob_start(); // Start buffering
## CSS applied styles
?>
<style>
ul.product-reviews, ul.product-reviews li { list-style: none; margin:0; padding:0; line-height: normal;}
ul.product-reviews li { display:block; max-width: 200px, padding: 10px; display:inline-block; vertical-align: text-top;}
ul.product-reviews li .title {font-size: 1.2em;}
ul.product-reviews li .content {max-width: 180px; font-size: 0.9em; margin-bottom: 6px;}
ul.product-reviews li .author, ul.product-reviews li .date {display: block; font-size: 0.75em;}
</style>
<?php
## HTML structure
?>
<ul class="product-reviews"><?php
foreach ( $comments as $comment ) {
?>
<li>
<h4 class="title"><?php echo get_the_title( $comment->comment_post_ID ); ?></h4>
<div class="content"><?php echo $comment->comment_content; ?></div>
<span class="author"><?php printf( __("Posted By %s") . ' ', '<strong>' . $comment->comment_author . '</strong>' ); ?></span>
<span class="date"><?php printf( __("On %s"), '<strong>' . date_i18n( 'l jS \of F Y', strtotime( $comment->comment_date) ) . '</strong>' ); ?></span>
</li>
<?php
}
?></ul><?php
return ob_get_clean(); // Return the buffered output
}
Code goes in function.php file of your active child theme (or active theme). Tested and works.
USAGE: [woo_reviews]
or in php: echo do_shortcode( "[woo_reviews]" );
WooCommerce: Display some 5 stars rating products reviews randomly
A "meta query" is required to the WP_Comment_Query
based on "rating" meta key set to 5 stars meta value, to get random reviews that have 5 stars rating, as follows:
function get_random_five_stars_products_reviews( $atts ) {
// Extract shortcode attributes
extract( shortcode_atts( array(
'limit' => 5, // number of reviews to be displayed by default
), $atts, 'woo_reviews' ) );
$comments = get_comments( array(
'status' => 'approve',
'post_status' => 'publish',
'post_type' => 'product',
'meta_query' => array( array(
'key' => 'rating',
'value' => '5',
) ),
) );
shuffle($comments);
$comments = array_slice( $comments, 0, $limit );
$html = '<ul class="products-reviews">';
foreach( $comments as $comment ) {
$rating = intval( get_comment_meta( $comment->comment_ID, 'rating', true ) );
$html .= '<li class="review">';
$html .= '<div>'.get_the_title( $comment->comment_post_ID ).'</div>';
if ( $rating > 4 ) $html .= wc_get_rating_html( $rating );
$html .= '<div>' .$comment->comment_content.'</div>';
$html .= "<div>Posted By :".$comment->comment_author." On ".$comment->comment_date. "</div>";
$html .= '</li>';
}
return $html . '</ul>';
}
add_shortcode('woo_reviews', 'get_random_five_stars_products_reviews');
Code goes in functions.php file of the active child theme (or active theme). Tested and works
USAGE: [woo_reviews]
or [woo_reviews limit="3"]
for 3 random reviews for example.
Display some WooCommerce product reviews with limited content length randomly
To limit displayed 5 starts reviews with a content that doesn't exceed a specific length (here 100 characters) use the following:
function get_random_five_stars_products_reviews( $atts ) {
// Extract shortcode attributes
extract( shortcode_atts( array(
'limit' => 5, // number of reviews to be displayed by default
'length' => 100, // Limit comments text content lenght
'show_stars' => true, // Or "false" to hide
), $atts, 'woo_reviews' ) );
$comments = get_comments( array(
'status' => 'approve',
'post_status' => 'publish',
'post_type' => 'product',
'meta_query' => array( array(
'key' => 'rating',
'value' => '5',
) ),
) );
shuffle($comments);
$count = 0; // Initializing
$html = '<ul class="products-reviews">';
foreach( $comments as $comment ) {
$content = $comment->comment_content;
if( strlen($content) <= $length && $count < $limit ) {
$rating = intval( get_comment_meta( $comment->comment_ID, 'rating', true ) );
$html .= '<li class="review">';
$html .= '<div>'.get_the_title( $comment->comment_post_ID ).'</div>';
if ( $show_stars ) {
$html .= wc_get_rating_html( $rating );
}
$html .= '<div>' .$content. '</div>';
$html .= "<div>Posted By :".$comment->comment_author." On ".$comment->comment_date. "</div>";
$html .= '</li>';
$count++; // Increase count
}
if ( $count == $limit ) {
break; // Stop the loop
}
}
return $html . '</ul>';
}
add_shortcode('woo_reviews', 'get_random_five_stars_products_reviews');
Code goes in functions.php file of the active child theme (or active theme). It should works.
Display woocommerce review count next to star rating
Woocommerce already displays reviews count next to star rating in single product page. But on shop and archives page it displays only star rating. Follow the below steps to display star rating count even on shop and archives pages.
Step 1) Create a new folder in your theme’s root and name it ‘woocommerce’
Step 2) Create a new folder in the newly created ‘woocommerce’ folder and name it ‘loop’
Step 3) Add ‘rating.php’ file to the newly created ‘loop’ folder
Now your directory would look something like this
/public_html/wp-content/themes/YOUR-THEME/woocommerce/loop
Add the below code to the newly created ‘rating.php’ and customize it according to your need.
<?php
/**
* Loop Rating
*
* This template can be overridden by copying it to yourtheme/woocommerce/loop/rating.php.
*
* HOWEVER, on occasion WooCommerce will need to update template files and you
* (the theme developer) will need to copy the new files to your theme to
* maintain compatibility. We try to do this as little as possible, but it does
* happen. When this occurs the version of the template file will be bumped and
* the readme will list any important changes.
*
* @see https://docs.woocommerce.com/document/template-structure/
* @author WooThemes
* @package WooCommerce/Templates
* @version 3.0.0
*/
if ( ! defined( 'ABSPATH' ) ) {
exit;
}
global $product;
if ( get_option( 'woocommerce_enable_review_rating' ) === 'no' ) {
return;
}
$rating_count = $product->get_rating_count();
$review_count = $product->get_review_count();
$average = $product->get_average_rating();
if ( $rating_count >= 0 ) : ?>
<?php echo wc_get_rating_html($average, $rating_count); ?>
<?php if ( comments_open() ): ?><a href="<?php echo get_permalink() ?>#reviews" class="woocommerce-review-link" rel="nofollow">(<?php printf( _n( '%s',$review_count,'woocommerce' ), '<span class="count">' . esc_html( $review_count ) . '</span>' ); ?>)</a><?php endif ?>
<?php endif; ?>
In case this doesn’t work
Add ‘templates’ folder in ‘woocommerce’ folder and then add ‘loop’ folder in ‘templates’ folder.
Now the directory would look like this
/public_html/wp-content/themes/YOUR-THEME/woocommerce/templates/loop
Make e-mail field from single product page review form not required
First, you have to hide email fields from a comment form rather than remove it.
function hide_email_field_on_comment(){
if( !is_admin() && is_product() ){
?>
<style type="text/css">
.comment-form-email{
display: none;
}
</style>
<?php
}
}
add_action( 'wp_head', 'hide_email_field_on_comment', 10, 1 );
Then you can modify single-product-reviews.php
and pass random email to value. so it will not give the required field error for email.
$fields = array(
'author' => array(
'label' => __( 'Name', 'woocommerce' ),
'type' => 'text',
'value' => $commenter['comment_author'],
'required' => $name_email_required,
),
'email' => array(
'label' => __( 'Email', 'woocommerce' ),
'type' => 'email',
'value' => 'test@test.com', // pass random email.
'required' => $name_email_required,
),
);
Now you have to remove email from comment when a comment is inserted. for that, you can use the preprocess_comment
filter hook.
function remove_dummy_email( $commentdata ){
unset( $commentdata['comment_author_email'] );
return $commentdata;
}
add_filter( 'preprocess_comment', 'remove_dummy_email', 10, 1 );
Related Topics
Woocommerce: Set Country by Default in Checkout Page
Fatal Error - 'Mongo' Class Not Found
Laravel No Supported Encrypter Found. the Cipher And/Or Key Length Are Invalid
Laravel Mail: Pass String Instead of View
Php: Split String into Array, Like Explode with No Delimiter
How to Upload Files in Laravel Directly into Public Folder
Creating an Array from a String Separated by Spaces
Get Filename of File Which Ran PHP Include
PHP SQL, Query Returns Only One Row of Data
How to Pass Custom Type Array to Postgres Function
Running a Zend Framework Action from Command Line
PHP Cli Getting Input from User and Then Dumping into Variable Possible
Fatal Error: Out of Memory, But I Do Have Plenty of Memory (Php)