[wp-trac] [WordPress Trac] #54114: paginate_links() ajax

WordPress Trac noreply at wordpress.org
Sun Sep 12 17:55:31 UTC 2021


#54114: paginate_links() ajax
--------------------------+-----------------------------
 Reporter:  Tkama         |      Owner:  (none)
     Type:  defect (bug)  |     Status:  new
 Priority:  normal        |  Milestone:  Awaiting Review
Component:  General       |    Version:  5.8.1
 Severity:  normal        |   Keywords:  has-patch
  Focuses:                |
--------------------------+-----------------------------
 `paginate_links()` may not work incorrectly for AJAX requests and other
 requests that pass `$_GET` parameters.

 Let's look how `paginate_links()` works in AJAX request handler function.
 I wrote a demo plugin:

 {{{#!php
 <?php
 /*
 Plugin Name: paginate_links() Bug
 */

 add_action( 'wp_ajax_' . 'paginate_links_test', 'paginate_links_test_ajax'
 );

 add_action(
         'admin_menu',
         function () {

                 add_options_page(
                         'paginate_links() test',
                         'paginate_links() test',
                         'manage_options',
                         'paglinkstest',
                         static function() {
                                 ?>
                         <script>
                                 jQuery( function( $ ){

                                         $( '#test_list' ).on( 'click', 'a
 .page-numbers', function( event ){

                                                 event.preventDefault()
                                                 let url =
 encodeURIComponent( this.getAttribute( 'href' ) )

                                                 $( '#test_list' )
                                                         .empty()
                                                         .load( `${ ajaxurl
 }?action=paginate_links_test&url=${ url }` )
                                         } )
                                 } )
                         </script>

                         <style>
                                 .pagination{ margin:3em; }
                                 .pagination > *{ padding:1em 2em; font-
 size:150%; }
                                 .pagination a:hover{ color:red;
 background:#fff; }
                         </style>

                         <div class="wrap">

                                 <h2><?php echo get_admin_page_title();
 ?></h2>

                                 <div id="test_list">
                                         <?php echo paginate_links_test();
 ?>
                                 </div>
                         </div>
                                 <?php
                         }
                 );
         }
 );


 function paginate_links_test( $page = null ) {

         $args = array(
                 'base'             => admin_url( 'options-
 general.php?page=paglinkstest&paged=%_%' ),
                 'format'           => '%#%',
                 'total'            => 20,
                 'current'          => max( 1, (int) ( $_GET['paged'] ??
 $page ?? 1 ) ),
                 'merge_query_vars' => false,
         );

         $pagination = paginate_links( $args );

         ?>
         <pre style="white-space: pre-wrap"><?php echo htmlspecialchars(
 $pagination ); ?></pre>
         <div class="pagination"><?php echo $pagination; ?></div>
         <?php

 }

 function paginate_links_test_ajax() {

         echo '<p>$_GET[url]: ' . $_GET['url'] . '</p>';

         wp_parse_str( wp_parse_url( $_GET['url'], PHP_URL_QUERY ),
 $query_vars );

         paginate_links_test( $query_vars['paged'] );

         exit;
 }

 }}}

 Let's install + activate this plugin, go to it's page (under settings menu
 item) and click on the pagination links:

 First paginate links looks good:

 `<a class="page-numbers" href="https://wp.dev/wp-admin/options-
 general.php?page=paglinkstest&paged=20">20</a>`

 But with each click the link to the page grows additional unnecessary
 parameters

 Second click:

 `<a class="page-numbers" href="https://wp.dev/wp-admin/options-
 general.php?page=paglinkstest&paged=20&action=paginate_links_test&url=https%3A%2F%2Fwp.dev
 %2Fwp-admin%2Foptions-
 general.php%3Fpage%3Dpaglinkstest%26paged%3D2">20</a>`

 Third:

 `<a class="page-numbers" href="https://wp.dev/wp-admin/options-
 general.php?page=paglinkstest&paged=20&action=paginate_links_test&url=https%3A%2F%2Fwp.dev
 %2Fwp-admin%2Foptions-
 general.php%3Fpage%3Dpaglinkstest%26paged%3D3%26action%3Dpaginate_links_test%26url%3Dhttps%253A%252F%252Fwp.dev
 %252Fwp-admin%252Foptions-
 general.php%253Fpage%253Dpaglinkstest%2526paged%253D2">20</a>`

 This happens because paginate_links() forcibly add current request $_GET
 parameters to each pagination link and we have no way to disable this
 behavior. So we can't normally use paginate_links() in AJAX requests in
 some circumstance.

 **The best solution** is to somehow cut out the merge of additional
 parameters, because this function is designed to build pagination links
 based on the passed data and this side effect only spoils everything. But
 I don't know what it is about backward compatibility.

 **So, the easiest solution** is to add additional argument to
 paginate_links(), which allow to disable merge of additional GET
 parameters.

 It will at least allow to use this function in AJAX requests and any other
 requests, where it's not necessary to add request parameters to pagination
 links.

-- 
Ticket URL: <https://core.trac.wordpress.org/ticket/54114>
WordPress Trac <https://core.trac.wordpress.org/>
WordPress publishing platform


More information about the wp-trac mailing list