WordPress.org

Ideas

Fill last page of comments

  1. Frank Strack
    Inactive

    Margje - I updated the code this morning to work with WP 4.4. I can't attest to its efficiency but it does work as expected again.

    <br />
    <?php<br />
    /*<br />
    Plugin Name: Fix Reversed Comments Pagination<br />
    Plugin URI: http://winkpress.com/articles/fix-reversed-comments-pagination/<br />
    Description: Fixes a problem with reversed comments pagination. See <a href="http://winkpress.com/articles/fix-reversed-comments-pagination/">this</a> for more details.<br />
    Author: WinkPress<br />
    Version: 1.0<br />
    Author URI: http://winkpress.com/<br />
    */<br />
    function wink_good_discussion_settings()<br />
    {<br />
      // If comments are not paginated<br />
      if (!get_option('page_comments'))<br />
        return false;</p>
    <p>  // If comments are not newer to oldest<br />
      //if (get_option('comment_order') != 'desc')<br />
      //  return false;</p>
    <p>  // If last page not displayed first<br />
      if (get_option('default_comments_page') != 'newest')<br />
        return false;</p>
    <p>  // Otherwise,<br />
      return true;<br />
    }</p>
    <p>if (wink_good_discussion_settings()):</p>
    <p>add_action('comment_form', 'wink_comment_redirect');<br />
    add_filter('comment_post_redirect', 'wink_comment_redirect', 99, 2);</p>
    <p>function wink_comment_redirect($location = '', $comment = null)<br />
    {<br />
      if (!$comment)<br />
      {<br />
        $cpage = get_query_var('cpage');<br />
        $link = get_comments_pagenum_link( $cpage );<br />
        $link = str_replace('#comments', '', $link);<br />
        echo "<input type='hidden' value='$link' name='redirect_to' />";<br />
      }<br />
      else<br />
      {<br />
        if ($comment->comment_parent == 0)<br />
        {<br />
          $location = get_permalink($comment->comment_post_ID);<br />
          $location .= '#comment-' . $comment->comment_ID;<br />
        }</p>
    <p>    return $location;<br />
      }<br />
    }</p>
    <p>class Walker_Comment_Wink extends Walker_Comment<br />
    {<br />
      /*<br />
       This is copied from class-wp-walker.php and modified slightly.<br />
       Thanks to jpowermacg5 from irc://irc.freenode.net/php for helping<br />
       me figure this out!<br />
      */<br />
      function paged_walk( $elements, $max_depth, $page_num, $per_page ) {</p>
    <p>	global $id;<br />
        global $cpage; </p>
    <p>    /* sanity check */<br />
        if ( empty($elements) || $max_depth < -1 )<br />
          return '';</p>
    <p>	$per_page = get_option('comments_per_page');</p>
    <p>    $args = array_slice( func_get_args(), 4 );<br />
        $output = '';</p>
    <p>    $id_field = $this->db_fields['id'];<br />
        $parent_field = $this->db_fields['parent'];</p>
    <p>    $count = -1;<br />
        if ( -1 == $max_depth )<br />
          $total_top = dm_comment_count( $count ); //count( $elements );<br />
        if ( $page_num < 1 || $per_page < 0  ) {<br />
          // No paging<br />
          $paging = false;<br />
          $start = 0;<br />
          if ( -1 == $max_depth )<br />
            $end = $total_top;<br />
          $this->max_pages = 1;<br />
        } else {<br />
          $paging = true;<br />
          $start = ( (int)$page_num - 1 ) * (int)$per_page;<br />
          $end   = $start + $per_page;<br />
          if ( -1 == $max_depth )<br />
            $this->max_pages = ceil($total_top / $per_page);<br />
        }</p>
    <p>	// flat display<br />
        if ( -1 == $max_depth ) {</p>
    <p>      //$page_num = 1 + ceil($total_top / $per_page);</p>
    <p>      if( $cpage=='' || empty($cpage)) 	$page_num = get_comment_pages_count();<br />
          else								$page_num = $cpage;</p>
    <p>        if ( !empty($args[0]['reverse_top_level']) ) {<br />
                $top_level_elements = array_reverse( $top_level_elements );</p>
    <p>            $start = ($page_num - 1) * $per_page;<br />
                $end = $start + $per_page;<br />
            } else {<br />
                $start = ((($page_num - 1) * $per_page) - $per_page) + ($total_top % $per_page); //$total_top - ($page_num) * $per_page; //($total_top - $per_page);// + ($total_top % $per_page); //$total_top - ($page_num) * $per_page;<br />
                $end = $start + $per_page;<br />
          }</p>
    <p>    $commargs = array(<br />
    		'status' => 'approve',<br />
    		'number' => ($start >= 0 ? $per_page : ($per_page + $start)),<br />
    		'post_id' => $id,<br />
    		'offset' => ($start >= 0 ? $start : 0),<br />
    		'type' => 'comment',<br />
    		'order' => 'ASC'<br />
    	);</p>
    <p>	$elements = get_comments($commargs);</p>
    <p>	  /*echo "<br />
    <pre>";
    	  print_r($commargs);
    	  echo "</pre>
    ";</p>
    <p>	  echo "page_num: " . $page_num . "<br />";<br />
          echo "total_top: " . $total_top . "<br />";<br />
          echo "per_page: " . $per_page . "<br />";<br />
          echo "per_page: " . $total_top % $per_page . "<br />";</p>
    <p>	  echo "Start: $start<br />";<br />
    	  echo "End: $end<br />";*/</p>
    <p>      $empty_array = array();<br />
          foreach ( $elements as $e ) {<br />
            $count++;</p>
    <p>        $this->display_element( $e, $empty_array, 1, 0, $args, $output );<br />
          }<br />
          return $output;<br />
        }</p>
    <p>    /*<br />
         * separate elements into two buckets: top level and children elements<br />
         * children_elements is two dimensional array, eg.<br />
         * children_elements[10][] contains all sub-elements whose parent is 10.<br />
         */<br />
        $top_level_elements = array();<br />
        $children_elements  = array();<br />
        foreach ( $elements as $e) {<br />
          if ( 0 == $e->$parent_field )<br />
            $top_level_elements[] = $e;<br />
          else<br />
            $children_elements[ $e->$parent_field ][] = $e;<br />
        }</p>
    <p>    $total_top = count( $top_level_elements );<br />
        if ( $paging )<br />
          $this->max_pages = ceil($total_top / $per_page);<br />
        else<br />
          $end = $total_top;</p>
    <p>    if ( !empty($args[0]['reverse_top_level']) ) {<br />
          $top_level_elements = array_reverse( $top_level_elements );</p>
    <p>      $page_num = 1 + ceil($total_top / $per_page) - $page_num;</p>
    <p>      $start = ($page_num - 1) * $per_page;<br />
          $end = $start + $per_page;<br />
        }</p>
    <p>    if ( !empty($args[0]['reverse_children']) ) {<br />
          foreach ( $children_elements as $parent => $children )<br />
            $children_elements[$parent] = array_reverse( $children );<br />
        }</p>
    <p>    foreach ( $top_level_elements as $e ) {<br />
          $count++;</p>
    <p>      //for the last page, need to unset earlier children in order to keep track of orphans<br />
          if ( $end >= $total_top && $count < $start )<br />
              $this->unset_children( $e, $children_elements );</p>
    <p>      if ( $count < $start )<br />
            continue;</p>
    <p>      if ( $count >= $end )<br />
            break;</p>
    <p>      $this->display_element( $e, $children_elements, $max_depth, 0, $args, $output );<br />
        }</p>
    <p>    if ( $end >= $total_top && count( $children_elements ) > 0 ) {<br />
          $empty_array = array();<br />
          foreach ( $children_elements as $orphans )<br />
            foreach( $orphans as $op )<br />
              $this->display_element( $op, $empty_array, 1, 0, $args, $output );<br />
        }</p>
    <p>    return $output;<br />
      }<br />
    }<br />
    endif;</p>
    <p>
    Posted: 2 years ago #
  2. treibstoff
    Member

    hello Frank,

    I replaced my original one (producing a Division by zero Error since WP4.4) with your new code...but just got this:
    Fatal error: Call to undefined function dm_comment_count() in /fix-reversed-comments-pagination.php on line 80:

    $total_top = dm_comment_count( $count ); //count( $elements );

    I was using this code before:
    https://github.com/wp-plugins/fix-reversed-comments-pagination/blob/master/fix-reversed-comments-pagination.php

    you find a solution???

    thanx thomas

    Posted: 2 years ago #
  3. jumbo
    Inactive

    Hi Frank,

    Thanks for trying to troubleshoot that plugin, but it doesn't appear to work.

    The problem appears to be here (in your modified plugin and the original):

    function paged_walk( $elements

    The $elements argument pre-WordPress 4.4 used to deliver the entire array of comments, from all pages. Now it just delivers what's meant to be shown on that page.

    For instance, let's say the WordPress discussion settings are set to show two comments per page, and there are 7 top-level comments total. So that would be a total of 4 paginated comments:

    page 1: 1 comment
    page 2: 2 comments
    page 3: 2 comments
    page 4: 2 comments

    With WordPress 4.3.1 and prior, the $elements array would pass all 7 comments, then the plugin would shift around the comment rendering loop start and end points to force the last page to always be filled up.

    Since WordPress 4.4, the $elements array would only pass the maximum number of comments per page allowed, which in this example would be two. If it were still passing all 7 comments, then a fix within the plugin would be possible.

    So there doesn't appear to be a fix possible for the plugin itself, because it's never going to be passed the full array of $elements to work on.

    This change is happening outside the plugin's ecosystem, and the fix needs to be found elsewhere.

    This seems to be part of WordPress 4.4 trying to more efficiently query and render comments, as discussed here:
    https://make.wordpress.org/core/2015/10/28/comment-object-and-query-features-in-4-4/

    So, the question is, how can we get the $elements array to send the full list of comments, as it was in WordPress 4.3.1 and prior?

    By the way (this doesn't really impact anything), the comment object that's part of the $elements array has changed from 'stdClass Object' to 'WP_Comment_Object'

    Posted: 2 years ago #
  4. jumbo
    Inactive

    The action appears to be happening in:

    /wp-includes/comment-template.php

    Within the following function:

    comments_template()

    That's the part of core that was changed with WordPress 4.4 that resulted in the following plugin no longer working:
    https://wordpress.org/plugins/fix-reversed-comments-pagination/

    The following trac discussion documents the change.
    https://core.trac.wordpress.org/ticket/8071

    Posted: 2 years ago #
  5. tinyCoder
    Member

    Hey, you guys found a solution for this yet?

    Thanks for letting us know if any solution available.

    Posted: 1 year ago #
  6. @ M.K. Safi, old but Gold. It works very fine. Thank you!

    Posted: 1 year ago #
  7. tinyCoder
    Member

    @schwerlastregal, what worked??

    It didn't work for me, can you please post more details?

    Thanks!

    Posted: 1 year ago #
  8. margje
    Member

    +1 for me, didn't work for me neither

    Posted: 1 year ago #
  9. gavsiu
    Member

    Still looking for a solution to an age old problem. Who want's the last page not to be completely filled when there are paged comments and sorted by newest anyway?

    I don't even care if WordPress has to update the comment permalinks and that they don't fall on the same comment page as when sorted by older.

    Posted: 1 year ago #
  10. Any solution here yet?
    The plugin that was suggested above still hasn't been updated (in 7 years.. :D So I guess it's unlikely anything will happen there)

    Posted: 3 months ago #

RSS feed for this topic

Reply

You must log in to post.

  • Rating

    12345
    9 Votes
  • Status

    This idea is under consideration