And I'm able to confirm that the module was loaded using:
$loaded = \Module::loaded('mymodule');
var_dump($loaded); // returns bool true
However, if I try to access a controller in my module, I get this error:
ErrorException [ Error ]: Class 'Mymodule\Controller\Test' not found
If I run a:
var_dump(get_declared_classes());
I get a big list of loaded classes, including a bunch of Fuel\Core\ classes, as well as a couple of my own controller classes, but there are no classes that match "mymodule" at all.
my module classes should reside in the \Mymodule\Controller namespace. However, I can't find that namespace even after \Module::load('mymodule'); succeeds.
What do I need to do to be able to access my module?
FuelPHP is designed on the JIT principle, which means it doesn't do anything that isn't absolutely needed, until it's needed.
In this case, loading a module just means the autoloader is informed that the module exists, and introduces the namespace of the module to the autoloader. It doesn't load any code, why should it, it doesn't know what you want to do with the module.
Perhaps you should first explain what you are trying to achieve, since you tell use you have an error, but you don't say what you did to create that error, and why you did that (i.e. what functionality did you expect)?
Well, technically you can, but since it's not an HMVC call (you'll need to forge a request for that), the context is still set to 'app', so your view will not be found.
What goes wrong here is that "\Myodule\Controller\Test::run();" requires the class "Test" to be in the "Mymodule\Controller" namespace, which is isn't. And it's not a controller (otherwise it would have been called "Controller_Test"), it's a standard class, which should therefore not be in the classes/controller folder.
I suggest you check the docs pages on Controllers, Modules and HMVC again to understand how to create and use them.
Controllers are meant to be called by a request, either via the browser, or via HMVC. And not directly as a standard PHP class. If you want that, create a standard PHP class (in the classes folder).
Am I misunderstanding this? I was under the impression that modules are MVC applications that are setup analogous to the main FuelPHP application. The documentation at http://fuelphp.com/docs/general/modules.html#/folder_structure seems to suggest that you can setup modules as MVC applications, and that's what I'd like to do.
Yes. Have you moved your controllers into a namespace? From the looks of it, not.
That page described that by default, controllers and models live in the same namespace, and are prefixed with their function. So a class containing a controller called Test is called "Controller_Test".
There is an option to change that, and move your controllers into a namespace. You have done that for your app controller "Testmodules", but not for your module controller, which should be:
namespace Mymodule\Controller; class Test extends \Controller {}
For this reason the class is not found, because you call it correctly (\Mymodule\Controller\Test), but that is not how it is defined.
And did you change the config file to tell Fuel you have namespaced your controllers?
As to the second point: no, you have not misunderstood that. Modules are completely identical to the setup of app itself, but have a "root" namespace identical to the module name.
What you have misunderstood is what HMVC is, and how it's implemented. It is important that you understand "Request context", because everything revolves around that.
When you enter a URL in the browser, a Request object is forged containing the request context, which is linked to the controller the request is routed too. This for example has an impact on how view, config and lang files are loaded. If the URL is routed to a module, that module is set as the context, which means when you load something, first the module is searched, and if not found, app and any loaded packages are searched.
If the Request context is "app" itself, and you simply use a PHP static call to a module class, the context doesn't change. There is no way PHP or Fuel would know that you want to switch contexts. As a result, when you try to load a view from that module controller, the module views folder will not be searched and the view will not be found.
The correct way of making an HMVC call is documented as well (http://docs.fuelphp.com/general/hmvc.html). You create a second Request for your module controller. This will set the correct context.
You also have to be aware that Modules are designed to make the app modular, and not specifically for HMVC purposes. This means that all modules are routable, and every controller in a module can be requested from the URL. If you have module controllers you only want to use internally in your application, you have to make sure they can't be called from the URL. You do that either through a route (that would route the module to a 404 page for example), or in the controllers before() method, by checking if it's an HMVC request (and redirect to a 404 page if not).
Thanks again for all your help Herro. I corrected the namespace in the mymodule test controller from:
namespace Mymodule;
to:
namespace Mymodule\Controller;
And I was able to successfully call mymodule logic from my Testmodules controller using:
echo \Mymodule\Controller\Test::action_run();
However, as you mentioned, this is not my intended functionality, as the module controller is running from the main application scope, and is attempting to load views from the main application instead of the module. However, when I try to use an HMVC request, such as:
It took some debugging, but I think I found the issue.
You ran into a an error in the documentation. When trying to find the module controller it will create the class name from the segments found, adding a backslash between namespace and classname.
Which means that if you define
'controller_prefix' => '\\Controller\\',
you'll end up with 3 backslashes, and a "class not found".
I've fixed the code for 1.5/develop, you can try if