I choose not to go down the action chain to the render. The reason I did this is because I have a project on the go and needed a quick solution.
Code: Select all
Default Page:
<?php
class ActionDefault extends Action {
var $id = 'content';
var $parent = 'layout/layout';
function execute() {
$this->document->setTitle('Default Controller');
$this->data['links'] = array();
$this->data['links'][] = array(
'text' => 'Google',
'href' => 'http://google.co.uk'
);
$this->render('common/default.tpl');
}
}
?>
Layout Page:
<?php
class ActionLayout extends Action {
var $id = 'layout';
var $children = array(
'module/header',
'module/column',
'module/footer'
);
function execute() {
$this->data['title'] = $this->document->getTitle();
$this->data['description'] = $this->document->getDescription();
$this->data['base'] = $this->document->getBase();
$this->data['charset'] = $this->document->getCharset();
$this->data['direction'] = $this->document->getDirection();
$this->data['language'] = $this->document->getLanguage();
$this->data['links'] = $this->document->getLink();
$this->data['styles'] = $this->document->getStyle();
$this->data['scripts'] = $this->document->getScript();
$this->render('layout/layout.tpl');
}
}
?>
Front Controller:
<?php
class Front {
var $default;
var $error;
var $pre_action = array();
var $output;
function __construct(&$registry) {
$this->registry =& $registry;
}
function setDefault($default) {
$this->default = $default;
}
function setError($error) {
$this->error = $error;
}
function addPreAction($pre_action) {
$this->pre_action[] = $pre_action;
}
function dispatch(&$request, &$response) {
$action = $this->requestHandler($request);
while ($action) {
foreach ($this->pre_action as $pre_action) {
$result = $this->execute($pre_action);
if ($result) {
$action = $result;
break;
}
}
$action = $this->execute($action);
}
$response->set($this->output);
}
function execute($action) {
$action = $this->build($action);
$result = $action->process();
if ($result) {
return $result;
} else {
$this->output = $action->getOutput();
}
}
function build($action, $child = NULL) {
$file = DIR_CONTROLLER . $action . '.php';
$class = 'Action' . basename($action);
if (file_exists($file)) {
include($file);
$action = new $class($this->registry);
foreach ($action->children as $key => $value) {
$action->children[$key] = $this->build($value);
}
if ($child) {
$action->children[] = $child;
}
if ($action->parent) {
$action = $this->build($action->parent, $action);
}
return $action;
} else {
exit('Error: Could not create ' . $action . '!');
}
}
function requestHandler(&$request) {
if (!is_null($request->get('action'))) {
return $request->get('action');
} else {
return $this->default;
}
}
}
?>
Page Controller:
<?php
class Action {
var $id;
var $parent;
var $children = array();
var $data = array();
var $output;
var $registry;
function __construct(&$registry) {
$this->registry =& $registry;
}
function __set($key, $value) {
$this->registry->set($key, $value);
}
function __get($key) {
return $this->registry->get($key);
}
function getId() {
return $this->id;
}
function process() {
foreach ($this->children as &$child) {
$result = $child->process();
if ($result) {
return $result;
}
}
$result = $this->execute();
if ($result) {
return $result;
}
}
function forward($action) {
return $action;
}
function redirect($url) {
header('Location: ' . $url);
exit(0);
}
function render($filename) {
foreach ($this->children as &$child) {
$this->data[$child->getId()] = $child->getOutput();
}
$this->output = $this->fetch($filename);
}
function fetch($filename) {
$file = DIR_VIEW . $filename;
if (file_exists($file)) {
extract($this->data);
ob_start();
include($file);
$content = ob_get_contents();
ob_end_clean();
return $content;
} else {
exit('Error: View ' . $file . ' not found!');
}
}
function getOutput() {
return $this->output;
}
}
?>
As I said I think the correct way of doing it would be to use action chains to store data and pass it on from one action to the next. Having one controller do the redirecting, forwarding and rendering seems like its putting a lot of responsibility on a single object.