I'm not completely familiar with HMVC, but I think HMVC can be compared to AJAX on the server side; where your controllers can send requests to other parts of your application without requiring additional requests or redirecting the user to a new page.
MVC only has 1 controller per request, HMVC can have many.
MVC request processing:
HMVC request:
Basically, at any point within an HMVC framework, you can do something like this:
<?php echo Request::factory('users/login') ?>
<?php echo Request::factory('search') ?>
Each request is entirely self-contained, as if someone went to (for users/login) http://example.com/users/login. It's very similar to AJAX, except that all of the requests happen within the main request.
Check out dlib's Dispatch library for a potential solution. As of right now, neither trunk or pre_3.0 support HMVC.
$address_book_model = new AddressBook;
$contacts = $address_book_model->get_contacts();
//pass these contacts to the template view to display
$contacts= Request::factory('addressbook/contacts')->execute();
//from here pass the contacts to the messaging template view to display the contacts on render
public function contacts(){
$address_book_model = new Models_AddressBook;
return $address_book_model->get_contacts();//would get all contacts for the particular user
}
Not exactly, since the return value of controllers is meaningless.
Here is a nice simple way to thinking about it. Say you have a login box on every single page. Rather than having to build login functionality into every controller, you could simply do this in your template:
<?php echo Request::factory('user/login')->execute() ?>
And the controller that responses to that request would do nothing except display a login form. All the POST data would already be part of the application, so errors and such would automatically be rendered.
Hope that makes sense.
Posted By: ShadowhandNot exactly, since the return value of controllers is meaningless.
Here is a nice simple way to thinking about it. Say you have a login box on every single page. Rather than having to build login functionality into every controller, you could simply do this in your template:
<?php echo Request::factory('user/login')->execute() ?>And the controller that responses to that request would do nothing except display a login form. All the POST data would already be part of the application, so errors and such would automatically be rendered.
Hope that makes sense.
Well the most obvious answer is that all requests happen through the same place, so the logic will be exactly the same. In terms of overhead, there really isn't that much. The "heavy lifting" is really all in Request::instance() which is only executed for the very first request.
You can still include views directly by using include Kohana::find_file('views', $path), but that does not give you all of the controller logic that goes with a particular view... and you certainly should not be putting validation logic in your views!
$this->request->response = json_encode(Request::factory('report_controller/controller_action')->execute()));
@dcunited08: That is exactly what the HMVC support in Kohana v3.x provides.
@jshaw: I think you could drop the json_encode call, as that would be handled in the controller itself. But that is basically spot on.
Lamonte you could use HMVC for a login box but it should only take care of the login box views because the login box request is going to be executed after the action request gets executed, which makes you spill memory and bandwidth.
In your case it's better to extend the (template) controller and add the login check to the before function and make all the controllers that have actions that need authorisation children of that extended controller. If it needs to be displayed on all pages then you have to make all your other controller children of that extended controller.
I think HMVC in Kohana is good for page pieces that have no connection with the content but aren't static (last comments, most read) or pieces that only need data set in parent controller (user chat, read by friends) and are displayed on more than one page.
Posted By: oceatoonbut I'm wondering can't all these modular elements be called individually using Ajax just like mashups would do ? (which would be an normal MVC)
So, now I'm wondering, could I take advantage of HMVC to sort of wrap all that functionality into a Kohana request using the request::factory method or am I misunderstanding what this HMVC stuff is good for?
Kohana HMVC is very powerful as you rightly point out but it is limited to calling Kohana requests as sub requests. That means a sub request must be a Kohana controller and action. Also note that $_GET and $_POST are NOT set differently in the subrequest - there was a huge discussion about this a while ago on the forums and it is a good idea not to try and emulate /mess with the globals inside subrequests.
You said "([Minify] has its own MVC thing going on)". It wouldn't directly be possible for Kohana to issue a sub-request to a different MVC framework. You would need to still have a kohana controller and action that wrapped up the Minify library functionality to be able to access it with a sub-request.
$validParams_serialized = urlencode(serialize($this->validParams));
$list = Request::factory('list/' . $validParams_serialized )->execute()->response;
Session::set('validParams', $this->validParams);
$this->validParams = Session::get('validParams', NULL);
Of course, if you really don't see the point of HMVC then don't use it, KO3 doesn't force its use. Far from it.
@felixhcat : if you want to pass a custom data to a request you could do it in a simple manner
$request = Request::factory('your/uri');
$request->my_data = $my_data;
$request->execute()->response;
access your custom data as $this->request->my_data
access your custom data as $this->request->my_data
though that wouldn't be true HMVC as it doesn't work for external requests, which is actually a good benefit of HMVC to scale "vertically".
Please tell me if that is wrong.
@zsoerenm correct - in theory there should be no interaction between requests other than what could be done with a true http request. So you should pass data in GET, POST or session in the usual way.
I'd also always be wary about setting a run-time property on a core class pike Request like that - can lead to very hard to debug issues.
It is worth noting that v3.1 has support for external requests and responses.
@zsoerenm yes it works only for internal requests.
@andrewc It may be ok to have interaction between internal requests and don't mimic in all aspects a true http request. And yes we should pass data in GET, POST but those GET, POST should be isolated per each internal request.
Perhaps a code like this
// save original
$original_POST = $_POST;
$original_method = Request::$method;
// overload $_POST
$_POST = $new_post_array;
$request = Request::factory('your/uri');
Request::$method = 'POST';
$request->execute()->response;
// restore original
$_POST =$original_POST;
Request::$method = $original_method;
FWIW I'm experimenting with
$request->transfer['somecontext'] = $somecontext;
before calling, and
$someconfigurationdata = $request->transfer['someconfigurationdata'];
on return.
I know this is somewhat contrary to the spirit of HMVC, and excludes external calls (though I presume with some work some kind of proxy system could be devised) but
there are advantages to HMVC for modularity of page construction for which I don't see a ready alternative, while at the same time
most widgets on my pages are coordinated in some way, and require sharing of internal configuration data which is somewhat peripheral to the main data
At least $request->transfer is somewhat standardized.
I'm wide open to ideas here though.
A specific situation is co-ordination of main page contents with sidebar data operation controls (such as Allow, Deny, Hide, Show, Add, etc.) Another one is vertical partitioning based on the user route into a dataset, such as listing all articles in a table, vs just opinion articles or blogs.
It looks like you're new here. If you want to get involved, click one of these buttons!