As designed Potential bug with XenForo_Router::getSubComponentAction

Chris D

XenForo developer
Staff member
Given this code example:

PHP:
<?php

class AddOn_Route_Prefix_Route implements XenForo_Route_Interface
{
    protected $_subComponents = array(
        'example' => array(
            'stringId' => 'example_string',
            'actionPrefix' => 'example',
            'controller' => 'AddOn_ControllerPublic_Example'
        )
    );

    public function match($routePath, Zend_Controller_Request_Http $request, XenForo_Router $router)
    {
        $action = $router->getSubComponentAction($this->_subComponents, $routePath, $request, $controller);

        return $router->getRouteMatch($controller, $action, 'tab_id');
    }
}

$action has different behavior depending on whether there is a trailing slash or not.

Navigating to this URL:

/index.php?route/example/hello

Resolves the action as "examplehello". Which produces:
"The controller AddOn_ControllerPublic_Example does not define an action called Examplehello."

This URL:

/index.php?route/example/hello/

Resolves the action as "example". Which is correct.

This inconsistency has the scope to potentially cause confusion if the trailing slash was accidentally omitted.

I am currently working around this in my own code, using:
PHP:
        $parts = explode('/', $routePath, 2);
        if (isset($parts[0]))
        {
            if ($parts[0] == 'example')
            {
                if (utf8_substr($parts[1], -1) != '/')
                {
                    $parts[1] .= '/';
                }

                $routePath = implode('/', $parts);
            }
        }
Which checks and rebuilds the $routePath accordingly to ensure the behavior is the same.
 
This is actually how all string-based parameters have worked since 1.0 -- you can see it with add-ons in the control panel for example. This was generally done intentionally, as otherwise it's impossible to have an action that does not take a parameter with a string param prefix.
 
Top Bottom