Construindo um framework PHP - Visão

Neste post vamos ver como construir e utilizar a parte de visão do nosso framework.

A visão é responsável por retornar alguma informação para o usuário(cliente). Essa informação normalmente é retornada em formato HTML, mas ela pode retornar em outros formatos também, como: JSON, XML, CSS etc.

A inclusão da visão nada mais é do que um _include _do arquivo. Vamos padronizar o local do arquivo(nome do nosso controlador) e nome(nome da ação) para facilitar a inclusão dele o código vai ficar assim:

aplicacao/controlador/ControladorInicial.php

class ControladorInicial
{
    public function acaoInicial() 
    {
        require "../aplicacao/visao/inicial/inicial.php";
    }
}

Simples, não? Para passar os dados para a nossa visão vamos criar variáveis no controlador e acessa-lás no arquivo de visão. Desta forma:

aplicacao/controlador/ControladorInicial.php

class ControladorInicial
{
    public function acaoInicial() 
    {
        $titulo = "Blog Planeta Framework";
        require "../aplicacao/visao/inicial/inicial.php";
    }
}

aplicacao/visao/inicial/inicial.php

<h1></h1>

Mas, pense comigo, se tivermos muitos controladores e muitas ações isso vai ficando cada vez mais complexo. Então, o que vamos fazer agora e organizar tudo isso. Vamos modificar a nossa função de autoload, construir uma classe de controlador, de visão e uma MVC para cuidar de tudo isso. Você vai ver como vai ficar bem mais fácil e organizado.

Nossa classes ficarão assim:

bibiloteca/Planeta/Mvc/Visao.php

class Planeta_Mvc_Visao
{
	public function renderizar($diretorio, $arquivo)
	{
            $local  = '../aplicacao/visao/';
	    require $local . $diretorio . '/' . $arquivo;
	}
}

bibiloteca/Planeta/Mvc/Controlador.php:

class Planeta_Mvc_Controlador
{
	protected $visao;
	
	public function __construct() 
	{
		$this->visao = new Planeta_Mcv_Visao();
	}
	
	public function renderizar()
	{
		$diretorio = strtolower(Planeta_Mcv_Visao::pegarInstancia()->pegarControlador());
		$arquivo   = strtolower(Planeta_Mcv_Visao::pegarInstancia()->pegarAcao()) . ".php";
		
		$this->visao->renderizar($diretorio, $arquivo);
	}
}

bibiloteca/Planeta/Mvc.php:

class Planeta_Mvc
{
    /**
     * Nome do controlador
     * 
     * @var string
     */
    protected $controlador;
    
    /**
     * Nome do controlador
     * 
     * @var string
     */
    protected $acao;
    
    /**
     * Instancia única do objeto Planeta_Mvc
     * 
     * @var Planeta_Mvc
     */
	private static $instancia;
    
    /**
     * Implementação do Singleton
     *
     * @return Planeta_Mvc 
     */
	public static function pegarInstancia()
	{
                //verifica se a instância existe
		if (!self::$instancia) {
			self::$instancia = new Planeta_Mvc();
		}
		
		return self::$instancia;
	}
	
    /**
     * Construtor privado para forçar o Singleton
     * 
     * @return void
     */
	private function __construct() 
	{}
    
    /**
     * Pega o controlador da requisição atual
     * 
     * @return string  
     */
    public function pegarControlador() 
    {
        return $this->controlador;
    }
    
    /**
     * Pega a ação da requisição atual
     * 
     * @return string  
     */
    public function pegarAcao() 
    {
        return $this->acao;
    }

         public function rodar()
         {
		//pega o modulo, controlador e acao 
		$controlador = isset($_GET['c']) ? $_GET['c'] : 'inicial';
		$acao		 = isset($_GET['a']) ? $_GET['a'] : 'inicial';
		
		//padronizacao de nomes
		$this->controlador = ucfirst(strtolower($controlador));
		$this->acao 	   = ucfirst(strtolower($acao));
		
                $nomeClasseControlador = 'Controlador' . $this->controlador;
	        $nomeAcao              = 'acao' . $this->acao;

                //verifica se a classe existe
		if (class_exists($nomeClasseControlador)) {
			$controladorObjeto = new $nomeClasseControlador;
			
			//verifica se o metodo existe
			if (method_exists($controladorObjeto, $nomeAcao)) {
				$controladorObjeto->$nomeAcao();
				return true;
			}
			throw new Exception('Acao nao existente.');
		}
		throw new Exception('Controlador nao existente.');
	}
    
        private function __clone() 
	{
		throw Exception('Nao pode');
	}
}

bibiloteca/Planeta/CarregadorAutomatico.php:

class Planeta_CarregadorAutomatico
{
    /**
     * Carrega a classe se ea existir
     *
     * @param string $nomeDaClasse
     * @return boolean
     */
	public static function carregar($nomeClasse)
	{
                //lista de diretorios que as classes serão pesquisadas
		$diretorios = array('../aplicacao/controlador', 
						    '../biblioteca');
		
                //transforma parte do nome da classe para diretorio
		$nomeClasse = str_replace(array('_', '\\'), '/', $nomeClasse);
		
                //procura as classes nos diretorios definidos 
		foreach ($diretorios as $diretorio) {
			//pega o caminho real do diretorio e junta com o nome da classe
                        $localClasse = realpath($diretorio) . '/' . $nomeClasse . ".php";
            
                        //checa se o arquivo existe
			if (file_exists($localClasse)) {
                                //inclue o arquivo
				require($localClasse);
                                //returna verdadeiro quando achou e para o loop
				return true;
			}
		}
		return false;
	}
	
    /**
     * Resitra o método para ser usado no autoload
     */
	public static function registrar()
	{
		spl_autoload_register('Planeta_CarregadorAutomatico::carregar');
	}
}

publico/index.php

require '../biblioteca/Planeta/CarregadorAutomatico.php';

Planeta_CarregadorAutomatico::registrar();
Planeta_Mvc::pegarInstancia()->rodar();

Agora para fazer referência a nossas variáveis de Visão vamos adicionar atributos na classe de Visão. E como o include agora está sendo feito dentro da classe de visão, no arquivo de visão iremos referenciar os atributos utilizando o $this. Assim:

aplicacao/controlador/ControladorInicial.php

class ControladorInicial extends Planeta_Mvc_Controlador
{
    public function acaoInicial() 
    {
        $this->visao->titulo = "Blog Planeta Framework";
        $this->renderizar();
    }
}

aplicacao/visao/inicial/inicial.php

<h1>titulo?></h1>

Ufa! Acho que por hoje já está bom. Nos vemos no próximo post.

Um grande abraço.

Espero que tenha te ajudado.

Published 08 January 2012