排名靠前的帖子平均评级问题

时间:2020-01-08 作者:Shoaib Saleem

我试图显示最高评级的职位,cpt与平均评级值。我为此创建了自定义小部件。默认情况下,wp post数据和平均值显示正确,但类似CPT的电影post未显示正确的平均值。我使用以下代码来实现这一点。需要帮助

public function widget( $args, $instance ) {
$title          = apply_filters( \'widget_title\', $instance[\'title\'] );
$posttype       = $instance[\'posttype\'];
$postsperpage   = $instance[\'postsperpage\'];
$postorder      = $instance[\'postorder\'];
$avgrt_pos      = $instance[\'avgrt_pos\'];
$image          = $instance[ \'showimage\' ] ? \'true\' : \'false\';
$avgrt_img      = $instance[ \'avgrt_star\' ];

// before and after widget arguments are defined by themes
echo $args[\'before_widget\'];
if ( ! empty( $title ) )
echo $args[\'before_title\'] . $title . $args[\'after_title\'];


global $wpdb, $post;

    $results = $wpdb->get_results("SELECT DISTINCT({$wpdb->prefix}comments.comment_post_ID), GROUP_CONCAT({$wpdb->prefix}comments.comment_ID separator \', \') comment_ids FROM {$wpdb->prefix}comments JOIN {$wpdb->prefix}commentmeta ON {$wpdb->prefix}commentmeta.comment_id = {$wpdb->prefix}comments.comment_ID 
     WHERE {$wpdb->prefix}comments.comment_approved = 1 GROUP BY {$wpdb->prefix}comments.comment_post_ID", ARRAY_A);



    foreach($results as $key => $value) 
    {
          $c_post_id = $value[\'comment_post_ID\'];
          $comment_ids = $value[\'comment_ids\'];
          $res = $wpdb->get_results( "SELECT AVG(`meta_value`) as avg_rate FROM {$wpdb->prefix}commentmeta WHERE `meta_key` = \'rating\' AND `meta_value` != \'\' AND comment_ID IN ($comment_ids) ORDER BY meta_value" );

          $results[$key][\'avg_rate\'] = $res[0]->avg_rate;
          //var_dump($res);
    }

    # sort value by high rated
    if($postorder==\'DESC\'){
        $sortOrder = SORT_DESC;
    }else{
        $sortOrder = SORT_ASC;
    }
    # avg stars
    if($avgrt_img==\'avgrt_str1\'){
        $avgrt_img = \'star-1\';
    }elseif($avgrt_img==\'avgrt_str2\'){
        $avgrt_img = \'star-2\';
    }elseif($avgrt_img==\'avgrt_str3\'){
        $avgrt_img = \'star-3\';
    }elseif($avgrt_img==\'avgrt_str4\'){
        $avgrt_img = \'star-4\';
    }elseif($avgrt_img==\'avgrt_str5\'){
        $avgrt_img = \'star-5\';
    }elseif($avgrt_img==\'avgrt_str6\'){
        $avgrt_img = \'star-6\';
    }else{
        $avgrt_img = \'star-1\';
    }



    $avg_rate = array_column($results, \'avg_rate\');
    array_multisort($avg_rate, $sortOrder, $results);


    $top_rated = array();
    foreach ($results as $result) 
    {

        if($result[\'avg_rate\'] && $result[\'comment_ids\'] )
        {
            $top_rated[] = $result[\'comment_post_ID\'];
         }

    }


   $args = array(
      \'post_type\' => $posttype,
      \'posts_per_page\' => $postsperpage,
      \'post__in\' => $top_rated,
      \'orderby\' => \'post__in\',
      \'post_status\' => \'publish\', 
   );

  $top_rated_posts = new WP_Query( $args );
    //var_dump($top_rated_posts);
  // The Loop
  if ( $top_rated_posts->have_posts() ) 
  {
     echo \'<div class="wpcr_top_rated_container"><ul>\';
     $i=0;
     while ( $top_rated_posts->have_posts() ) 
     {
        $top_rated_posts->the_post();
        $postid= get_the_ID();

            /* grab the url for the full size featured image */
            $featured_img_url = get_the_post_thumbnail_url(get_the_ID(),\'thumbnail\');
            $get_post_link = get_permalink();

            if($image == \'true\'){
                if(!empty($featured_img_url)){
                    $feaimage = \'<a href="\'.esc_url($get_post_link).\'"><img src="\'.esc_url($featured_img_url).\'" alt=""></a>\';
                }else {
                    $feaimage = \'\';
                }
            }   
            $topr_desc = get_the_content();
            $words = 15;
            $more = \' […]\';
            $excerpt = wp_trim_words( $topr_desc, $words, $more );

            $avgrating = \'<div class="wpcr_aggregate"><a class="wpcr_inline" title=""><span class="wpcr_averageStars_tprt \'.$avgrt_img.\'" data-wpcravg="\'.number_format((float)$results[$i][\'avg_rate\'], 2, \'.\', \'\').\'"></span></a><span class="avg-inline">\'.number_format((float)$results[$i][\'avg_rate\'], 2, \'.\', \'\').\'</span></div>\';

                    //var_dump($results[$i][\'avg_rate\']);   

            if($avgrt_pos == \'before\'){
                $avg_bef = $avgrating;
            }
            if($avgrt_pos == \'after\'){
                $avg_aft = $avgrating;
            }

                $output = \'<li>\';
                $output .= \'<div class="left">\'.$feaimage.\'</div>\';
                $output .= \'<div class="right"><a href="\'.esc_url($get_post_link).\'"><span class="wpcr_title" title="">\'.get_the_title().\'</span></a>\';
                $output .= $avg_bef.\'<div class="desc">\'.$excerpt.\'</div>\'.$avg_aft.\'</div></li>\';
                echo $output;
        $i++;
    }
    echo \'</ul></div>\';

    wp_reset_query();
  } else {
    echo \'Sorry, no post found.\';
  }

 echo $args[\'after_widget\'];
}
屏幕截图

enter image description here

enter image description here

1 个回复
SO网友:Tom J Nowell

您的代码使用以下内容:

number_format((float)$results[$i][\'avg_rate\'], 2, \'.\', \'\')
如果我们看看$i 设置后,我们在循环之前看到:

     $i=0;
还有这个:

        $i++;
但我看不出在有条件的情况下,这如何以任何方式映射到当前帖子,这意味着并非结果数组中的所有内容都包含在帖子查询中。

相反,不要使用$i, 使用post ID,并将post ID存储为键。

进一步说明:

这不会按比例扩展,因为帖子数量增加,查询速度会变慢,而评级数量增加,查询速度会变慢。2倍的帖子并不意味着两倍的速度慢,它会变得更快。当没有太多数据时,速度会很快,之后会逐渐停止wp_reset_query 这里没有位置。除非你正在使用query_posts 不要使用它。也许你想用wp_reset_postdata?$wpdb->prepare 如果是你的朋友,请清理这些查询并使其安全。有很多不必要的变量,例如,为什么要使用$output? 只需回显它们并节省另一个变量的工作量,这是对资源的浪费,在读取和键入时会增加开销,而且没有任何好处$avg_bef$avg_aft 仅当选择该位置时才分配,这将生成PHP警告(在PHP 8中,将生成PHP fatals),事先为其分配一个默认值$avg_bef = \'\'; 等等,不要只是凭空把它们拉出来

相关推荐

Comments.php保留评论日期/时间,但删除日期/时间的#超级链接

我在谷歌上搜索了这个问题,似乎找不到解决方案。。。在评论中,我试图从评论日期/时间中删除超链接,当您将鼠标悬停在评论日期上方时,它会将超链接(示例/#comment-210)链接到以下评论。。。我可以在函数中输入什么。php删除链接,我想保留日期/时间文本。。