wiki:WF/camadacontroller

Version 13 (modified by viani, 16 years ago) (diff)

--

Camada de Controle

WikiInclude(WF/tableofcontents)?

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 workflow, a camada de Controle está dividida em três níveis, cada qual com suas responsabilidades, 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 atividade, deve-se fazer o seguinte para implementá-lo:

  • Criar um arquivo com formato de nome seguindo o padrão class.AtividadeController.inc.php;
  • Armazenar o arquivo no diretório 'code' da estrutura de diretórios do processo. Se preferir editar os arquivos de controle pela interface web, eles ficam na aba 'includes' da Edição interface de codificação;
  • 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.

O acionamento da camada de Controle se dará pela execução do método run();

Exemplo de uma classe Controller de uma atividade:

<?php
/**
 * Camada de Controle a nível de atividade
 * @author Fulano
 * @version 1.x
 * @license http://www.gnu.org/copyleft/gpl.html GPL 
 * @package Nome_do_processo
 */
class AtividadeController extends Controller
{ 
	/**
	 * Acao padrao/inicial da atividade.
	 * @return void
	 * @access public
	 */
	function __default()
	{		
		$this->model->defaultAction();
		$this->loadViewVars();
		$this->showForm($this->TEMPLATEPADRAO);
	}
	
	/**
	 * Executa a ação  da atividade compor e encerra a execução da atividade.
	 * @return void
	 * @access public 
	 */
	function salvar()
	{               
	   	if (!$this->model->salvarAction())
	   	{
	   		$this->loadViewVars();
			$this->showForm($this->COMPOR);	
	   	}
	}    
} 
?>

Neste exemplo, o método run() (declarado na classe Controller) recebe como parâmetro a ação a ser executada, e o método dispatch() está encarregado de executar o método de controle correspondente. Assim, se for passada a ação 'salvar' será executado o método salvar() desta mesma classe.

Caso nenhuma ação seja recebida, será executado o método __default(), também definido nesta classe.

Note que para cada ação que for necessária na atividade, deverá existir um método correspondente na camada Controller.

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

Tudo que foi falado até aqui sobre a camada Controller está contido no escopo da atividade, mas note que na definição da classe Controller, existe uma herança de outra classe, representado pela cláusula 'extends Controller'. Isso significa que existe uma classe superior (pai) da qual a classe em questão é filha. Na classe pai existem métodos que são comuns a todos as classes Controller das atividades do processo em questão. Esta maneira de programar por objetos, com herança, é fundamental para evitar a repetição de código.

Continuando com o exemplo, teremos uma classe Controller, a nível de processo, cujo código está exemplificado a seguir. Esta classe também fica armazena no diretório 'code', e nome do arquivo deve seguir o formato class.Controller.inc.php

<?php
/**
 * Gerencia o processo Atos Administrativos
 * @author carloseduardo
 * @author viani
 * @author aleheil
 * @version 1.4
 * @license http://www.gnu.org/copyleft/gpl.html GPL 
 * @package Atos_Administrativos
 */
class Controller extends BaseController
{	
    /**
     * @var string Tela inicial da atividade Compor
     * @access public
     */
	var $COMPOR = 'Compor.tpl';

    /**
     * @var string Tela da atividade Consultar
     * @access public
     */
	var $CONSULTAR = 'Consultar.tpl';

    /**
     * @var string Tela da atividade Alterar
     * @access public
     */
	var $ALTERAR = 'alterar.tpl';

    /**
     * @var string Tela da atividade Visualizar
     * @access public
     */
	var $VISUALIZAR = 'visualizar.tpl';     

    /**
     * Construtor da classe
     * @param object $model Instância da camada Model
     * @param array Configurações do ambiente MVC
     * @return object
     * @access public
     */ 
    function Controller(&$model , &$env)
    {
        $this->super(&$model , &$env);
        $this->assign('inbox', $this->model->getWfProperty('wf_workflow_path') . 
                       SEP . 'index.php?start_tab=0');
	$this->assign('processes', $this->model->getWfProperty('wf_workflow_path') . 
                       SEP . 'index.php?start_tab=1');
	$this->assign('activity_title', 'Atos Administrativos');
    }    	

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

Na classe de Controle, a nível de processo, exemplificada no código anterior, iremos colocar tudo aquilo que for comum às classes Controle das atividades. A classe começa definindo as constantes que representam os templates do processo. Depois implementa o método construtor 'Controller', que no exemplo, está definindo três variáveis da camada View, que ficarão disponíveis para as classes que a estenderem. Também é implementado o método run() que é responsável por chamar o método adequado de cada classe Controller das atividades. Podemos notar que, no exemplo, este método já está estabelecendo uma conexão com o banco de dados do processo (feita através do comando $this->model->DAO->connect()), mas isto é opcional.

Mais uma vez observamos a existência de uma cláusula 'extends' que neste caso está estendendo a classe BaseController. Essa classe está definida a nível de módulo e contém métodos de uso geral para atividades de Controle, que estão disponíveis para as classes filhas.

Segue uma explicação dos atributos da classe BaseController:

  • view: objeto da classe Smarty que representa a camada View;
  • templateFile: armazena o nome do template em uso pela 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.

Resumindo, a implementação da camada Controller de uma atividade estará representada por três classes, com herança entre elas:

  • BaseController: age em todos os processos desenvolvidos sob o padrão MVC no módulo de workflow;
  • Controller: estende o nível de módulo. Age somente sobre as atividades dos processos;
  • AtividadeController: estende os níveis anteriores. Recebe e responde as requisições do usuário final dos processos.