wiki:WF/camadacontroller

Camada de Controle

Por definição, a camada de Controle faz o gerenciamento entre o usuário, as Views (interfaces) e a Model (funções do sistema). Ela deve saber apenas quais são as funções do sistema e não como implementá-las. Será responsável por receber as ações solicitadas pelo usuário, chamar a implementação da Model correspondente e com base na resposta, encaminhar uma interface (View) adequada de volta ao usuário.

No esquema MVC, empregado no módulo workflow, a camada de Controle está dividida em três níveis, cada qual implementando parte da solução, como descrito a seguir:

  • Nível módulo: age sobre todos os processos de workflow;
  • Nível processo: extende o nível de módulo e age sobre todas as atividades do processo;
  • Nível atividade: extende o nível de processo e age somente sobre a atividade.

Começando pelo nível de módulo, ele é representado pela classe BaseController, que possui atributos e métodos de uso geral, disponíveis para todas as atividades. A classe não precisa ser codificada porque já está inclusa no pacote de código do módulo workflow. Basta estendê-la.

Atributos da classe BaseController:

  • templateFile: armazena o nome do template em uso pela camada View;
  • view: objeto da classe Smarty que representa a camada View;
  • model: objeto da classe Model da atividade.

Métodos da classe BaseController:

  • showForm: troca o template em uso;
  • syncVars: transfere todos os atributos da camada Model para a Camada View;
  • loadViewVars: recupera os dados produzidos pela camada Model e os transfere para a camada View;
  • assign: define o valor de uma variável da camada View;
  • cancelar: aborta a execução da atividade corrente;
  • dispatch: executa a ação solicitada pelo usuário;
  • __default: método abstrato a ser redefinido nas classes filhas;
  • run: método abstrato a ser redefinido nas classes filhas.

Partindo para o nível de processo, ele é representado pela classe Controller, que deve ser implementada pelo desenvolvedor do processo, seguindo estas diretrizes:

  • Criar um arquivo com o nome class.Controller.inc.php;
  • Armazenar o arquivo no diretório 'code' da estrutura de diretórios do processo;
  • Se preferir editar o arquivo pela interface web, ele fica na aba 'includes' da interface de codificação;
  • Definir uma classe com o nome Controller, e que estenda a classe BaseController;
  • Definir um ou mais atributos para os templates da atividade;
  • Implementar o método __default();
  • Implementar o método run().

Eis um exemplo de classe Controller de um processo:

<?php
/**
 * Implementa a Classe Controller do Processo
 * @author Fulano
 * @version 1.x
 * @license http://www.gnu.org/copyleft/gpl.html GPL 
 * @package Nome_do_Processo
 */
class Controller extends BaseController
{	
    /**
     * @var string Template padrão da atividade
     * @access protected
     */
	var $TEMPLATEPADRAO = 'template.tpl';

    /**
     * Construtor da classe
     * @param object $model Instância da camada Model
     * @param array Configurações do ambiente MVC
     * @return object
     * @access protected
     */ 
    function Controller(&$model , &$env)
    {
        $this->super(&$model , &$env);
    }    	

    /**
     * Execucao da atividade.
     * @param $action Servico (acao) solicitado
     * @return void
     * @access protected
     */
    function run($action)
    {
        $this->dispatch($this->getNormalizedAction($action));
    }
    
}
?>

O acionamento da camada de Controle se dará pela execução do método run(), que por sua vez fará uso do método dispatch(), que analisará a ação requisitada e executará o método de ação adequado. Assim, se for requisitada uma ação 'salvar', será executado o método salvar(), que deverá estar declarado a nível de atividade. Caso nenhuma ação seja recebida, será executado o método __default().

Continuando, agora é a hora de implementar a classe de Controle a nível de atividade. Para isso fazer o seguinte:

  • Criar um arquivo com formato de nome seguindo o padrão class.Atividade.Controller.inc.php;
  • Armazenar o arquivo no diretório 'code' da estrutura de diretórios do processo;
  • Definir uma classe com nome no formato AtividadeController, e que extenda a classe Controller do processo;
  • Implementar um método __default();
  • Implementar um método run();
  • Implementar um método para cada ação da atividade.

Exemplo de uma classe Controller de uma atividade:

<?php
/**
 * Implementa a Camada Controller da atividade Cadatrar
 * @author Fulano
 * @version 1.x
 * @license http://www.gnu.org/copyleft/gpl.html GPL 
 * @package Nome_do_Processo
 */
class CadastrarController extends Controller
{ 
	/**
	 * Acao padrao/inicial da atividade.
	 * @return void
	 * @access protected
	 */
	function __default()
	{		
		$this->model->defaultAction();
		$this->loadViewVars();
		$this->showForm($this->TEMPLATEPADRAO);
	}
	
	/**
	 * Executa a ação salvar da atividade
	 * @return void
	 * @access protected
	 */
	function salvar()
	{               
	   	if (!$this->model->salvarAction())
	   	{
	   		$this->loadViewVars();
			$this->showForm($this->TEMPLATEPADRAO);	
	   	}
	}
} 
?>

Note que os métodos run() e __default() devem ser implementados, seja na classe Controller ou na classe AtividadeController, dependendo de como o desenvolvedor julgar mais conveniente.

É importante ressaltar que para cada ação da atividade, deverá existir um método correspondente na classe a nível de atividade.

Analisando o método salvar(), vemos que o mesmo faz uso da camada Model para executar a operação de sistema (salvarAction) e caso obtenha sucesso irá carregar os dados na camada View e a seguir definir qual o template será usado para mostrá-los.