Eu sou da opinião que todo bom desenvolvedor frontend tem que ter pelo menos uma noção de backend, e o contrário também tem que acontecer, é comum as pessoas virem me perguntar como que faz pra fazer o Fancybox funcionar no CakePHP, ou como que eu integro um plugin para Jquery no site, puxa, a maioria das vezes é adicionar um seletor, chamar o javascript no Html e configurar de acordo com a documentação, vamos ver se simplifico pra vocês.
A ideia é criar uma galeria de imagens com painel de administração e separada por álbuns. Iremos instalar também o DebugKit pra medir o uso de memória do CakePHP e saber se a nossa aplicação está pesada ou não.
Para quem o CakePHP é interessante?
O CakePHP é interessante para devs backend que precisam ganhar tempo ao desenvolver ou querem entender como funciona o esquema de MVC.
Também é interessante para os devs frontend que precisam automatizar algumas tarefas, entender como é o mundo do backend e até ganhar tempo com o sistema de temas, layouts e view do CakePHP (camada V).
O que vamos usar?
Vamos precisar de:
- Uma cópia do CakePHP (https://cakephp.org/, a direita tem uma palavra grande escrito Download com o link para a versão estável mais recente.)
- Uma cópia do Fancybox (https://fancyapps.com/fancybox/#license, botãozinho azul!)
- O DebugKit (https://github.com/cakephp/debug_kit, na lateral direita tem um link chamado “Download ZIP”)
- O WideImage (https://wideimage.sourceforge.net/download/, aonde está escrito “download it”, baixe só o lib (terceiro da lista))
- Um desenvolvedor web
- Água
- Pó de café
- Uma cafeteira
Modo de preparo
Primeiro você pega a água, o pó de café e a cafeteira pra fazer um café esperto e acompanhar este tutorial.
Preparando o ambiente!
- Em seguida, descompacte o CakePHP no seu servidor local (eu uso o Xampp: https://www.apachefriends.org/pt_br/index.html) para facilitar aqui.
- Descompacte o DebugKit na pasta app/Plugin do CakePHP e renomeie o diretório debug_kit-master para DebugKit
- O FancyBox vai em app/webroot, mas apenas a pasta source, e renomeie para fancy.
- O WideImage pode ir em app/Vendor/wideimage e dentro os arquivos dele de forma que o WideImage.php fique disponível em app/Vendor/wideimage/WideImage.php
Agora que temos todos os arquivos, vamos ativar o DebugKit pra poder ter as métricas de uso de memória, execução dos SQLs e outros dados.
- Abra o arquivo app/Config/bootstrap.php e cole o código abaixo (cod.1) na linha 72
- Após isso abra o AppController.php (em app/Controller) e cole o bloco cod.2 na linha 35, entre as chaves ({}) da classe AppController.
Cod.1::
Cod.2::
Se acessar sua aplicação agora vai ver que temos um pequeno botão no canto superior direito, ao clicar nele você já tem acesso aos dados da sua aplicação, em timer você vê o uso de memória.
Pra fechar, acesse o core.php em app/Config, procure e descomente a linha a seguir (aqui era a 152) removendo as barras do começo (//)
Preparando a estrutura
Pra começar vamos precisar de um banco de dados (vamos usar o MySql), execute o código abaixo (se quiser, use algo como PHPMyAdmin para ajudar) pra criar as tabelas:
Cod.3:
Preencha as linhas que comentei (host, login, password e database), com isso já temos o banco de dados também conectado, para verificar, acesse a aplicação no navegador e verifique a última mensagem dos blocos coloridos.
Para finalizar esta etapa de preparação, vamos criar os arquivos da galeria:
Em app/Model crie Albun.php e Imagen.php (e sim, com n, já que o CakePHP trabalha com singular e plural em inglês, até da pra mudar isso, mas o artigo já vai ficar enorme).
Em app/Controller crie AlbunsController.php e ImagensController.php
Em app/View crie 2 pastas (Albuns e Imagens) com 3 arquivos dentro de cada:
- admin_novo.ctp
- admin_editar.ctp
- admin_index.ctp
E apenas na pasta Albuns, crie mais 2 arquivos além dos dois que devem estar dentro dela e da Imagens:
- ver.ctp
- index.ctp
A partir deste ponto é interessante que você conheça um pouco sobre MVC. Aqui vai uma dica: escrevi sobre isso aqui. Não precisa fazer o exemplo todo, apenas entender como é.
Relacionando as imagens com os albuns
Em primeiro lugar precisamos entender como as imagens se relacionam com cada álbum, a própria documentação do CakePHP já fala sobre isso (https://book.cakephp.org/2.0/en/models/associations-linking-models-together.html), infelizmente está em inglês, vou eu mesmo mostrar como é.
Temos 4 tipos possíveis de relacionamento entre tabelas.
Um para um – hasOne
Um para muitos – hasMany
Muitos para um – belongTo
Muitos para muitos – hasAndBelongsToMany ou HABTM
Se você ler com calma já vai ver que é fácil de definir relacionamentos, no nosso caso imagens tem um álbum ou Muitos para Um, indo ao contrário, álbum te muitas imagens ou Um para Muitos, logo:
Album hasMany Imagem
Imagems belongsTo Album
Entendeu a lógica por traz de definir os relacionamentos? Então vamos informar isso nos models.
Abra os arquivos Album.php e Imagem.php que estão em app/Model e vamos configurar:
Cod. 5:
Pronto, com isso sempre que buscarmos algo no banco de dados ele já vai incluir automaticamente os dados relacionados, ou seja, se eu listar o álbum, ele vai trazer todas as imagens deste determinado álbum e o contrário também vai acontecer (dizer a qual álbum a imagem pertence).
Criando os controllers
Os controllers vão decidir o que será feito na aplicação, ou seja, exibir o que? Pegar que infromação no banco? Que hora o upload deve ser feito? É muito simples, os dois arquivos devem ser salvos em app/Controller:
Cod. 6:
Configurando a criação de álbuns de imagens na administração
No controller álbuns (AlbunsController.php) crie uma função chamada admin_novo, assim:
Cod. 7:
Este action (o nome dado as functions de cada página nos controllers do CakePHP) vai testar se o carregamento da página foi um post, se sim, ele informa que estamos criando um registro, tenta salvar o registro e envia para a index caso tenha sucesso, com uma mensagem de “Album criado”, caso contrário, apenas informa que algo deu errado.
A view desta action, ou o cara que vai exibir os dados na tela do usuário fica assim (arquivo app/View/Albuns/admin_novo.ctp):
Cod. 7A:
Configurando a edição de álbuns de imagens na administração
Muito parecido com add, mas dessa vez checando se o álbum especificado existe antes de salvar.
Cod. 8:
E a view (app/View/Albuns/admin_editar.ctp)
Cod. 8A:
Configurando a remoção de álbuns de imagens na administração
Também preciso remover o álbum quando não precisar mais dele. Temos uma action que pode cuidar disso, é bem parecido com a admin_editar, mas desta vez ele usa delete em vez de save:
Cod. 9:
Este action redireciona para index, então ele não tem uma view.
Configurando a listagem de álbuns de imagens na administração
E pra fechar a administração de álbuns, a listagem de álbuns com paginação:
Cod. 10:
O recursive -1 impede que o álbum traga os dados relacionados que no nosso caso são as imagens, a segunda linha traz os álbuns salvos no banco com paginação (página 1, página 2…).
Não esqueça de ativar o componente paginator no seu controller acrescentando a variável $components no inicio da classe AlbunsController (logo abaixo tem um exemplo na classe imagens)
Cod. 11:
E a view (app/View/Albuns/admin_index.ctp):
Cod. 10A:
Configurando a administração de imagens
A administração de imagens é bem parecida com a de álbuns, vou apenas passar o código pra gente não se estender muito, mas está bem simples de entender.
Primeiro o controller ImagensController.php
Cod. 12:
E as views:
Cod. 12A:
Configurando o upload e tratamento de imagens
Note nas actions admin_novo e admin_editar do ImagensController que você tem uma linha assim:
Ela carrega uma função do model Imagen.php chamada upload que cuida de salvar os dados do arquivo enviado ($this->request->data[‘Imagen’][‘url’]) e também criar uma pasta com o id do álbum atual ($this->request->data[‘Imagen’][‘albun_id’]) no diretório app/webroot/img, mas o que ela faz ao certo?
- Primeiro vamos verificar se o arquivo enviado tem o tipo certo (jpeg, gif, png…)
- Em seguida verificamos se deu tudo certo durante o upload
- Caso tenha, checo se o diretório aonde as imagens vão fica existe (será em app/webroot/img/album/{id do álbum}), se não existir eu crio
- Então parto pra etapa de conversão de nome, transformando em um formato aceito na web, mas sem perder o nome de arquivo que o usuário tinha antes
- E uso o WideImage pra ajustar a imagem para um tamanho aproximado de 800x600px e criar uma miniatura de 250x250px exatos (cortando o excesso a partir de centro da imagem)
O código completo vai no app/Model/Imagen.php, logo a baixo da linha da variável $belongsTo:
Cod. 13:
Listando os álbuns
Bem, nossa aplicação já está salvando a imagem, já cria álbuns e associa um ao outro, mas ainda não mostra o resultado final, vamos configurar isso.
Primeiro precisamos de uma listagem de álbuns com uma miniatura e um titulo para o usuário escolher o que quer ver.
Vou configurar para que a miniatura seja a primeira imagem do álbum, vamos ao controller (app/Controller/AlbunsController.php):
Cod. 14:
Você viu que eu usei o contain ali dentro do array, isso é um behavior e ele precisa ser chamado no Model pra funcionar, para isso vá ao model Albun.php e acrescente a variável antes ou depois da var $hasMany:
Cod. 14A:
A view é a app/Albuns/index.ctp.
Cod. 14B:
Listando as imagens de cada álbum
E pra fechar nossa galeria faltou apenas criarmos a exibição da galeria em si, para isso devemos trazer o nosso álbum e o CakePHP já vai trazer os dados relacionados a ele (que no nosso caso são as imagens):
Cod. 15:
A view ver.ctp(não vou falar o caminho desta vez, deve ter ficado claro pra você) de álbuns vai exibir o html já formatado para eu usar o Fancybox, ou seja, imagem dentro de um link.
Cod. 15A:
Integrando ao FancyBox
O Fancybox é um plugin para frontend, então o processo é o mesmo que em qualquer outro lugar, basta criar o HTML da galeria no formato que ele usa (fizemos isso no passo anterior) e chamar os javascripts, css e configurar o plugin.
Ainda na view ver.ctp de Albuns, faça isso logo no final:
Cod. 16:
O primeiro bloco (Html->script) chama os javascripts (o jquery do server do Google e o jquery.fancybox.pack.js que está no diretório webroot).
O segundo bloco (Html->css) faz o mesmo com o css local.
E o terceiro cria um bloco … configurando o Fancybox, note que eu coloquei tudo com inline=>false assim ele não imprime isso na view e sim nas tags script e css que estão no nosso arquivo app/View/Layout/default.ctp (já vem no CakePHP) pra evitar a bagunça (como se o javacript direto na página fosse muito organizado, mas deu pra entender bem como proceder).
Como usar?
Fácil, você tem três urls base:
/albuns – listagem de álbuns
/admin/abuns – administração de álbuns
/admin/imagens – administração de imagens
Além disso você ainda pode usar estas urls, mas a navegação da galeria já vai te guia por elas:
/admin/novo
/admin/albuns/editar/{id do album}
/admin/albuns/remover/{id do álbum}
/admin/novo
/admin/imagens/editar/{id da imagem}
/admin/imagens/remover/{id da imagem}
/albuns/ver/{id do album}
Perceba que cada action gerou uma url e que o admin_ gerou um /admin em cada action, além dos ids e os controllers, no fim você entende que as urls seguem o padrão
/:prefixo/:controller/:action – lembrando que o prefixo é o admin
Ou
/:controller/:action
Ou
/:controller – e action passada é a index por padrão quando uma não for especificada.
Isso ainda pode ser personalizado, mas é outro assunto.
Conclusão
Note que esta é uma tarefa normalmente dispendiosa, é uma administração completa de galeria de imagens que embora simples é bem completa e eu consegui resumir tudo em poucas linhas de código e um artigo apenas.
Você ainda precisa proteger a administração da sua aplicação com senha, adicionar um controle de imagens melhor, checar se o arquivo existe e alterar o nome para não substituir, apagar a imagem quando o dado for apagado do banco (tanto o álbum quanto as imagens), remover a imagem antiga quando troca no admin_editar, setar imagem de capa do álbum… enfim, mas agora você tem um norte pra começar a trabalhar.
Aqui o arquivo pronto para download (o sql do banco está em app/Config/Schema/database.sql): https://blog.erikfigueiredo.com.br/galeria.zip
Obrigado a todos.