E ai pessoal, tudo bem? Hoje vamos continuar nosso exemplo da livraria. Para quem ainda não viu a primeira parte do artigo, é só clicar aqui.
A primeira coisa que vamos fazer é adicionar algumas linhas para nosso index. Coloque esse trecho de código antes da tabela.
{if $Session->check('Message.status')}
<div class="bs-docs-example">
<div>
<button type="button" class="close" data-dismiss="alert">×</button>
{$Session->flash()}
</div>
</div>
{/if}
Aqui nós estamos criando uma verificação de mensagens flash. As mensagens flash servem para passarmos mensagens entre as requisições e isso é muito útil quando não utilizamos ajax. Nós criamos duas flashs: uma é para dizer qual o tipo da mensagem (sucesso, erro, alerta) e a outra a mensagem propriamente dita.
A próxima modificação é mais simples. Criaremos um link para adicionar postagens:
<a href="{$Url->action("add", "categorias")}"><i class="icon-plus"></i>{__(" Nova Categoria")}</a>
Note que utilizamos o Helper $Url para apontar para uma action em um controller, isso irá gerar “/categorias/add”.
Validando Dados de um formulário
Vamos refazer nossa action para adicionar uma categoria:
public function add() { if ($this->RequestHandler->isPost()) { //Vamos salvar os dados que vieram de um formulário de cadastro if ($this->Categoria->save($this->data)) { $this->Session->setFlash("alert-success", "status"); $this->Session->setFlash("Categoria salva com sucesso!"); } else { $this->Session->setFlash("alert-error", "status"); $this->Session->setFlash("Ocorreu um erro ao salvar a categoria."); } //redirecionamos para a listagem $this->redirectToAction("index"); } else { $status = array( "ATIVO" => "ATIVO", "INATIVO" => "INATIVO" ); $this->status = new SelectList($status, null, null); } }
Vou explicar o que estamos fazendo nesse método. Primeiramente vamos verificar se o usuário está fazendo uma requisição POST ou GET. Caso seja POST, ele irá tentar salvar os dados da categoria e em seguida redirecionar para a action index() que é nossa listagem. Caso a requisição seja GET, então, nós vamos criar e passar para a view um tipo de objeto chamado SelectList, que trata a forma de como as listas devem se comportar em um combobox no HTML. Então criamos um array com os possíveis status da categoria e passamos para o construtor do nosso objeto. Após isso, a view será renderizada.
Vamos criar nossa view para adicionar uma categoria, salve ela na pasta App/View/Pages/Categorias/add.tpl
Aqui está nossa View de adição de postagens:
{block name="content"}
<div class="page-header">
<h1>{__("Adicionar Categoria")}</h1>
</div>
{$Form->create("add", "categorias")}
{$Form->inputTextLabel("nome")}
{$Form->dropDownListLabel($status, "status")}
<div class="form-actions">
{$Form->submit("Salvar", ["class" => "btn btn-primary"])}
<button type="button" class="btn">Cancel</button>
</div>
{$Form->close()}
{/block}
Criamos um input para digitarmos o nome da categoria, e criamos um combobox para listarmos os status disponíveis para a categoria. Lembrando que esse método aceita apenas objetos do tipo SelectList, por isso criamos ele anteriormente. Já podemos criar a validação dos dados.
Como é realizado a validação no EasyFw? Muito simples: através de anotações. Vejamos como irá ficar nossa classe de categoria…
O que nós estamos fazendo com nossa classe? Estamos dizendo para ela que o nome será requerido e não pode ser vazio e o status da categoria é requerido. Agora, se tentarmos incluir algo com os campos vazios, automaticamente será retornado um erro para o formulário e mostrado para o usuário.
Editando categorias
Podemos criar a edição das categorias que funciona de forma muito parecida com a inclusão. No controller CategoriasController criem a action view() e edit().
public function view($id) { $this->categoria = $this->Categoria->getEntityManager()->read(null, $id); $status = array( "ATIVO" => "ATIVO", "INATIVO" => "INATIVO" ); $this->status = new SelectList($status, null, null); } public function edit($id) { $categoria = $this->Categoria->getEntityManager()->read(null, $id); $this->updateModel($categoria, $this->data); //Vamos salvar os dados que vieram de um formulário de cadastro if ($this->Categoria->save($categoria)) { $this->Session->setFlash("alert-success", "status"); $this->Session->setFlash("Categoria salva com sucesso!"); } else { $this->Session->setFlash("alert-error", "status"); $this->Session->setFlash("Ocorreu um erro ao salvar a categoria."); } //redirecionamos para a listagem $this->redirectToAction("index"); }
Por que nós criamos duas actions? Para separarmos melhor a nossa lógica. Criamos uma action view() que será chamada quando o usuário solicitar a página de edição da categoria, e a action edit() que fará a lógica para salvar a edição no banco.
A action view() recebe um $id como parâmetro, que será passado pela URL. Com o $id em mãos iremos procurar o registro no banco e retorná-lo para a View, nós também passamos os status para uma combobox da nossa edição.
Na action edit() nós também recebemos um $id como parâmetro. Com ele vamos encontrar o registro no banco de dados e vamos atualizá-lo utilizando o método updateModel() – isso evita que tenhamos que atualizar cada campo manualmente. Logo em seguida, nós salvamos no banco e redirecionamos para a action index().
Vamos criar nossa View de edição. Ela será muito parecida com a de inclusão; salve-a na pasta App/View/Pages/Categorias/view.tpl:
{block name="content"}
<div class="page-header">
<h1>{__("Editar Categoria")}</h1>
</div>
{$Form->create("edit", "categorias", $categoria->id)}
{$Form->inputTextLabelFor($categoria->nome, "nome")}
{$Form->dropDownListLabelFor($status, $categoria->status, "status")}
<div class="form-actions">
{$Form->submit("Salvar", ["class" => "btn btn-primary"])}
<button type="button" class="btn">Cancel</button>
</div>
{$Form->close()}
{/block}
Notem que agora nossos métodos tem um sufixo FOR; esses métodos são para preencher os campos com valores. Nós falamos a propriedade que será preenchida no campo e damos o nome do campo (lembrando que o nome do campo deve ser igual o nome do campo do banco de dados).
Excluindo categorias
Finalmente, para finalizar o CRUD de categorias vamos deletar um registro. O método é bem simples.
public function delete($id) { if ($this->RequestHandler->isPost()) { //Vamos salvar os dados que vieram de um formulário de cadastro if ($this->Categoria->delete($id)) { $this->Session->setFlash("alert-success", "status"); $this->Session->setFlash("Categoria excluida com sucesso!"); } else { $this->Session->setFlash("alert-error", "status"); $this->Session->setFlash("Ocorreu um erro ao excluir a categoria."); } //redirecionamos para a listagem $this->redirectToAction("index"); } else { $this->categoria = $this->Categoria->getEntityManager()->read(null, $id); } }
A action delete() recebe um $id como parâmetro, onde esse id é a categoria que queremos excluir. Caso a requisição venha por POST, nós vamos tentar excluir a categoria. Se der certo, mandamos a mensagem de sucesso; caso contrário mandamos a de erro.
Caso a requisição venha por GET, nós mostramos uma tela de confirmação da exclusão – salve-a na pasta App/View/Pages/Categorias/delete.tpl. A tela de confirmação ficará assim:
{block name="content"}
<div class="page-header">
<h1>{__("Excluir Categoria")}</h1>
</div>
{$Form->create("delete", "categorias", $categoria->id)}
{$Form->inputTextLabelFor($categoria->nome, "nome", ["disabled" => true])}
{$Form->inputTextLabelFor($categoria->status, "status", ["disabled" => true])}
<div class="form-actions">
{$Form->submit("Confirmar", ["class" => "btn btn-primary"])}
<button type="button" class="btn">Cancel</button>
</div>
{$Form->close()}
{/block}
Estamos utilizando o terceiro parâmetro dos inputs, que é o HtmlOptions. Nele estamos dizendo que vamos desabilitar os inputs do HTML com [“disabled” => true].
Conclusão
Espero que tenham gostado da continuação do artigo. Tentei ser bem claro e espero ter conseguido. No próximo artigo vamos continuar esse exemplo e começar a trabalhar com modelos relacionados. Nos artigos futuros vou tentar explicar como criar uma API REST com esse exemplo e utilizar o jQuery mobile para acessarmos os serviços.
Para que quiser baixar o projeto, é só clonar o repositório no GitHub.
Obrigado pelo apoio e atenção pessoal. Abraços!
Links
- Site do Framework: http://www.easyframework.net
- Repositório no Github: https://github.com/LellysInformatica/EasyFramework
- Repositório do Easy Skeleton: https://github.com/LellysInformatica/easyskeleton