HMVC in Kohana

After a question yesterday in the forums I wrote a simple yet useful library to call other controllers and controller methods from within a controller in Kohana. It’s stored in the Dispatch library

Here’s the example from yesterday:
Example:

 
$article_list=Dispatch::controller('article')->method('list',5);
 
$article_list=Dispatch::controller('article')->method('list',array(5,'last');
//or with magic methods
$article_list=Dispatch::controller('article')->list(5);

Will load Article_Controller and execute method list() and return the output of the method. The 5 is passed as first argument or in the second 5 is passed as first, ‘last’ as second argument.

The controller() method returns a Dispatch object.

It’s called HMVC and over at CodeIgniter they use it as well: here or here
More information can be found here: hmvc

Xobb pointed out at the forums that this is not strictly HMVC, he’s right. I called it that since I didn’t know any better way of calling it. Xobb named id pull-mvc which is perhaps more appropriate. Nevertheless, I’ve got to read up on mvc terminology.


16 Responses to “HMVC in Kohana”

  1. vlads Says:

    Hi!
    Im using Dispatcher for unit-testing.

    when i call
    Dispatch::controller(’todo’)->method(’index’);

    and then

    Dispatch::controller(’todo’)->method(’index’);

    it causes fatal error “Fatal error: Cannot redeclare class Todo_Controller”

    i propose to use require_once instead of require, or

    // Set controller class name
    $controller = ucfirst($controller).’_Controller’;

    // Include the Controller file
    // prevent loading more than once
    if (!class_exists($controller)) require $filepath;

  2. dlib Says:

    You’re right, in fact I changed this already in my local version but the one in svn is not updated to reflect this. I planned to do another update before the next commit. I’ll try to update it asap.

  3. Zeelot Says:

    was just wondering if you could implement this:

    $foo = Dispatch::controller(’dir/bar’);

    Dispatch thinks the controller name is Dir/bar

    I organize my entire kohana controllers like this and kohana does it for me so I think Dispatch should work similarly to Kohana when loading a controller.

  4. dlib Says:

    I will look into this, I expect to need this functionality myself pretty soon.

  5. Zeelot Says:

    I’ve implemented it by extending the library and using the same code found in Router.php around line 85(stripped down)… I believe that is where Kohana does it (this was the first time I dug into the Kohana core files)

  6. Zeelot Says:

    here it is (just got it working)
    I know it’s ugly but I needed something quick and dirty

    http://pastebin.ca/1030113

  7. dlib Says:

    I’ve included your code into the svn version. It’s still hackish but it should work (not tested), when I have more time I’ll work out something cleaner.

    Thanks though, great addition to the library.

  8. Zeelot Says:

    public static function controller($controller)
    {
    public static function controller($rsegments)
    {

    typo? you forgot to delete the top controller function

  9. Edemilson Lima Says:

    Could this work with directory support?

    public static function controller($controller) {
    $controller_file = strtolower($controller);

    if(strstr($controller, ‘/’)) {
    $segments = explode(’/', $controller);
    controller = $segments[count($segments) - 1];
    }

    // Set controller class name
    $controller = ucfirst($controller).’_Controller’;

  10. Edemilson Lima Says:

    I missed a “$” at the sixth line…

  11. Zeelot Says:

    latest SVN seems broken?
    the echoed content is not returned anymore. it’s just echoed…seems fine in older version or is it just me?

  12. kRON Says:

    Anyone know, by chance, why I can’t seem to load a controller from a view file, but can from within a controller?

  13. boonker Says:

    …maybe worth a try…

    i want to use this dispatcher for calling modules/controller from other controller/templates in the future (like slotting in agavi).

    Dispatch::module(’MyModule’)->controller(’MyController’)

    what you think?

  14. boonker Says:

    …and i forgott…

    Dispatch::module(’MyModule’)->controller(’MyController’)->method(’myMethod’)->params(array(’foo’=>’bar’))

  15. Zaak Says:

    Hello. Where i can get actual Dispatch source code?

  16. Lou K Says:

    Just wondering — any reason why method() doesn’t just use func_get_args? I.E.

    $args = func_get_args();
    array_shift($args); $result=call_user_func_array(array($this->controller, $method), $args);

    That way it doesn’t need to be called with an array.