Usamos cookies para medir audiência e melhorar sua experiência. Você pode aceitar ou recusar a qualquer momento. Veja sobre o iMasters.
Como se criar e quais as vantagens de criar uma classe Action que gere instancias padrões para a aplicação?
Ou seja, extender um controller de uma classe action que por sua vez extende de Zend_Controller_Action.
<?php
class App_Controller_Action extends Zend_Controller_Action {
...
}
<?php
class UsuariosController extends App_Controller_Action {
...
}
Ouvi dizer que isso é ideal para não ter que ficar instanciado os models em diversas partes da aplicação, parametros, etc...
Há possibilidades de você postar um exmplo de como faz?
Grato
Vamos lá:
<?php
/**
* Classe que define um controller padrão para o sistema administrativo
*
* @author Matias Rezende
*/
abstract class App_Controller_Crud extends Zend_Controller_Action {
/**
* @var App_Mapper_Abstract
*/
protected $_model = null;
/**
* @var string
*/
protected $_name = null;
/**
* @var array
*/
protected $_filtros = array ();
/**
* Método executado no início do controller
*/
public function init() {
$name = end ( explode ( '_', get_class ( $this ) ) );
$name [0] = strtolower ( $name [0] );
$this->_name = $name;
$this->_model = $this->modelFactory ();
$this->_filtros = array (
new Zend_Filter_StringTrim (),
new Zend_Filter_StripTags ( array (
'encoding' => 'UTF-8'
) )
);
}
/**
* Método responsável por listar os itens cadastrados
*/
public function listarAction() {
$paginacao = Zend_Paginator::factory ( $this->_model->getGrid ( $this->_request->getParams () ) )->setCurrentPageNumber ( $this->_request->getParam ( 'pagina', 1 ) )
->setItemCountPerPage ( 30 );
$this->view->lista = $paginacao;
}
/**
* Método responsável por inserir os dados do formulário no banco de dados.
* Faz a validação dos dados de acordo com o formulário cadastrado.
*/
public function inserirAction() {
$form = $this->getForm ();
if ($this->_request->isPost () && $form->isValid ( $this->_request->getPost () )) {
$id = $this->_model->insert ( $form->getValues () );
$this->_helper->flashMessenger->addMessage ( array (
'true' => sprintf ( '%s incluído com sucesso.', $this->_name )
) );
$this->_helper->redirector ( 'listar' );
}
$this->view->action = 'Inserir';
$this->view->form = $form;
$this->render ( 'form', null, true );
}
/**
* Método que faz a edição dos itens
*/
public function editarAction() {
$id = intval ( $this->_request->getParam ( 'id', 0 ) );
if (empty ( $id )) {
$this->_helper->flashMessenger->addMessage ( array (
'false' => 'Erro inesperado.'
) );
$this->_helper->redirector ( 'listar' );
}
$form = $this->getForm ( $id );
if ($this->_request->isPost ()) {
if ($form->isValid ( $this->_request->getPost () )) {
$this->_model->update ( $form->getValues (), array (
sprintf ( '%sId = ?', $this->_name ) => $id
) );
$this->_helper->flashMessenger->addMessage ( array (
'true' => sprintf ( '%s alterado com sucesso.', $this->_name )
) );
$this->_helper->redirector ( 'listar' );
}
} else {
$form->populate ( $this->_model->find ( $id )
->current ()
->toArray () );
}
$this->view->action = 'Alterar';
$this->view->form = $form;
$this->render ( 'form', null, true );
}public function deletarAction() {
$id = intval ( $this->_request->getParam ( 'id', 0 ) );
if (! empty ( $id )) {
$this->_model->delete ( array (
sprintf ( '%sId = ?', $this->_name ) => $id
) );
$this->_helper->flashMessenger->addMessage ( array (
'true' => sprintf ( '%s excluído com sucesso.', $this->_name )
) );
} else {
$this->_helper->flashMessenger->addMessage ( array (
'false' => 'Erro inesperado.'
) );
}
$this->_helper->redirector ( 'listar' );
}
/**
* Formulário para cadastro
*
* @param int $id o id do item para excluir da validação
* @return Zend_Form
*/
abstract protected function getForm($id = 0);
/**
* Método que cria o model de acordo com o namespace definido na classe filha
* @return App_Mapper_Abstract
*/
private function modelFactory() {
$className = sprintf ( 'Model_%s', ucfirst ( $this->_name ) );
$objeto = new $className ();
if (! $objeto instanceof App_Model_Abstract) {
throw new Zend_Exception ( 'A classe model solicitada não implementa os métodos necessário.' );
}
return $objeto;
}
}
Usando, por exemplo para usuários:
Tabela do banco:
SET @OLD_UNIQUE_CHECKS=@@UNIQUE_CHECKS, UNIQUE_CHECKS=0;
SET @OLD_FOREIGN_KEY_CHECKS=@@FOREIGN_KEY_CHECKS, FOREIGN_KEY_CHECKS=0;
SET @OLD_SQL_MODE=@@SQL_MODE, SQL_MODE='TRADITIONAL';
CREATE SCHEMA IF NOT EXISTS `exemplo` ;
USE `exemplo` ;
-- -----------------------------------------------------
-- Table exemplo.usuario
-- -----------------------------------------------------
CREATE TABLE IF NOT EXISTS `exemplo`.`usuario` (
`usuarioId` MEDIUMINT(8) NOT NULL AUTO_INCREMENT ,
`usuarioNome` VARCHAR(100) NOT NULL ,
`usuarioLogin` VARCHAR(100) NOT NULL ,
`usuarioSenha` VARCHAR(100) NOT NULL ,
PRIMARY KEY (`usuarioId`) )
ENGINE = InnoDB;
SET SQL_MODE=@OLD_SQL_MODE;
SET FOREIGN_KEY_CHECKS=@OLD_FOREIGN_KEY_CHECKS;
SET UNIQUE_CHECKS=@OLD_UNIQUE_CHECKS;
O controller:
<?php
class Sistema_UsuarioController extends App_Controller_Crud {
public function init() {
// deixar aqui caso queira fazer alguma coisa antes de inicializar este controller
parent::init ();
}
protected function getForm($id = 0) {
$form = new Zend_Form ();
$form->setMethod ( Zend_Form::METHOD_POST );
$nome = new Zend_Form_Element_Text ( 'usuarioNome' );
$nome->setLabel ( 'Nome *' )
->setAttrib ( 'maxlenght', 100 )
->setRequired ()
->addFilters ( $this->_filtros );
$login = new Zend_Form_Element_Text ( 'usuarioLogin' );
$login->setLabel ( 'Email: * ' )
->setRequired ()
->setAttrib ( 'maxlenght', 100 )
->addValidator ( new Zend_Validate_EmailAddress () )
->addValidator ( new Zend_Validate_Db_NoRecordExists ( array (
'table' => 'usuario',
'field' => 'usuarioLogin',
'exclude' => array (
'field' => 'usuarioId',
'value' => $id
)
) ) );
$senha = new Zend_Form_Element_Password ( 'usuarioSenha' );
$senha->setLabel ( 'Senha *' )
->setRequired ();
$confSenha = new Zend_Form_Element_Password ( 'confPassword' );
$confSenha->setLabel ( 'Confirme sua Senha: * ' )
->addValidator ( new Zend_Validate_Identical ( $this->_getParam ( 'usuarioSenha' ) ) )
->addErrorMessage ( 'A senha e a confirmação de senha não batem.' )
->setIgnore ( true );
$submit = new Zend_Form_Element_Submit ( 'send' );
$submit->setLabel ( 'Enviar' );
$form->addElements ( array (
$nome,
$login,
$senha,
$confSenha,
$submit
) );
return $form;
}
}
listar.phtml:
<h3>Listar Usuários</h3>
<table width="100%">
<thead>
<tr>
<th>Nome</th>
<th>Email</th>
<th>Ações</th>
</tr>
</thead>
<tbody>
<?php if(count($this->lista)) : ?>
<?php foreach ($this->lista as $item) : ?>
<tr>
<td><?php echo $item->nome ?></td>
<td><?php echo $item->login ?></td>
<td>
<a href="<?php echo $this->url(array('action' => 'editar','id' => $item->id)) ?>">Editar usuário</a>
<a href="<?php echo $this->url(array('action' => 'deletar','id' => $item->id)) ?>" onclick="return confirm('Confirma a exclusão?')">Excluir Usuário</a>
</td>
</tr>
<?php endforeach;?>
<?php else :?>
<tr class="empty">
<td colspan="3">Não há registros a serem listados</td>
</tr>
<?php endif;?>
</tbody>
</table>
<?php echo $this->paginationControl($this->lista,null,'paginator.phtml');?>
Para o formulário você pode criar um arquivo chamado form.phtml de deixá-lo em /views/scripts/form.phtml, contendo algo parecido com isto:
<?php echo $this->form?>
Para renderizar o formulário na tela.
Criando o Model e com isto você tem um CRUD básico para a tabela de usuários.
Carlos Eduardo
Nossa Carlos, matou a pau...
Melhor impossivel. show de bola.
Com essa explicação acredito que conseguirei deixar meus projetos mais genericos nessa ações de crud.
Também estou refatorando algumas coisa em relação aos models e ao dbtable.
Obrigado mesmo.
Eu faço assim. Permite criar rotinas padrões (como você mesmo citou sobre Model) e evitar código duplicado, principalmente em se falando do CRUD básico.
Por exemplo, com meu controller padrão (que eu utilizo em admin de sites, por exemplo), para criar o CRUD de uma tabela, preciso criar o Model e o formulário dele e pronto.
Carlos Eduardo