1

I created simple custom WordPress plugin for a client in 2016 that simply displays a paginated list of results queried from a custom table.

try {

    $recordcountquery = 'SELECT
            FName,LName
        FROM
            tblBurialRegister WHERE';
    
    if (!empty($_SESSION['firstname']))
    {
        $cond = $mydb->prepare(' FName = %s', $_SESSION['firstname']);
        $recordcountquery .= $cond; 
    }
    if (!empty($_SESSION['lastname']) && !empty($_SESSION['firstname'])) 
    {
        $recordcountquery .= ' and';
    }
    if (!empty($_SESSION['lastname']))
    {
        $cond = $mydb->prepare(' LName = %s', $_SESSION['lastname']);
        $recordcountquery .= $cond;
    }
    $countresults = $mydb->get_results($recordcountquery);
    $total = count($countresults);

// How many items to list per page
    $limit = 20;

    // How many pages will there be
    $pages = ceil($total / $limit); 
    // What page are we currently on?
    $page = get_query_var('page');
    
    if($page == 0)
    {
    $page = 1;
    }   
    
    // Calculate the offset for the query
    $offset = ($page - 1)  * $limit;
        // Some information to display to the user
    $start = $offset + 1;
    $end = min(($offset + $limit), $total);

    // The "back" link
    $prevlink = ($page > 1) ? '<a href="?page=1" title="First page">&laquo;</a> <a href="?page=' . ($page - 1) . '" title="Previous page">&lsaquo;</a>' : '<span class="disabled">&laquo;</span> <span class="disabled">&lsaquo;</span>';

    // The "forward" link
    $nextlink = ($page < $pages) ? '<a href="?page=' . ($page + 1) . '" title="Next page">&rsaquo;</a> <a href="?page=' . $pages . '" title="Last page">&raquo;</a>' : '<span class="disabled">&rsaquo;</span> <span class="disabled">&raquo;</span>';
    

if (count($countresults) > 0)
    {
echo "<span id='results' class='top-offset'></span><p style='font-size:x-large;'>Showing results for: ".$_SESSION['firstname']." ".$_SESSION['lastname']."</p><br/>";

    // Display the paging information
    echo '<div id="paging" class="paging-text" style="font-size: large;"><p>', $prevlink, ' Page ', $page, ' of ', $pages, ' pages, displaying ', $start, '-', $end, ' of ', $total, ' results ', $nextlink, ' </p></div>';
    }
    
    $query = 'SELECT
            ID,NUM,FName,LName,AGE,DATEBORN,DDate
        FROM
            tblBurialRegister WHERE';
    
    if (!empty($_SESSION['firstname']))
    {
        $cond = $mydb->prepare(' FName = %s', $_SESSION['firstname']);
        $query .= $cond;    
    }
    if (!empty($_SESSION['lastname']) && !empty($_SESSION['firstname'])) 
    {
        $query .= ' and';
    }
    if (!empty($_SESSION['lastname']))
    {
        $cond = $mydb->prepare(' LName = %s', $_SESSION['lastname']);
        $query .= $cond;
    }
    
    $query .= ' ORDER BY
            LName,FName
        LIMIT '
            . $limit .
        ' OFFSET '
            . $offset .'';
    
    $results = $mydb->get_results($query);
    
    
    
    // Do we have any results?
    if (count($results) > 0) {
        echo "<div style='overflow-x:auto;'><table style='font-size:large;'><th>First Name</th><th>Last Name</th><th>AGE</th><th></th>";
        foreach ($results as $obj) :
        
        $age = $obj->AGE;
        if(empty($age))
        {
            $age = 'Unknown';
        }
        $bdate = $obj->DATEBORN;
        if(empty($bdate))
        {
            $bdate = 'Unknown';
        }
        $ddate = $obj->DDate;
        if(empty($ddate))
        {
            $ddate = 'Unknown';
        }
        
        echo "<tr><td>".$obj->FName."</td><td>".$obj->LName."</td><td>".$age."</td><td><form method='post' action='http://www.website.com/record-search-details/'><button id='myBtn' class='et_pb_contact_submit et_pb_button rsButton' style='color: #424892!important;
    border-color: #424892;' type='submit' name='RecordDetails' value=".$obj->ID.">Details</button></form></td></tr>";
    endforeach;
    echo "</table></div>";
    } else {
        echo '<p>No results found.</p>';
    }

} catch (Exception $e) {
    echo '<p>', $e->getMessage(), '</p>';
}

This code has not been touched since it's release and has been working. They reported to me in the last few months that the pagination is not working and user's cannot get past the first page.

It looks to me like the query string is now being removed when a link in the pagination is clicked ie. ?page=2. Perhaps something changed in a WordPress update at some point that changed the behavior of query strings?

I looked into wp_removable_query_args() in functions.php which exists in the plugin like so:

function wp_removable_query_args() {
    $removable_query_args = array(
        'activate',
        'activated',
        'admin_email_remind_later',
        'approved',
        'core-major-auto-updates-saved',
        'deactivate',
        'delete_count',
        'deleted',
        'disabled',
        'doing_wp_cron',
        'enabled',
        'error',
        'hotkeys_highlight_first',
        'hotkeys_highlight_last',
        'ids',
        'locked',
        'message',
        'same',
        'saved',
        'settings-updated',
        'skipped',
        'spammed',
        'trashed',
        'unspammed',
        'untrashed',
        'update',
        'updated',
        'wp-post-new-reload',
    );

But my understanding is that this only removes the query strings listed, so page should not be removed. Any help or direction would be appreciated.

1 Answer 1

2

I don't believe this is an issue with a WP update, but rather an issue that has always been there but unnoticed:

$page = get_query_var('page');

page is a query var, yet it's being reused. As a result, when you ask for page 2, you are not asking for page 2 of the custom results, that's just a coincidence.

Instead you are asking for page 2 of the main query, the main post loop that loaded the page and template. But there is no page 2.

This regularly happens to people who don't know how to modify the main query and create replacement post loops. Their custom post loops have a page 3, but the main query does not, so page 3 gives them a 404.

Since this is a custom SQL query, the fix is easy, don't reuse reserved keywords such as page from the main query/URL for custom queries.

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.