Hi,

I'm using Drupal for a couple of month now and since I want to use it for all my further projects I'd really like to be able to write my modules using some basic MVC architecture.

So here is how I want to do it: I want to have a module called 'mvc' which will include my basic classes for Model's, Controller's and Views and I want to have a new Folder in modules called mvc with the following sub-folders:

mvc/models
mvc/controllers
mvc/views

Whenever a page is requested and no page is found I want to make drupal call a function of my mvc modules which is going to look for a controller with the name of the first argument. So for example if somebody calls www.my-site.com/projects/add and drupal doesn't have a path for that registered I want my mvc module to check if there is a file called mvc/controllers/projects.php and if yes include that file (+ models, views) and check if there is a class called mvc_projects and if yes initalize it and call a function in it passing the other arguments (here: 'add'). Then the controller will use a switch statement to figure out the kind of request and after that calling various functions on the model and finally call a function in the view class in order to display the entire thing.

So my question basically is:
- How do I tell drupal to make a function of my module the default 'page not found' callback?

For everybody interested in the mvc the module itself here is what I want to accomplish:
- The mvc module itself is a hack for Drupal to support MVC. All the stuff inside the 'mvc' folder should be as drupal independent as possible (where is the point of using mvc if you can only reuse code inside of drupal?)
- The mvc module might support some theming and database functions / classes to the 'mvc modules' but they are supposed to be very general and to easily be replaced for the purpose of other projects.
- Keep the entire thing as light weight as possible.

Alright, I hope you guys got what I think and someone knows the answer to my problem ; ).

Comments

the_undefined’s picture

So I figured out how to do the callback without hacking into drupal's code itself.

I use the hook_menu in my mvc class and when it's called it checks if the Path out of $_GET['q'] is registered. If not it add's a temporary callback to with this path to my mvc_callback function.

The way I find out if a path exists is this one:

	function drupal_path_exists($path)
	{	
		$menu = menu_get_menu();
				
		while ($path && (!array_key_exists($path, $menu['path index']) || empty($menu['items'][$menu['path index'][$path]]['callback']))) {
		$path = substr($path, 0, strrpos($path, '/'));
		}
		if (!array_key_exists($path, $menu['path index'])) {
		return false;
		}
		$mid = $menu['path index'][$path];
		
		if (empty($menu['items'][$mid]['callback'])) {
		return false;
		}
				
		return true;
	
	}

The code comes out from menu.inc and seems to work good so far.

Is anybody else interested in this idea and might want to share idea's/suggestions or offer help?

Felix

victorkane’s picture

For the sake of discussion, and in general terms, my feeling is that Drupal pretty much supports MVC right out of the box.

In any Java-based framework, such as Spring, for example, MVC is implemented by using jsp or velocity (plus css of course) as the basis for a view which is going to be constructed by the controller, which will also invoke the persistence layer (model) to obtain the data to pass over to the view.

In other words, it is the responsability of the controller to construct the model and view, and to hand it over to the view implementation (theme).

In drupal, a php block, for example, does something very similar. It is a controller, which can consult the model (database layer of Drupal) to obtain data to populate the data structures expected by the theme (view).

Of course, the php block can be abused, and used to avoid this separation, but the possiblity is there, I think; especially if the theme assumes its responsabilities. Especially if the php block generates pure html. But that is not necessarily the case.

As an example of what I mean, see this "show the last five stories" I adapted from the snippets section:

<?php
$type = 'story';
$nlimit = 5;
$result = db_query_range("SELECT n.created, n.title, n.nid, n.changed
FROM node n
WHERE n.type = '$type'
ORDER BY n.changed
DESC ", 0, $nlimit);
while ($node = db_fetch_object($result)) {
    $output[] = l($node->title, "node/".$node->nid);
}
return theme('item_list',$output);
?> 

The array $output is a data structure that knows nothing about its presentation.

http://awebfactory.com.ar

the_undefined’s picture

Hi ingles,

well of course I won't argue that Drupal does support 'mvc' to some extend. But it does a bad job making this available to the module developer and virtually no module for drupal I've seen so far is really MVC. There are HTML, Sql Queries and Request handlers all over the place.

So all I want to do is make a module that enables modules to be somehwat drupal independent and also strict MVC.

Because I hate the idea of rewriting modules I create for drupal when I want to use them in another project (that is not drupal). And since I often am in the situation where I have to extend existing websites of my clients that are done in all kinds of ways I think MVC is the way to go for not having to rewrite most of my code ...

Regarding your Code example. I'd say it's almost MVC. The problem is the l() function that is called to create the $output array. What happens if you want to display this list as Plain text sperated with "," or insert them into an Atom/RSS Feed? Than you have to rewrite code ... Instead of just creating a new 'view' and you just use your controler to pass the data from your module to it ...

WJ’s picture

Hello, the_undefined

I'm a new comer here and also interested in MVC issues too. It reads that Drupal 4.x or previous versions did not support MVC very well.

How is Drupal's recent version 5.x doing with MVC support? Do you have any comment?