Search code examples
phpregexurl-rewritingpagination

How can I generate paging links from the URL when using mod_rewrite changes the URL


First of all I am in DESPERATE need of help here PLEASE I will most likely start a bounty as soon as SO lets me.

I have a pretty large site (social network) MANY PAGES, I am currently doing a complete re-write to build it better then I did 2 years ago. 1 thing I have decided to change is the URLs on my site, there were like this http://example.com/?p=page-identifier-name and sometimes http://example.com/?p=page-identifier-name&page=2&user=343433 you get the point with ultiple items in the URL, I am now switching to use mod_rewrite, I have actually done it, I have the whole site changed to using it but I have 1 huge problem,

My paging function, I LOVE it, it makes really nice paging like this prev 1 2 - 34 35 36 37 - 189 190 next or similar and work pretty well however now that I have switch to using mod-rewrite, obviously my URLs are different now which breaks my pager, I have tried a few things with no luck yet on making it work correctly again, that is why I have provied the full code to the paging below so if you care to help me you can easily drop it into a page and see how it works yourself.

The paging code currently looks for all keys and values in the URL for $_GET it then basicly itterates through all them since some pages have more then others on my site, it then re-build the proper URL with the correct page number and spits it out on the screen for my pager. So something like www.example.com/?p=mail.inbox is now www.example.com/mail/inbox, if enough items are on the page though then it will show as www.example.com/?p=mail.inbox&page=12 now www.example.com/?mail/inbox/page/12 another page might have more then just the p=page to show and page=page number some pages also have user_id's and sort by and just differetn things, now I wouldn't mind having somethings just appended to the pretty url but things like page number I would like to show how I want it to show, I have all the mod_rewrite and regex working I just need help to make my pager code generate the correct links. Since all pages are processed through the index.php file the page showing is never deeper then the root folder but the it would be nice maybe if I could trick it into thinking it is when it have a pretty url that makes it look like it is in a different folder. example.com/mail/inbox is really in the root level index and not 2 folders deep, tried using something like

$selfurl = $_SERVER["REQUEST_URI"].'/page/'. $pagenumber;

If I was on this page www.example.com/mail/inbox then this would make a paging link look like this www.example.com/mail/inbox/page/12 however if I were to click that link, then the new paging links would look like this www.example.com/mail/inbox/page/12/page/34 so obviously that is not the solution, I am really stuck here and if I can not find a solution then I will have to quit using regex and have some really crappy paging, I would really appreciate anyone who can try to help me, I don't see a soltion but surely there has to be one.

<?PHP

class Paging
{

