<?php
/**************************************
PHP MVC2
by FatFOX 19/07/2007
marcio.gh at gmail.com
- do
Front Controller PHP
Configurado para acesso Friendly URLs:
http:// [your_host] /do/ActionName/arg1/arg2/...
Apache deve ser configurado para forçar o "do" como um script PHP
httpd.conf:
<Files do>
ForceType application/x-httpd-php
</Files>
- class MVC_Config
Interpreta "config.xml", que contém as configurações do controlador
- class MVC_RequestProcessor
Implementa proccessRequest($MVC_Config) que processa todas as requisições.
Lança exceções caso encontre algum erro
***************************************/
class MVC_Config {
public $config_file;
public $templates;
public $actions;
private $tmp_module;
private $tmp_auth_module;
private $tmp_action;
private $tmp_global_forwards;
private $tmp_type;
private $tmp_forwards;
function MVC_Config($config_file = "/config.xml") {
$this->config_file = $_SERVER['DOCUMENT_ROOT'].$config_file;
$xml_parser = xml_parser_create();
xml_parser_set_option($xml_parser, XML_OPTION_CASE_FOLDING, false);
xml_set_element_handler($xml_parser, array(&$this, "XMLstartElement"), array(&$this, "XMLendElement"));
if (!($fp = fopen($this->config_file, "r"))) {
throw new Exception("MVC: Erro abrindo configuracao XML: ". $this->config_file);
}
while ($data = fread($fp, 4096)) {
if (!xml_parse($xml_parser, $data, feof($fp))) {
throw new Exception(sprintf("MVC: Erro XML: %s na linha %d",
xml_error_string(xml_get_error_code($xml_parser)),
xml_get_current_line_number($xml_parser))
);
}
}
xml_parser_free($xml_parser);
}
function XMLstartElement($parser, $name, $attrs) {
if ($name == "xml") {
$this->actions = array();
$this->templates = array();
$this->auth_modules = array();
unset($this->tmp_module);
unset($this->tmp_auth_module);
unset($this->tmp_global_forwards);
unset($this->tmp_action);
unset($this->tmp_type);
$this->tmp_forwards = array();
}
if ($name == "template") {
$template_idx = $attrs["name"];
$this->templates[$template_idx] = $attrs["file"];
}
if ($name == "auth-module") {
$auth_module_idx = $attrs["name"];
$this->auth_modules[$auth_module_idx] = array("require_session_user"=>$attrs["require-session-user"], "login_action"=>$attrs["login-action"]);
}
if ($name == "module") {
$this->tmp_module = $attrs["name"];
$this->tmp_auth_module = $attrs["auth-module"];
}
if ($name == "global-forward") {
$this->tmp_global_forwards[$attrs["name"]] = array("file"=>$attrs["file"], "template"=>$attrs["template"]);
}
if ($name == "action") {
$this->tmp_action = $attrs["name"];
$this->tmp_type = $attrs["type"];
}
if ($name == "forward") {
$this->tmp_forwards[$attrs["name"]] = array("file"=>$attrs["file"], "template"=>$attrs["template"]);
}
}
function XMLendElement($parser, $name) {
if ($name == "action") {
if (is_array($this->tmp_global_forwards)) {
$this->tmp_forwards = array_merge($this->tmp_forwards, $this->tmp_global_forwards);
}
$this->actions[$this->tmp_action] = array("module"=>$this->tmp_module, "type"=>$this->tmp_type, "auth_module"=>$this->tmp_auth_module, "forwards"=>$this->tmp_forwards);
$this->tmp_forwards = array();
}
if ($name == "module") {
$this->tmp_global_forwards = array();
}
if ($name == "xml") {
unset ($this->tmp_module);
unset ($this->tmp_auth_module);
unset ($this->tmp_action);
unset ($this->tmp_global_forwards);
unset ($this->tmp_forwards);
unset ($this->tmp_type);
}
}
}
class MVC_RequestProcessor {
static $Config;
function proccessRequest($Config) {
self::$Config = $Config;
$args = explode("/", $_SERVER['PATH_INFO']);
array_shift($args);
$do = $args[0];
if (!isset($do)) {
throw new Exception("proccessRequest: Acao nao informada");
}
foreach (self::$Config->actions as $action_name=>$mapping) {
if ($action_name == $do) {
$MyMapping = $mapping;
break;
}
}
if (! isset($MyMapping)) {
throw new Exception("proccessRequest: Acao '". $do ."' inexistente");
}
if ($MyMapping["auth_module"]) {
$auth_module = self::$Config->auth_modules[$MyMapping["auth_module"]];
if (! is_array($auth_module)) {
throw new Exception("proccessRequest: Acao '". $do ."' solicitou modulo de autenticacao inexistente: ". $MyMapping["auth_module"]);
}
if (! isset($_SESSION[$auth_module["require_session_user"]])) {
$_SESSION["auth_module_destination"] = $_SERVER["REQUEST_URI"];
header("Location: /do/". $auth_module["login_action"]);
}
}
$actionClassFile = $_SERVER['DOCUMENT_ROOT'] ."/". $MyMapping["module"] ."/". $MyMapping["type"] .".class.php";
if (! is_file($actionClassFile)) {
throw new Exception("proccessRequest: Classe '". $actionClassFile ."' nao encontrada");
}
include($actionClassFile);
$Action = new $MyMapping["type"];
$_REQUEST['args'] = $args;
$forward = $Action->execute($_REQUEST, $_SESSION);
if (! isset($MyMapping["forwards"][$forward])) {
throw new Exception("processRequest: Classe '". $actionClassFile ."' retornou forward inexistente '". $forward ."'");
}
$Forward = $MyMapping["forwards"][$forward];
$file = $Forward["file"];
if (substr($file, 0, 1) == "/") {
$view_file = $_SERVER['DOCUMENT_ROOT'] . $file;
} else {
$view_file = $_SERVER['DOCUMENT_ROOT'] ."/". $MyMapping["module"] ."/view/". $file;
}
if (! is_file($view_file)) {
throw new Exception("proccessForward: Arquivo de visão do forward '". $forward ."' da Acao '". $do ."' não encontrado: ". $view_file);
}
$template_idx = $Forward["template"];
$template = self::$Config->templates[$template_idx];
if (isset($template)) {
$template_file = $_SERVER['DOCUMENT_ROOT'] . "/" . $template;
if (! is_file($template_file)) {
throw new Exception("proccessForward: Arquivo de template do forward '". $forward ."' da Acao '". $do ."' não encontrado: ". $template_file);
}
ob_start();
include $view_file;
$MVC_conteudo = "\n<div id='div". $do ."'>\n";
$MVC_conteudo.= ob_get_contents();
$MVC_conteudo.= "\n</div>\n";
ob_end_clean();
include($template_file);
ob_flush();
} else {
include($view_file);
}
}
}
try {
session_start();
MVC_RequestProcessor::proccessRequest(new MVC_Config());
} catch (Exception $e) {
exit("<pre>". $e->getMessage() ."</pre>");
}
?>
|