<?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>");
 
}
 
?> 
 
 |