1. This site uses cookies. By continuing to use this site, you are agreeing to our use of cookies. Learn More.

Question about handling URL parameters

Discussion in 'XenForo Development Discussions' started by corbitWire1, Oct 29, 2011.

  1. corbitWire1

    corbitWire1 Member

    My adventure into the beautiful system of xenForo continues:

    I've overriden XenForo_Route_Prefix_Threads and XenForo_ControllerPublic_Thread. Actually I am trying to modify the behavior of XenForo_ControllerPublic_Thread and I need to support one additional URL parameter named 'apage'. That's why I've overriden XenForo_Route_Prefix_Threads.

    My class (which overrides XenForo_Route_Prefix_Threads) contains the following code:

    PHP:
    public function match($routePathZend_Controller_Request_Http $requestXenForo_Router $router)
    {
    $action $router->resolveActionWithIntegerParam($routePath$request'thread_id');
    $action $router->resolveActionAsPageNumber($action$request);

    // Handle article pages
    if (preg_match('#^apage-(\d+)$#i'$action$match))
    {
    $action '';
    $request->setParam('apage'$match[1]);
    //die ($request->getParam('apage'));
    }

    //$request->setParam('apage', 1);
    return $router->getRouteMatch('XenForo_ControllerPublic_Thread'$action'forums');
    }
    It should work on a URL like index.php?threads/this-is-a-test.5/apage-2. The regex code works correctly as it is almost the same code xenForo uses to handle /page-id URL patterns. If I uncomment the 'die' line, the requested apage value get's displayed. That means that the regex works and the apage param get's set correctly. The problem is that the value of apage isn't available to my controller (my controller reports a value of 0 all the time). If I set the apage parameter to a hardcoded value as I've done in the commented line, everything works like a charm. My controller fetches the apage value by using

    PHP:
    $apage max(0$this->_input->filterSingle('apage'XenForo_Input::UINT));
    Why my hardcoded apage value works while the URL's one doesn't?
     
  2. Fuhrmann

    Fuhrmann Well-Known Member

    I have tested in here and dont know why too.

    This is strange, because after using the method setParam with the value of $match[1], then calling getParams method return me this:

    array(3) { ["_origRoutePath"]=> string(29) "threads/sdfsdfdsfs.77/apage-2" ["thread_id"]=> int(77) ["apage"]=> string(1) "2" }

    But then in the Controller, i receive this 0 value too.
     
  3. Fuhrmann

    Fuhrmann Well-Known Member

    Maybe you have to use in your extended controller
    Code:
     canonicalizePageNumber($page, $postsPerPage, $thread['reply_count'] + 1, 'threads', $thread)
    AND

    Code:
    canonicalizeRequestUrl(XenForo_Link::buildPublicLink('threads', $thread, array('page' => $page)))
    both functions are used by the actionIndex in the ControllerPublicThread.

    I have commented this lines, and now i get the value from "apage".
     
  4. corbitWire1

    corbitWire1 Member

    Thanks for your help :) I noticed these functions but I didn't touched them because I can't understand why setting a hardcoded value works, while the value found in the url doesn't work. Both use $request->setParam. I'll do some experiments with these functions and reply with the results.
     
  5. corbitWire1

    corbitWire1 Member

    No luck so far...

    I'am digging in canonicalizeRequestUrl and XenForo_Link::buildPublicLink in order to understand the way they work. If you have any suggestion please let me know!
     
  6. corbitWire1

    corbitWire1 Member

    To Kier/Mike (or any other developer who knows the answer :p)

    I haven't solved the problem yet. I noticed that buildLink method XenForo_Route_Prefix_Threads get's called in the process of handing the url and it's parameters. I've kept match function as shown above and I've overriden buildLink as follows:

    PHP:
    public function buildLink($originalPrefix$outputPrefix$action$extension$data, array &$extraParams)
        {
            if (
    $action == 'article-page' && !empty($extraParams['articlePage']))
            {
                
    $articlePage $extraParams['articlePage'];
                unset(
    $extraParams['articlePage']);
                
    $extraParams['apage'] = $articlePage['pageId'];
                
    $action '';
                
    $action $this->getAPageNumberAsAction($action$extraParams);
     
                return 
    XenForo_Link::buildBasicLinkWithIntegerParam($outputPrefix$action$extension$data'thread_id''title');
            }
            else
            {
                return 
    parent::buildLink($originalPrefix$outputPrefix$action$extension$data$extraParams);
            }
        }
    Also I tried the following...

    PHP:
    public function buildLink($originalPrefix$outputPrefix$action$extension$data, array &$extraParams)
        {
            if (
    $action == 'article-page' && !empty($extraParams['articlePage']))
            {
                
    $articlePage $extraParams['articlePage'];
                unset(
    $extraParams['articlePage']);
                
    $extraParams['apage'] = $articlePage['pageId'];
                
    $action '';
                
    $action $this->getAPageNumberAsAction($action$extraParams);
     
                return 
    XenForo_Link::buildBasicLinkWithIntegerParam($outputPrefix$action$extension$data'thread_id''title');
            }
            else if (isset(
    $extraParams['apage']))
            {
     
                
    $action '';
                
    $action $this->getAPageNumberAsAction($action$extraParams);
             
                return 
    XenForo_Link::buildBasicLinkWithIntegerParam($outputPrefix$action$extension$data'thread_id''title');
            }
            else
            {
                return 
    parent::buildLink($originalPrefix$outputPrefix$action$extension$data$extraParams);
            }
        }
     
        private function 
    getAPageNumberAsAction($action, array &$params)
        {
            if (isset(
    $params['apage']))
            {
                if (
    strval($params['apage']) !== XenForo_Application::$integerSentinel && $params['apage'] < 0)
                {
                    unset(
    $params['apage']);
                }
                else if (!
    $action)
                {
                    if (
    $params['apage'] != XenForo_Application::$integerSentinel)
                    {
                        
    $params['apage'] = intval($params['apage']);
                    }
     
                    
    $action "apage-$params[apage]";
     
                    unset(
    $params['apage']);
                }
            }
     
            return 
    $action;
        }
    with no luck as you already know! apage is always 0. But if I set apage to a hardcoded value as I've shown above, everything works normally without adding this extra code in buildLink. The only way for my controller to read a non-zero value is to set it hardcoded in match function. Why is this happening? What is the proper way to handle the apage parameter?
     

Share This Page