Admin - Voltando ao Gii (CRUD) — Parte 1!

Cálcio Heavy Metal
PHPRio
Published in
8 min readMar 28, 2018

No artigo anterior implementamos as rotinas de autenticação e autorização no admin. Nesse artigo vamos implementar os CRUDs do admin e customizar as views do CRUD Category.

CRUDs no admin

Como já foi dito em outro post, nosso admin é o nosso backend do site, onde os administradores poderão cadastrar, alterar e deletar dados e qualquer outra função de administrador.

Vamos começar fazendo mais uma pequena mudança no menu.

vitrine\views\layouts\admin.php

Acesse o Gii (http://localhost/vitrine/web/gii/) para criamos nossos models e dar vida ao admin.

Model Produtos

Repare no campo Namespace. O que fiz, foi alterar a rota padrão para app\modules\admin\models, sendo assim o modelo foi criado dentro do diretório models em nosso admin. Também ativei a I18N que serve para fazer sites multi-linguas.

Por usarmos os nomes das tabelas no plural e as classes no singular, precisamos modificar as relations (relações) no modelo. Para isso substitua todos os Categories por Category.

Movendo os models Category e ProductImage para o admin.

Para não termos que recriar esses modelos novamente, vamos simplesmente movê-los de /models/ para modules/admin/models/.
Precisamos mudar também os namespaces de app/models para app/modules/admin/models.
Assim como foi feito nas relations de Product altere para singular: Products:: para Product::.

CRUD Product

Repare que todos os campos do gerador do CRUD foi modificados, todos eles apontam para o módulo admin. Habilitamos aqui também I18N e Pjax que já integra a grid com o AJAX.

CRUD Category

Repare que todos os campos do gerador do CRUD foi modificados, todos eles apontam para o módulo admin. Habilitamos aqui também I18N e Pjax que já integra a grid com o AJAX.

CRUD User

Para simplificar copie o model disponível no git e substitua ele no seu User model.

/vitrine\modules\admin\models\User.php
Mais para frente faremos um tratamento especial nesse CRUD.

Limpando CRUDs anteriores

Fizemos uns CRUDs de testes somente com o objetivo de mostrar como desenvolver com Yii é prático e rápido. Agora vamos remover os CRUDs criados anteriormente. No site não há necessidade de haver CRUD no lado do cliente pois o cliente só poderá consultar as informações.

Delete os seguintes Models: ./models/Category.php, ./models/CategorySearch.php, ./models/Product.php, ./models/ProductImage.php e ./models/ProductSearch.php.

Delete os seguintes Controllers: ./controllers/ProductController.php.

Delete os seguinte Views: ./views/Category e ./views/Product.

Com isso limpamos o nosso frontend e agora vamos focar no admin.

Customizando o CRUD Category

Aqui vem mais uma parte empolgante do Yii, customização dos componentes das views. Fazer as chamadas das FKs (chaves estragarias) e outras coisas.

Vamos começar com o CRUD Categoty. Vamos cuidar do nosso Insert (Create). Pelo menu acesse Tools -> Add category.

Form gerado pelo Gii

Faça alguns testes. Tente salvar sem digitar nada e tente colocar uma data. Vai receber mensagens de erro como a imagem abaixo.

Veja que que foram exibidos os erros e na data foi requerido um inteiro.

Isso ocorreu porque nosso model já vem com esses tratamentos por default, vale lembrar que isso só ocorreu porque definimos isso na tabela pela nossa migration.

Abra o arquivo ./modules/admin/models/Category.php, esse arquivo estende o yii\db\ActiveRecord que é responsável pelo trabalho de fazer as interações com o Banco.

Basicamente esse arquivo vem com alguns métodos que são responsáveis pela validação dos campos, labels, nome da tabela e relacionamentos.

Explicando alguns métodos:

  • rules(): Pega o que foi definido na tabela e gera as validações como por exemplo campo obrigatório, campo unique, integer, etc. Para mais informações sobre validação veja na doc: http://www.yiiframework.com/doc-2.0/yii-validators-validator.html;
  • attributeLabels(): Gera os ‘títulos’ exibidos acima dos campos no formulário;
  • getProducts(): Esse é responsável pelo relacionamento. Nesse caso é um relacionamento do tipo hasMany (1 para Muitos) com a tabela Product.

Agora vamos melhorar esse formulário e deixar somente os campos que interessa e deixar o campo status mais amigável. Veja a imagem a baixo.

Só precisamos disso nesse formulário. Veja as modificações feitas no código abaixo.

Modificando o model Category: ./modules/admin/models/Category.php

Em ./modules/admin/models/Category.php adicionei dois novos métodos e algumas constantes.

  • behaviors(): Esse método foi criado para que ele preencha automaticamente os campos created_at e updated_at e para isso ele precisa da classe yii\behaviors\TimestampBehavior.
  • getStatusItems(): Faz uso das constantes adicionadas para criar os RadioButtons (RadioList) no campo status lá no formulário.

Modificando Model CategorySearch: ./modules/admin/models/CategorySearch.php

  • Em ./modules/admin/models/CategorySearch.php movi os atributos created_at e updated_at para a área safe do método rules();
  • Alterei a quantidade máximas de registros por página (paginação) na GridView();
  • Fiz tratamento nos atributos created_at e updated_at, transformando de Timestamp para o tipo date possibilitando a pesquisa funcionar na GridView().

Vamos fazer algumas modificações no nosso arquivo de listagem (index.php) para que ele fique mais apresentável e funcione corretamente. Pelo menu do admin acesse Tools -> List category.

Adicionei um registro qualquer só para mostrar a tela padrão.

Repare que as colunas Status, Created At e Updated At estão simplesmente mostrando valores crus. Iremos customizar essa tela para que o campo Status venha com a informação Ativo ou Desativo, que as colunas Created At e Updated At venham formatados como uma data. Para isso precisamos mudar o arquivo ./modules/admin/views/category/index.php.

Widget GridView::widget()

Esse widgets é responsável pela criação da GridView no index. Como explicado no primeiro post, o Yii trabalha com widgets, esses widgets fazem o trabalho na maioria das vezes muito mais prático, pois não tem que ficar alterando um mundo de HTML e PHP. Basta adicionar, excluir e/ou alterar alguma diretriz e pronto, a modificação é feita.

Arquivo original criado pelo Gii
  1. Pjax::begin() / Pjax::end(): Inicia e finaliza o bloco onde o AJAX será utilizado;
  2. 'dataProvider' => $dataProvider: Como o nome já sugere, fornece as informações do model (Category);
  3. 'filterModel' => $searchModel: Caso o SerachModel seja criado no CRUD, essa linha é adicionada e é ela que é responsável pelos campos de filtro acima da grid. E é o SerachModel que tem as consultas (SQL) que fazem esses filtros funcionarem;
  4. 'columns' => []: Todas as colunas da grid é controlada por esse parâmetro da GridView. Logo para exibir, remover ou alterar algum campo da grid deverá ser feito aqui.

Detalhando o atributo Columns da GridView:

  1. O primeiro item desse campo é o [’class' => 'yii\grid\SerialColumn’] que nada mais é que a primeira coluna da grid que simplesmente é um número serial e que nada tem a ver com o id registrado. Faça um teste, remova essa coluna e atualize a view e perceberá que a primeira coluna desapareceu. (Deixo a seu critério remover ou utilizar essa coluna).
  2. 'id’, 'name’, 'status’, 'created_at’, 'updated_at’: são os campos da tabela, esses você pode optar qual quer exibir ou não e tb alterar a ordem de exibição. Remova algum e atualize a view para ver como fica. Volte com a coluna removida.
  3. [’class' => 'yii\grid\ActionColumn’]: Como o nome sugere é a coluna que controla as ações da grid como por exemplo os ícones de Excluir, Editar e Visualizar.

Mesmo sendo um widget tudo aí pode ser customizado como por exemplo: as larguras das colunas usando o CSS, ordem de exibição, cores dos ícones da ActionColumn até mesmo os filtros podem ser customizados.

Aqui precisamos de umas formatações personalizadas

Vamos criar um arquivo chamado /components/formatter/BrazilianFormatter.php e vamos criar o código abaixo.

Iremos usar esse script para sobrescrever o Formatter padrão do Yii e adicionar “formatações” novas. Repare que na criação da classe fazendo uso da classe Formatter que está sendo estendida pela nossa classe. Precisamos dizer ao Yii para utilizar essa classe no projeto. Veja Abaixo.

Edit o arquivo . /config/web.php e adicione a nova classe no índice class conforme o código abaixo.

...’components’ => [
‘request’ => [
‘cookieValidationKey’ => ‘LIvbC6NRcUZBbv-kaaQBCCEBTOmt5uCc’,
],
‘formatter’ => [
‘class’ => ‘app\components\formatters\BrazilianFormatter’,
‘dateFormat’ => ‘php:d/m/Y’,
‘datetimeFormat’ => ‘php:d/m/Y H:i:s’,
‘timeFormat’ => ‘php:H:i:s’,
‘decimalSeparator’ => ‘,’,
‘thousandSeparator’ => ‘.’,
‘currencyCode’ => ‘R$ ‘,
],
...

Veja que no índice class está o nosso componente BrazilianFormater.

NOTA: A vantagem de ter criado esse arquivo é de nos poupar muito trabalho no futuro. Levando em consideração que em um projeto maior a possibilidade de ter que se usar as mesmas coisas em várias telas e widgets diferentes faz em pensarmos em soluções reaproveitáveis. Essa é uma ótima maneira de se fazer isso.

Editando o GridView::Widget() de categorias

Ficou bem melhor. Não foi?

Alterações feitas:

  1. Customização das larguras das colunas e posicionamento do texto;
  2. No campo status agora são exibidos os textos Ativo ou Inativo em vez de 1 ou 0;
  3. Nos campos Created At e Updated At agora exibe uma data no padrão brasileiro (lembra do arquivo ./config/web.php que configuramos o formatter?);
  4. Na coluna Actions modifiquei a cor do ícone de excluir para vermelho e também modifiquei a mensagem padrão.

Calma ainda precisa de mais uma coisinha. Se tentar executar isso exibirá um erro porque provavelmente yii\jui\DatePicker não está instalada.

Antes precisamos verificar se o plugin yiisoft/yii2-juiestá em ./vendor/yiisoft/yii2-jui se não tiver vai precisar instalar um componente do Yii o JUI Extension for Yii 2, que cuida da parte de UX (User Experience) pelo composer: php composer.phar require --prefer-dist yiisoft/yii2-jui. No nosso caso usamos o componente DatePicker do jQuery.

NOTA: Outro ponto a observar é que desde a versão ~2.0.13 do Yii não precisamos do (maldito) pacote asset-plugin que foi instalado no inicio desse projeto. Caso tenha instalado esse pacote recomendo desinstalar o Composer e remover todas os diretórios composer e/ou .composer. Após isso reinstalar o Composer novamente.

Mais uma modificação precisa ser feita em nosso arquivo ./config/web.php.

Adicione em qualquer lugar dentro do parâmetro $config=[]:

Adicione somente o índece aliases no array.

Com isso seu DatePiker vai funcionar nesse projeto.

OBS: Para projetos criados sem a dependência do pacote asset-plugin só precisará instalar o JUI Extension for Yii 2 como descrito acima.

Editando o arquivo view.php

Esse arquivo é responsável por exibir a tela de detalhe do item cadastrado (no nosso caso Categoria). Ele utiliza o widget DetailView::widget(), que assim como GridView::widget() também é customizável.

View original, gerado pelo Gii.

Ele é acessado de duas formas. Pelo ícone “olho” na coluna Actions do index.php, ou após efetuar um cadastro pelo botão Create Category.

Abra o arquivo /modules/admin/views/category/views.php, e vamos fazer algumas modificações. Segue abaixo o arquivo alterado.

Modificações feitas:

  • Adição do texto com tradução “Category :”;
  • Criação do botão Novo, permitindo realizar um novo cadastro.

Modificações feitas no DetailView::widget()

  • Adição do parâmetro ‘template’ => ‘’, que serviu para definir o tamanho na primeira coluna;
  • Em status, utilizamos o método status (asStatus()) do componente que criamos chamado BrazilianFormatter;
  • Em Created At e Updated At aplicamos o formatter date (padrão do Yii) que faz a formatação no padrão dd/mm/yyyy.
View formatada. Repare os itens modificados que foram citados e compare as duas telas.

Mais uma etapa concluída do projeto. Acompanhe o projeto e vejas os arquivos no GitHub: https://github.com/Calcio/vitrine

Agradecimentos especiais ao GFrancisquini, Raphael Barbosa, Railton Nepomuceno e Kilderson Sena do grupo do telegram Yii Brasil, por me ajudarem com algumas problemas que tive enquanto criava esse post.

Espero que tenham gostado desse post. Vou dividir essas customizações em outros posts para não ficar muito cansativo.

--

--