Another MVC approach
Back to the Controller_Employee::execute(). Two things happen inside of $result = $action->execute().
- 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.
- 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.
- « first
- ‹ previous
- 1
- 2
- 3
- 4
(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
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!