Display some WooCommerce product reviews with limited content length randomly - php

I am making shortcode for reviews Based on WooCommerce: Display some reviews randomly on home page to put on other pages. How can i limit reviews by character numbers, like 100 or 200 characters. SO they will not be too long and fit any page.
I am using following code for reviews now
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');

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.

Related

Problem with query products in WooCommerce with category argument in WP_Query

I tried to query products by WP_query and it was all fine. But when i tried query it with category argument nothing happenned. When i trying add new shortcode with category args it doesn't work too. I can't see where the problem is. I don't think that swiper.js could make a error. When i enter empty 'category_name' it shows all products. Others argument work as they should
function test_short($attr) {
$content = '';
$content .= "<script src='https://unpkg.com/swiper/swiper-bundle.min.js'></script>";
$sharg = shortcode_atts( array(
'cat' => '',
), $attr );
$args = array(
'post_type' => 'product',
'category_name' => 'gry',
'suppress_filters' => true
);
$wc_query = new WP_Query($args);
$content .= '<div class="swiper slidee">
<div class="swiper-wrapper">';
if($wc_query->have_posts()) {
while($wc_query->have_posts()) {
$content .= '<div class="swiper-slide">';
$wc_query->the_post();
$id = get_the_ID();
$url = wp_get_attachment_image_src(get_post_thumbnail_id($id), 'full')[0];
$content .= '<img class="product_img" src="'.$url.'">';
$title = get_the_title();
$content .= "<div class='title'>".$title."</div>";
$product = wc_get_product( $id );
$content .= number_format(($product->get_price()),2)." zł";
$content .= '
<div class="koszyk_ikona"></div><div class="koszyk_tekst">Dodaj do koszyka</div>
';
$content .= '</div>';
}
}
$content .= '
</div>
<div class="swiper-button-next"></div>
<div class="swiper-button-prev"></div>
</div';
$content .= "<script>";
$content .= file_get_contents(get_site_url().'/javascript.js');
$content .= "</script>";
$content .= '<script type="text/javascript"> var swiper = new Swiper(".slidee", {
slidesPerView: 3.5,
spaceBetween: 30,
autoplay: {
delay: 3000,
},
speed: 1700,
navigation: {
nextEl: ".swiper-button-next",
prevEl: ".swiper-button-prev"
}
});
</script>';
wp_reset_query();
return $content;
}
add_shortcode("test_short","test_short");
EDIT!!!!
I discovered that no of my products have category when i check them by get_the_category(). How is possible when i added them to category and at products admin panel they all have some of category
$category = array('Clothing', 'Bed');
$args = array(
'posts_per_page' => -1,
'post_type' => 'product',
'tax_query' => array(
array(
'taxonomy' => 'product_cat',
'field' => 'name',
'terms' => $category
)
)
);
$loop = new WP_Query($args);
if ($loop->have_posts()):
while ($loop->have_posts()) : $loop->the_post();
global $product;
echo '<pre>';
print_r($product->get_name());
echo '</pre>';
endwhile;
endif;

WooCommerce: Display some 5 stars rating products reviews randomly

Based on WooCommerce: Display some reviews randomly on home page answer code, I am using the following code that shows 5 random reviews:
function get_woo_reviews()
{
$comments = get_comments(
array(
'status' => 'approve',
'post_status' => 'publish',
'post_type' => 'product',
)
);
shuffle($comments);
$comments = array_slice( $comments, 0, 5 );
$html = '<ul>';
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>';
endforeach;
$html .= '</ul>';
ob_start();
echo $html;
$html = ob_get_contents();
ob_end_clean();
return $html;
}
add_shortcode('woo_reviews', 'get_woo_reviews');
But It also shows some comments without any rating.
How to change this code to show only 5 star rating reviews?
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.

add shortcode heading showing multiple time

