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

Dynamic ControllerPublic

silence

Well-known member
#1
So here is my actionIndex:
Code:
    public function actionIndex()
    {
        $sectionId = $this->_input->filterSingle('section_id', XenForo_Input::STRING);

        if ($sectionId)
        {
            return $this->responseReroute(__CLASS__, 'section');
        }

        $this->canonicalizeRequestUrl(
            XenForo_Link::buildPublicLink('monkey')
        );

        $viewParams = array();

        return $this->responseView('monkey_ViewPublic_Index', 'monkey_index', $viewParams);
    }
However, when I do put a parameter in the URL '/monkey/test/' it tells me it cannot find that action defined.
While that normally makes sense, how would I make it redirect to actionSection if there is something there, since the way I'm doing it isn't working :(

Thanks!
 

silence

Well-known member
#3
If that isn't working, the problem probably lies within your route prefix controller.
I gotta be honest, I'm not 100% clear about the routing system in XF so I can't say I know if that's it :|
Code:
    /**
     * Match a specific route for an already matched prefix.
     *
     * @see XenForo_Route_Interface::match()
     */
    public function match($routePath, Zend_Controller_Request_Http $request, XenForo_Router $router)
    {
        $action = $router->resolveActionWithStringParam($routePath, $request, 'section_id');
        return $router->getRouteMatch('monkey_ControllerPublic_Index', $action, 'monkey');
    }

    /**
     * Method to build a link to the specified page/action with the provided
     * data and params.
     *
     * @see XenForo_Route_BuilderInterface
     */
    public function buildLink($originalPrefix, $outputPrefix, $action, $extension, $data, array &$extraParams)
    {
        if (is_array($data) && !empty($data['section_id']))
        {
            return XenForo_Link::buildBasicLinkWithStringParam($outputPrefix, $action, $extension, $data, 'section_id');
        }
    }
 

Chris D

XenForo developer
Staff member
#6
It's a XenForo... quirk. It's not a bug.

It's basically as designed.

I do this in the match() function:

PHP:
        $parts = explode('/', $routePath, 2);
        if (isset($parts[0], $parts[1]))
        {
            if ($parts[0] == 'tags')
            {
                if (utf8_substr($parts[1], -1) != '/')
                {
                    $parts[1] .= '/';
                }

                $routePath = implode('/', $parts);
            }
        }
That adds the trailing slash if it is missing.
 

silence

Well-known member
#7
It's a XenForo... quirk. It's not a bug.

It's basically as designed.

I do this in the match() function:

PHP:
        $parts = explode('/', $routePath, 2);
        if (isset($parts[0], $parts[1]))
        {
            if ($parts[0] == 'tags')
            {
                if (utf8_substr($parts[1], -1) != '/')
                {
                    $parts[1] .= '/';
                }

                $routePath = implode('/', $parts);
            }
        }
That adds the trailing slash if it is missing.
I'm confused, I don't see it in any of XF's routes nor in any addons I've come across. Also I just plopped that wonderful snippit in but I'm stilling suffering from the same issue.
 

Chris D

XenForo developer
Staff member
#8
Sorry there's a conditional in it:

PHP:
if ($parts[0] == 'tags')
You don't need that bit. Just the bit inside that statement.

There are no XF public routes which use resolveActionWithStringParam. They're all in the Admin CP. Search the XenForo/Route directory for resolveActionWithStringParam to see.

Also, typically, they are used with some sort of action e.g. /edit so the trailing slash issue isn't obvious.

You will get a route error with:

http://localhost/admin.php?bb-code-media-sites/youtube

But not with:

http://localhost/admin.php?bb-code-media-sites/youtube/
 

silence

Well-known member
#9
Sorry there's a conditional in it:

PHP:
if ($parts[0] == 'tags')
You don't need that bit. Just the bit inside that statement.

There are no XF public routes which use resolveActionWithStringParam. They're all in the Admin CP. Search the XenForo/Route directory for resolveActionWithStringParam to see.

Also, typically, they are used with some sort of action e.g. /edit so the trailing slash issue isn't obvious.

You will get a route error with:

http://localhost/admin.php?bb-code-media-sites/youtube

But not with:

http://localhost/admin.php?bb-code-media-sites/youtube/
Ah that's strange!
However, it still won't work for me :(
Code:
    public function match($routePath, Zend_Controller_Request_Http $request, XenForo_Router $router)
    {
        $parts = explode('/', $routePath, 2);

        if (isset($parts[0], $parts[1]))
        {
            if (utf8_substr($parts[1], -1) != '/')
            {
                $parts[1] .= '/';
            }

            $routePath = implode('/', $parts);
        }

        $action = $router->resolveActionWithStringParam($routePath, $request, 'section_id');
        return $router->getRouteMatch('monkey_ControllerPublic_Index', $action, 'monkey');
    }
It doesn't seem to be redirecting me at all like your bug report snippit does so I'm confused.
 

silence

Well-known member
#12

Chris D

XenForo developer
Staff member
#15
I think this will work with your original code:
PHP:
        $parts = explode('/', $routePath, 2);
        if (isset($parts[0]))
        {
            if (utf8_substr($parts[0], -1) != '/')
            {
                $parts[0] .= '/';
            }

            $routePath = implode('/', $parts);
        }
 

silence

Well-known member
#16
I think this will work with your original code:
PHP:
        $parts = explode('/', $routePath, 2);
        if (isset($parts[0]))
        {
            if (utf8_substr($parts[0], -1) != '/')
            {
                $parts[0] .= '/';
            }

            $routePath = implode('/', $parts);
        }
That completed the process!
here is the full thing working :)
Code:
    protected $_subComponents = array(
        'charlist' => array(
            'controller' => 'monkey_ControllerPublic_CharList'
        )
    );

    public function match($routePath, Zend_Controller_Request_Http $request, XenForo_Router $router)
    {
        $controller = 'monkey_ControllerPublic_Index';

        $parts = explode('/', $routePath, 2);
        if (isset($parts[0]))
        {
            if (utf8_substr($parts[0], -1) != '/')
            {
                $parts[0] .= '/';
            }

            $routePath = implode('/', $parts);
        }

        $action = $router->getSubComponentAction($this->_subComponents, $routePath, $request, $controller);

        if (!$action)
        {
            $action = $router->resolveActionWithStringParam($routePath, $request, 'section_id');
        }

        return $router->getRouteMatch($controller, $action, $parts[0], $routePath);
}