Search code examples
phpmodulehmvcfuelphp

Can't get unroutable HMVC request to work in FuelPHP


In the documentation of FuelPHP, it has the following sample:

// or fetch the output of a module
$widget = Request::forge('mymodule/mycontroller/mymethod/parms', false)->execute();
echo $widget;

This works when the function I am calling has the action_ prefix, but when I remove the prefix (since I don't want it to be called by the browser) it doesn't work anymore even if I set the 2nd parameter to false.

Here is an example:


WORKS

In one controller I call:

$widget = Request::forge('mymodule/mycontroller/mymethod')->execute();
echo $widget;

In mycontroller:

public function action_mymethod()
{
    echo 'works';
}

FAILS with 404

In one controller I call:

$widget = Request::forge('mymodule/mycontroller/mymethod', false)->execute();
echo $widget;

In mycontroller:

public function mymethod()
{
    echo 'works';
}

Solution

  • You can not remove the action prefix.

    You don't understand how HMVC in FuelPHP works. From the controllers point of view, a request is a request, no matter where it comes from. Any action can be called either from the URL (the main request) or through secondary requests (HMVC).

    The second parameter of the Request::forge() method just controls the routing. If true (the default), the request is send through the routing engine, so routes will apply when mapping the request URI to a controller/method. If false, the routing engine is bypassed, and a direct mapping is made to the controller/method.

    You will need this if your routing table contains a catch-all at the end to avoid routing to internal controllers. This is the preferred way of shielding controllers from being called through a main request.

    If you have controllers with both public and internal methods, using the route option can become complex as you need to exclude some URI's from the catch_all.

    In that case you can check the request type in the controller action using:

    \Request::is_hmvc()
    

    This will return false if your action is called by the main request (i.e. via the browser URL) or true if it was an HMVC call. You can redirect elsewhere, or throw a HttpNotFoundException if you want your 404 to be shown.