    /*////////////////////////////////////////////////////////////////////////
    * Paging Function
    * //paging(10000, 50, 4); //number of results / items per page / number of page links in center
    * // paging(10000, 50); //or
    */ ///////////////////////////////////////////////////////////////////////
    public static function show_paging($total_results, $items_per_page, $adjacents = 3)
    {
        //$total_results = $reccnt;
        //$items_per_page = $pagesize;
        // adjacements will determinine how many paging links are in the middle of the outer paging

        if ($total_results > $items_per_page) {
            // build our link URLs
            $url_string = "?";
            foreach ($_GET as $k => $v) {
                if ($k != "page") { // <-- the key you don't want, ie "page"
                    if ($url_string != "?") {
                        $url_string .= "&"; // Prepend ampersands nicely
                    }
                    $url_string .= $k . "=" . $v;
                }
            }
            $selfurl = $url_string . '&page=';
            $page = $_GET['page'];
            if ($page) {
                $start = ($page - 1) * $items_per_page;
            }
            else {
                $start = 0;
            }
            if ($page == 0) {
                $page = 1; //if no page var is given, default to 1.
            }
            $prev = $page - 1; //previous page is page - 1
            $next = $page + 1; //next page is page + 1
            $lastpage = ceil($total_results / $items_per_page); //lastpage is = total_results/ items per page, rounded up.
            $lpm1 = $lastpage - 1; //last page minus 1
            /*
            * Now we apply our rules and draw the pagination object. 
            * We're actually saving the code to a variable in case we want to draw it more than once.
            */
            $pagination = "";
            if ($lastpage > 1) {
                $pagination .= '<div class="pagingspace"><div class="pager">';
                //previous button
                if ($page > 1) {
                    $pagination .= '<a href="' . $selfurl . $prev .
                        '" title="go to previous page"><span class="page-numbers prev">prev</span></a>';
                }
                //pages
                if ($lastpage < 7 + ($adjacents * 2)) { //not enough pages to bother breaking it up{
                    for ($counter = 1; $counter <= $lastpage; $counter++) {
                        if ($counter == $page) {
                            $pagination .= '<span class="page-numbers current">' . $counter . '</span>';
                        }
                        else {
                            $pagination .= '<a href="' . $selfurl . $counter . '" title="go to page ' . $counter .
                                '"><span class="page-numbers">' . $counter . '</span></a>';
                        }
                    }
                }
                else {
                    if ($lastpage > 5 + ($adjacents * 2)) { //enough pages to hide some{
                        //close to beginning; only hide later pages
                        if ($page < 1 + ($adjacents * 2)) {
                            for ($counter = 1; $counter < 4 + ($adjacents * 2); $counter++) {
                                if ($counter == $page) {
                                    $pagination .= '<span class="page-numbers current">' . $counter . '</span>';
                                }
                                else {
                                    $pagination .= '<a href="' . $selfurl . $counter . '" title="go to page ' . $counter .
                                        '"><span class="page-numbers">' . $counter . '</span></a>';
                                }
                            }
                            $pagination .= '<span class="page-numbers dots">&hellip;</span>';
                            $pagination .= '<a href="' . $selfurl . $lpm1 . '" title="go to page ' . $lpm1 .
                                '"><span class="page-numbers">' . $lpm1 . '</span></a>';
                            $pagination .= '<a href="' . $selfurl . $lastpage . '" title="go to page ' . $lastpage .
                                '"><span class="page-numbers">' . $lastpage . '</span></a>';
                            //in middle; hide some front and some back
                        }
                        else {
                            if ($lastpage - ($adjacents * 2) > $page && $page > ($adjacents * 2)) {
                                $pagination .= '<a href="' . $selfurl .
                                    '1" title="go to page 1"><span class="page-numbers">1</span></a>';
                                $pagination .= '<a href="' . $selfurl .
                                    '2" title="go to page 2"><span class="page-numbers">2</span></a>';
                                $pagination .= '<span class="page-numbers dots">&hellip;</span>';
                                for ($counter = $page - $adjacents; $counter <= $page + $adjacents; $counter++) {
                                    if ($counter == $page) {
                                        $pagination .= '<span class="page-numbers current">' . $counter . '</span>';
                                    }
                                    else {
                                        $pagination .= '<a href="' . $selfurl . $counter . '" title="go to page ' . $counter .
                                            '"><span class="page-numbers">' . $counter . '</span></a>';
                                    }
                                }
                                $pagination .= '<span class="page-numbers dots">&hellip;</span>';
                                $pagination .= '<a href="' . $selfurl . $lpm1 . '" title="go to page ' . $lpm1 .
                                    '"><span class="page-numbers">' . $lpm1 . '</span></a>';
                                $pagination .= '<a href="' . $selfurl . $lastpage . '" title="go to page ' . $lastpage .
                                    '"><span class="page-numbers">' . $lastpage . '</span></a>';
                                //close to end; only hide early pages
                            }
                            else {
                                $pagination .= '<a href="' . $selfurl .
                                    '1" title="go to page 1"><span class="page-numbers">1</span></a>';
                                $pagination .= '<a href="' . $selfurl .
                                    '2" title="go to page 2"><span class="page-numbers">2</span></a>';
                                $pagination .= '<span class="page-numbers dots">&hellip;</span>';
                                for ($counter = $lastpage - (2 + ($adjacents * 2)); $counter <= $lastpage; $counter++) {
                                    if ($counter == $page) {
                                        $pagination .= '<span class="page-numbers current">' . $counter . '</span>';
                                    }
                                    else {
                                        $pagination .= '<a href="' . $selfurl . $counter . '" title="go to page ' . $counter .
                                            '"><span class="page-numbers">' . $counter . '</span></a>';
                                    }
                                }
                            }
                        }
                    }
                }
                //next button
                if ($page < $counter - 1) {
                    $pagination .= '<a href="' . $selfurl . $next .
                        '" title="go to next page"><span class="page-numbers prev">next</span></a>';
                }
                else {
                    $pagination .= '<span class="page-numbers prev">next</span>';
                    $pagination .= '</div></div>';
                }
            }
            echo '<table width="100%"  border="0" cellspacing="0" cellpadding="5" class="paginator">';
            echo '<tr><td align="center" height="20" class="black11bold">';
            echo $pagination;
            echo '</td></tr></table>';
        }
    }

    // converts page number to a start position number for MySQL query
    public static function page2db($page, $items_per_page)
    {
        if ($page) {
            $start = ($page - 1) * $items_per_page;
        }
        else {
            $start = 0;
        }
        return $start;
    }

}

?>

To use

<?PHP
//to use the paging functions i do something like this
$pagesize = 10;
$start = Paging::page2db($_GET['page'], $pagesize); //page number and items perpage

//the show the pager links
Paging::show_paging($total_count, $pagesize, 4);

?>

UPDATE

I need to figure out a way to get the value from URLs like this and only have the part minus the domain name, so http://example.com/mail/inbox would only return /mail/inbox this should work on and number of directories and should not return valus like ?var1=something that are on it, so it should only return the folders that are added onto a domain the catch is these folders are not real folders, they are created with mod_rewrite in the URL

http://example.com/mail/inbox
http://example.com/forums/category
http://example.com/users/online
http://example.com/users/online/friends

I am trying to fix a PHP paging code that is messed up now that I use mod-rewrite, the links it prints to the screen are incorrect because it rebuilds the URL based on the $_GET values, this doesnt work anymore as the names in the URLs do not match the $_GET values

SO if a URL is http://example.com/users/online or http://example.com/users/online/page/22 then I need to rebuld it into a variabe as http://example.com**/users/online/ then my paging code can add on it's page part if needed to.


Solution

  • It seems the best method that I have found is to pass into the paging function, the URL of the page I am on using

    $pagingurl = 'http://localhost/mail/inbox/';
    Paging::show_paging($total_count, 3, $pagingurl, 4);
    

    This seesm liek the best solution for allowing me to use my mod-rewrite URLs