Hi my code is below for adding shortcode in posts. when i am adding shortcode two times it shows me heading two times that i added in code "Recent Posts" is there is way to show this heading only top means one time?
/*shortcode start*/
add_shortcode( 'recent-posts', 'PL_recent_posts' );
function PL_recent_posts( $atts ) {
extract( shortcode_atts( array(
'numbers' => '5',
'order' => 'ASC',
), $atts ) );
$rposts = new WP_Query( array( 'posts_per_page' => $numbers, 'orderby' => 'date' , 'colorss' => $color ) );
if ( $rposts->have_posts() ) {
$html = '<h3>Recent Posts</h3><ul class="recent-posts">';
while( $rposts->have_posts() ) {
$rposts->the_post();
$html .= sprintf(
'<li>%s</li>',
get_permalink($rposts->post->ID),
get_the_title(),
get_the_title()
);
}
$html .= '</ul>';
}
wp_reset_query();
return $html;
}
Define a global variable to detect whether title is already added.
function PL_recent_posts( $atts ) {
global $title_added;
...
if ( $rposts->have_posts() ) {
if ( $title_added ) {
$html = '<ul class="recent-posts">';
} else {
$html = '<h3>Recent Posts</h3><ul class="recent-posts">';
$title_added = true;
}
Hope that helps..!

Function paginate_links within a short code not showing where it should be

I created a short code to display a list of Projects, which they are in a custom post type "Projects". The short code is simply displaying the projects and I want to include the pagination within the short code. Everything is working well, except that the pagination is showing BEFORE the list of projects, it should output after the list.
Everything will work if it's built-in in a custom page template. But of I use the short code, it won't output the way it should.
Here is the short code PHP code :
if (!function_exists('shortcode_projects_list')) {
function shortcode_projects_list($atts, $content = null) {
global $wp_query;
global $options;
$args = array(
"type" => "standard",
"order_by" => "date",
"order" => "DESC",
"number" => "-1",
"category" => "",
"selected_projects" => ""
);
extract(shortcode_atts($args, $atts));
$html = "";
$_type_class = '';
$_portfolio_space_class = '';
if ($type == "standard"){
$_type_class = " standard";
$_portfolio_space_class = "portfolio_with_space";
} elseif ($type == "standard_no_space"){
$_type_class = " standard_no_space";
$_portfolio_space_class = "portfolio_no_space";
}
if($type != 'standard_no_space') {
$html .= "<div class='block-grid $_portfolio_space_class cf'>\n";
if (get_query_var('paged')) {
$paged = get_query_var('paged');
} elseif (get_query_var('page')) {
$paged = get_query_var('page');
} else {
$paged = 1;
}
if ($category == "") {
$args = array(
'post_type' => 'projects',
'orderby' => $order_by,
'order' => $order,
'posts_per_page' => $number,
'paged' => $paged
);
} else {
$args = array(
'post_type' => 'projects',
'projects_cat' => $category,
'orderby' => $order_by,
'order' => $order,
'posts_per_page' => $number,
'paged' => $paged
);
}
$project_ids = null;
if ($selected_projects != "") {
$project_ids = explode(",", $selected_projects);
$args['post__in'] = $project_ids;
}
query_posts($args);
if (have_posts()) : while (have_posts()) : the_post();
$terms = wp_get_post_terms(get_the_ID(), 'projects_cat');
$project_bg_color = get_post_meta(get_the_ID(), 'sbwp_project_bg_color', true);
$project_text_color = get_post_meta(get_the_ID(), 'sbwp_project_text_color', true);
$html .= "<article class='block-item third-width third-height cf";
foreach ($terms as $term) {
$html .= " portfolio_category_$term->term_id";
}
$title = get_the_title();
$excerpt = get_the_excerpt();
$post_featured_image = get_post_thumbnail_id(get_the_ID());
if ($post_featured_image) {
$project_thumbnail = wp_get_attachment_image_src( $post_featured_image, 'full', false);
if ($project_thumbnail) (string)$project_thumbnail = $project_thumbnail[0];
}
$custom_portfolio_link = get_post_meta(get_the_ID(), 'qode_portfolio-external-link', true);
$portfolio_link = $custom_portfolio_link != "" ? $custom_portfolio_link : get_permalink();
$target = $custom_portfolio_link != "" ? '_blank' : '_self';
$html .="' style='background-color: ".$project_bg_color."'>";
$html .= "<a href='".$portfolio_link."' rel='bookmark' title='".$title."'>";
$html .= "<div class='image' style='background-image: url(".$project_thumbnail.");'></div>";
$html .= "<div class='text ".$project_text_color."'>";
$html .= "<p>".$excerpt."</p>";
$html .= "<span class='line ".$project_text_color."'></span>";
$html .= "<h1>".$title."</h1>";
$html .= "</div>";
$html .= "</a>";
$html .= "</article>\n";
endwhile;
$html .= "</div>";
$html .= "<div class='m-all t-all d-all last_col cf'>";
$html .= bones_page_navi();
$html .= "</div>";
else:
?>
<p><?php _e('Sorry, no posts matched your criteria.', 'sbwp'); ?></p>
<?php
endif;
$html .= "</div>";
wp_reset_query();
}
return $html;
}
}
Here is the bones_page_navi() function :
function bones_page_navi() {
global $wp_query;
$bignum = 999999999;
if ( $wp_query->max_num_pages <= 1 )
return;
echo '<nav class="pagination">';
echo paginate_links( array(
'base' => str_replace( $bignum, '%#%', esc_url( get_pagenum_link($bignum) ) ),
'format' => '',
'current' => max( 1, get_query_var('paged') ),
'total' => $wp_query->max_num_pages,
'prev_text' => '←',
'next_text' => '→',
'type' => 'list',
'end_size' => 3,
'mid_size' => 3
) );
echo '</nav>';
} /* end page navi */
The HTML output when using the short code can been seen here.
The pagination links (nav) should output within the div under the div with the block-grid class.
Thanks in advance !
That's because the navigation is echoed, not returned.
function bones_page_navi() {
global $wp_query;
$bignum = 999999999;
if ( $wp_query->max_num_pages <= 1 )
return;
$output = '';
$output .= '<nav class="pagination">';
$output .= paginate_links( array(
'base' => str_replace( $bignum, '%#%', esc_url( get_pagenum_link($bignum) ) ),
'format' => '',
'current' => max( 1, get_query_var('paged') ),
'total' => $wp_query->max_num_pages,
'prev_text' => '←',
'next_text' => '→',
'type' => 'list',
'end_size' => 3,
'mid_size' => 3
) );
$output .= '</nav>';
return $output;
} /* end page navi */

Customising excerpt in theme

I've been reading a lot of how to customize excerpt function in WordPress but I have no idea how to proceed with this.
The theme that I am using already have 4 pre-customized excerpt functions and the one that I will show here is closest to my desired but still needs to improve.
My question is how to stop erasing HTML formating from my content (line breaks, paragraphs, font variants, etc)?
add_shortcode('display_news_s5', 'be_display_posts_shortcode5');
function be_display_posts_shortcode5($atts) {
// Pull in shortcode attributes and set defaults
extract( shortcode_atts( array(
'post_type' => 'post',
'post_parent' => false,
'id' => false,
'tag' => '',
'category' => '',
'offset' => 0,
'posts_per_page' => '1',
'order' => 'DESC',
'orderby' => 'date',
'include_date' => false,
'include_excerpt' => false,
'excerpt_l' => 8,
'taxonomy' => false,
'tax_term' => true,
'tax_operator' => 'IN'
), $atts ) );
// Set up initial query for post
$args = array(
'post_type' => explode( ',', $post_type ),
'tag' => $tag,
'category_name' => $category,
'p' => $id,
'posts_per_page' => $posts_per_page,
'order' => $order,
'orderby' => $orderby,
'offset' => $offset
);
// If Post IDs
if( $id ) {
$posts_in = explode( ',', $id );
$args['post__in'] = $posts_in;
}
// If taxonomy attributes, create a taxonomy query
if ( !empty( $taxonomy ) && !empty( $tax_term ) ) {
// Term string to array
$tax_term = explode( ', ', $tax_term );
// Validate operator
if( !in_array( $tax_operator, array( 'IN', 'NOT IN', 'AND' ) ) )
$tax_operator = 'IN';
$tax_args = array(
'tax_query' => array(
array(
'taxonomy' => $taxonomy,
'field' => 'slug',
'terms' => $tax_term,
'operator' => $tax_operator
)
)
);
$args = array_merge( $args, $tax_args );
}
// If post parent attribute, set up parent
if( $post_parent ) {
if( 'current' == $post_parent ) {
global $post;
$post_parent = $post->ID;
}
$args['post_parent'] = $post_parent;
}
$listing = new WP_Query( apply_filters( 'display_posts_shortcode_args', $args, $atts ) );
$count = 0;
if ( !$listing->have_posts() )
return apply_filters ('display_posts_shortcode_no_results', false );
$inner = '';
while ( $listing->have_posts() ): $listing->the_post(); global $post;
$count++;
if( $count == 1 ){
$style = ' news-main-post';
} else {
$style = ' news-list-posts';
}
$title = '<div class="news-listing-title"><a class="title" href="'. get_permalink() .'">'. get_the_title() .'</a></div>';
if ($include_date == 'true') $date = ' <div class="news-listing-meta"><span class="news-listing-date">'. get_the_date() . '</span><span class="news-listing-comment">('. get_comments_number() .')</span></div>';
else $date = '';
if ($include_excerpt == 'true') $excerpt = '<span>' .excerpt($excerpt_l) . '</span>';
else $excerpt = '';
$output = '<div class="news-listing' . $style . '"><div class="news-listing-item">'. $title . $excerpt . $date . '</div></div>';
$inner .= apply_filters( 'display_posts_shortcode_output', $output, $atts, $title, $excerpt, $date );
endwhile; wp_reset_query();
$open = apply_filters( 'display_posts_shortcode_wrapper_open', '<div class="news-listing-wrapper-s3">' );
$close = apply_filters( 'display_posts_shortcode_wrapper_close', '<div class="clear"></div></div>' );
$return = $open . $inner . $close;
return $return;
}
Have a look here: LINK looks like its doing what you want to acchieve.

Categories