0

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';
}
zgosalvez
  • 384
  • 1
  • 5
  • 22

1 Answers1

6

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.

WanWizard
  • 2,574
  • 15
  • 13
  • Oh, okey. I got confused since [Base Controller](http://docs.fuelphp.com/general/controllers/base.html) says, "Methods that can be requested through the URL are prefixed with 'action_'." So I assumed I can just remove the prefix so that it isn't accessible by the browser but can still be requested internally (i.e. HMVC). By the way, I think you meant `\Request::is_hmvc()` will return true if HMVC, otherwise Browser URL? – zgosalvez Apr 01 '12 at 02:13
  • By the way, found out that calling `Request::forge('mymodule/mycontroller/mymethod/parms')->execute();` will also return 404 if **mycontroller** extends **Controller_Template** and not **Controller**. – zgosalvez Apr 04 '12 at 07:20
  • I see no reason why. Could it be that 'mymodule/mycontroller/mymethod/parms' is not routable? That would indeed throw a 404. If so, use FALSE as third parameter to forge() to bypass the routing engine. – WanWizard Apr 06 '12 at 20:31
  • I get a 404 without the false (found out it wasn't routable). But I get a 'The connection was reset' by the browser with the false on. I think Controller_Template shouldn't be extended by widgets since I believe the template loops within itself through the module. What do you think? – zgosalvez Apr 06 '12 at 23:57
  • I can't look into your code to see what you have done but if your HMVC controller extends the same base controller as your primary one, and uses the same template, then clearly you have a major design flaw in your application. – WanWizard May 07 '12 at 10:55