Daniel has posted 1 posts at DZone. View Full User Profile

Another MVC approach

08.04.2008
| 17974 views |
  • submit to reddit

Back to the Controller_Employee::execute(). Two things happen inside of $result = $action->execute().

  1. The Action's auth() method is called, which would check stuff like: if the current user is not the employee's boss, the user can't change the employee record. In this example, I won't check for anything, so I can just use the generic Action_Detail object (it's auth() method always returns true). Otherwise you would create an object Action_Detail_Employee_Update extends Action_Detail and override the auth() method.
  2. If the Action::auth() returns true, we can go on executing the action.

Now that we're authorized to update this employee, we want to get to the part where we create a form. For this I use a proprietary form library that compares to PEAR's HTML_QuickForm (but is actually better :) ). So just for argument's sake, don't bother with trying to understand the $form object. The code for actually performing the action looks something like this:
In Action_Detail::execute()

$form = HTML_Form::createFromData('form', $this->record); 

# if the form is submitted and validated, redirect to overview
if ($form->isSubmitted() && $form->validate()) {
$this->record->save(); // record updaten
return new ActionResult_Redirect('/'.FrontOffice::currentController().'/list');
}

# create form
if ($this->data->mode === 'show')
return new ActionResult_View('View/Show.php', $this->record);
else
return new ActionResult_View('View/Update.php', $this->record);

The ActionResult is returned to the Controller, where we saw the return $result->execute(); code. In this case, we get the ActionResult_View object returned to us, with a view and some data to present in the view.

Almost there, just the ActionResult_View::execute() to wrap it up.

function execute()  
{
# Make $data available as a global in the View
$data = $this->data;

# determine output format (HTML/XML etc)
$type = ucfirst(strtolower(FrontOffice::i()->output));

# locate View file
$view = preg_replace('/View/', 'View/'.$type, $this->view);

try {
$success = @include($view);
if (!$success) throw new View_Exception("View does not exist");
} catch (View_Exception $e) {
print $e->getMessage();
}
}

The View file that's included here could look something like this:

# initialize stuff like menu/layout etc 
initLayout();

if ($data && $data instanceof QDB_Record)
{
$form = HTML_Form::createFromData('form', $data);
$form->validate();

$form->display();
}

And that's it. We include the PHP file and it outputs some HTML to the client.

To close, here's the directory structure I use:

Action
  \Delete.php
  \Detail.php
  \Overview.php
  \Static.php
ActionResult
  \Download.php
  \NotAllowed.php
  \Redirect.php
  \View.php
MyApplication
  \Action
  \Employee
     \Update.php
  \Controller
     \Employee.php
     \...
  \View
     \...

View
  \Html
     \Overview.php
     \Start.php
     \...
   \Xml
     \Overview.php
     \Start.php
     \...

Action.php
ActionResult.php
Controller.php
Data.php
FrontOffice.php

That's it. We're currently using this architecture in a big application and it's proving to be very flexible and easy to use. It may take a little time to get used to the structure, but the high reusability and small pieces of code really pay off in the long run.

Note that I've simplified some stuff, and I haven't gone into detail about some of the interfaces/abstract classes I use. I intended to get my idea across, and look forward to any questions/suggestions and comments.

 

Published at DZone with permission of its author, Daniel Oosterhuis.

(Note: Opinions expressed in this article and its replies are the opinions of their respective authors and not those of DZone, Inc.)

Comments

Daniel Oosterhuis replied on Mon, 2008/08/04 - 8:25am

Just a slight correction. The QDB package is available at http://blog.adaniels.nl/downloads/qdb.zip.

Mc Esher replied on Tue, 2008/08/05 - 7:37am

Nice article! I like the simplicity of your implementation and indeed, as mentioned it looks like it's all reusable. I saw some other implementations of the MVC approach (eg. CodeIgniter) that turned into frameworks (or they were meant to be so to begin with). With this level of reusability you might see your implementation turn into another framework before long. The QDB package also seems very interesting. I hope to see more of your publications!

Comment viewing options

Select your preferred way to display the comments and click "Save settings" to activate your changes.