Laravel

Laravel 8 e 9, o maior framework PHP
Voltar
Acesse no Github
Laravel 9: Novidades

Maior framework PHP do mundo, usando como princípio MVC. Possui motor administrado pelo Composer, automatização com PHP artisan e BD (PDO), views padronizadas Blade e estilização Bootstrap, estruturação Hash de segurança, entre outros recursos tecnológicos. Possui, além disso, o maior ecossistema de extensões, atendendo à todo tipo de necessidade de software moderno.


Instalação

  1. Baixar e iniciar XAMPP: Tutorial
  2. Baixar dependências e vinculá-las ao XAMPP
    • sudo apt install curl composer nodejs npm
    • sudo curl -s https://getcomposer.org/installer | /opt/lampp/bin/php
    • sudo mv composer.phar /usr/local/bin/composer
    • sudo ln -s /opt/lampp/bin/php /usr/local/bin/php
  3. (Diretório que desejar) Criar projeto Laravel: composer create-project --prefer-dist laravel/laravel nomeProjeto

Funcionamento

  1. User dispara ação no Browser para determinada URL
  2. Ação será capturada pelo routes 'web.php', no diretório Routes, que será roteado a um controller
  3. Controller conversa com Model, que conversa com BD (PDO)
  4. Feeback do BD (falha/sucesso) volta ao Model, esse repassa ao Controller
  5. Controller chama View dinâmica (Blade), que enviará o resultado via Browser (HTML) para User

NA PRÁTICA
(Atente-se com os 'use' e 'namespace', para checar se os mesmos encontram-se e correspondem à árvore de diretórios)

  1. Criar route no 'web.php', comentá-la para criar o Controller
  2. Criar controller, com artisan, e criar metodo que será lido na route
  3. Testar, informando uri, se o método do controller e route funcionam
  4. Criar view com Html
  5. No controller, criar o metodo de return view, com parâmetros var visão e var controller
  6. Na view, informar as vars dinâmicas {{$user->name}} do informadas como parâmetros do método no controller

Diretórios

  • Index: Pasta public estão arquivos visualizáveis aos usuários (que serão vinculados à url)
  • Models: Pasta app/models encontram-se as models(user.php model padrão de usuários)
  • Controllers: Pasta app/http/controllers
  • Views: Pasta resources/views (ex welcome.blade.php view padrão index Laravel)
  • Routes: Pasta routes (web.php possui as rotas do Browser, api.php de APIs...)
  • .env: Arquivo de configurações do Laravel (DBs, Drivers...)
  • Vendor: Pasta vendor possui dependências do Laravel (não mexer)
  • Migrations: Pasta database/migrations possui migrations(códigos php gestores BD)
  • Public: Diretórios Web Accessible, acessados por todos
  • package.json: Arquivo de dependências do projeto
  • webpack.mix.js: Se existir, arquivo de vinculação e mimificação de arquivos ao Public
  • Storage: Pasta onde são salvos arquivos
  • filesystems.php: Arquivo, na pasta Config, de configurações de diretórios do Laravel

Comandos automatizadores

(Ordem de criação: Migrations(se ñ mcr) -> Model mcr -> PopularMigrations -> Controller(se ñ mcr) -> Fresh)
  • Migrations em Paralelo:
    • Criar migration: php artisan make:migration comando_nomeTable_table --create=nomeTable(create opcional)
    • Add campo à migration: php artisan make:migration comando_nomeTable_table --table=nomeTable
    • Executar migrations pendentes: php artisan migrate
    • Desfazer migration: php artisan migrate:rollback --step=2(step opcional)
    • Resetar BD conforme migrations: php artisan migrate:fresh
  • Model e Controller limpo:
    • Criar model: php artisan make:model nomeModel -mcr(mcr Migration/Controller opcional)
  • Model e Controller CRUD:
    • Criar controller: php artisan make:controller pasta\nomeController --resource --model=nomeModel(--resource e model opcionais)
  • Outros:
    • Listar routes: php artisan route::list
    • Instalar dependências: npm install nomeDependencia
    • Executar modificações com dependências/mimificaçõesMix: npm run dev(produtcion)
    • Manter execução de dependências: npm run watch
    • Criar objeto(Mail): php artisan make:mail newLaravelTips
    • Importar templates markdown(Email): php artisan vendor:publish --tag=laravel-mail
    • Inserir estrutura BD queues: php artisan queue:table
    • Executar jobs queues: php artisan queue:work
    • Criar classes/objetos jobs: php artisan make:job nomeClasse


Projetos



Anotações


Iniciar projeto Laravel
1.Instalação do projeto 2.Configuração BD no '.env' 3.Criar model, migration e controller simples(php artisan make:model nomeModel -mcr) 4.Parametrizar migration, então model 5.Resetar BD e executar migrations(php artisan migrate:fresh) 6.Definir route 7.Programar método(s) do controller vinculado à route 8.Criar e programar view, com Html dinâmico, vinculada ao método do controller 9.Testar acesso com Browser
3.Automatizar com artisan e resource
1.Criar controller com metodos: php artisan make:controller Form\TestController --resource --model=User (--resource cria todos os métodos do controller automaticamente) (--model=User criará automaticamente parâmetros relacionados à model User) 2.Criar view automatizada com métodos CRUD //Criador de rotas padrões para o controller (get,post,put/patch,delete), altera o nome da route de 'usuario' para 'user', e altera os parâmetros de uri 'usuarios' para 'user' Route::resource('usuarios',TestController::class)->names('user')->parameters(['usuarios'=>'user']); 3.Alterar nome de trechos da uri para personalizados('original'=>'personalizado') //Providers > AppServiceProvider.php, método boot() use Illuminate\Support\Facades\Route; public function boot() { Route::resourceVerbs([ 'create'=>'novo', 'edit'=>'editar' ]); }
4.Versionar BD com Migrations
Comandos de gestão de BD de dentro do Laravel Up: Comando de envio ao BD (Ex: Create table) Down: Contrário de Up, comando de retorno/desfazer ao BD (Ex: Drop table) 1.Criar Migration (create table): php artisan make:migration comando_nomeTable_table(ex: create_users_table) --create=nomeTable 2.Adicionar novo campo à table existente (Alter Table): php artisan make:migration comando_nomeTable_table --table=nomeTable 3.Criar BD: php artisan migrate (executa todos os arquivos de migrate criados pendentes) Desfazer criação no BD: php artisan migrate:rollback (desfaz todas as alterações no BD) php artisan migrate:rollback --step=2 (No caso, desfazer os últimos 2 passos)
5.Criar regra de negócio e configurar Model, manual e automatizado
Para criar Model, primeiro precisa de uma table do mesmo no BD sobre a mesma, criando nova Migration 1.Resetar BD com projeto: php artisan migrate:fresh 2.Criar Migration: php artisan make:migration create_posts_table 3.Após codificar Migration, atualizar BD: php artisan migrate 4.Criar Controller: php artisan make:controller PostController 4.1.Modificar o método welcome em routes 'web.php', com o controller PostController, com método de execução 'showForm' 5.Criar método 'showForm' no PostController, em branco 6.Criar view de return do 'showForm', chamada 'form.blade.php', e populá-la com Html básico e @csrf 7.Criar nova route em 'web.php', do tipo post, com nome e método chamados 'debug' 8.No Controller 'PostController', criar método debug só com o inicial, e concluir o 'showForm' 9.Inserir action como {{route}} na view 'form.blade.php' 10.Popular método 'debug' no controller PostController 11.Testar submissão do formulário Hmtl com 'dd($request->al());' Para inserir os dados do form Html no BD, precisa-se criar a respectiva Model antes. 12.Criar Model 'Post': php artisan make:model Post 12.1.Popular Model 'Post' Laravel converte tudo para minúsculo e plural ao BD, ou seja, a table relacionada precisa ser 'posts' 13.Informar somente dados relacionados com BD no Controller 'PostController', no método 'debug'(remover o _token...) 13.1.Informar dados que serão enviados ao Model 'Post' para que possa serem persistidos ao BD(informar no método 'debug' do 'PostController') Da forma acima ocorrerá erro, pois o slug precisa ser não null. Para contornar isso, segue: 14.Na Model 'Post', informar e popular o método setPropriedadeAttribute($valorPassadoAtributo) (ex setTitleAttribute($value)) Com isso, automaticamente ao informar o title, ele informará o mesmo como slug, já formatado no formato url, gerados pelo método Str, já informado 15.Testar, no formulário Html, a inserção de valores no BD AUTOMATIZADO 1.Criar Model, com Migration e Controller: php artisan make:model nomeModel -mcr 2.Preencher campos na migration, de acordo com a respectiva table no DB 3.Informar atributos na Model 4.Informar as routes 'web.php' e programar os métodos no Controller
6.Relacionamentos entre Models
1.Criar Models, com Controllers e Migrations: php artisan make:model Address -mcr php artisan make:model Category -mcr php artisan make:model Post -mcr php artisan make:controller UserController --resource 2.Popular Migrations com atributos 3.Resetar BD: php artisan migrate:fresh 4.Inserir dados no BD: INSERT INTO users(name,email,password,created_at,updated_at) VALUES ('ubsocial','ubsocial@gmail',123,now(),now()),('ubsocial2','ubsocial@gmail',456,now(),now()); 5.Adicionar route usuario/{id} para UserController@show em 'web.php' (Informar 'use' também) 6.Popular método show em UserController (informar 'use' tbm), com $user = User::where('id',$id)->first(); dd($user); 7.Testar no Browser: http://localhost/projetos/laravel/projeto6/public/usuario/1 8.Inserir, manualmente, alguns Addressess no BD: INSERT INTO addresses(user,street,number,city,state,created_at,updated_at) VALUES (1,'rua x',33,'cidade','rs',now(),now()); 9.Popular Model Address (Nesse caso, não foram criadas views com forms, foram colocado diretamente via controller - não recomendado) RELACIONAMENTO 1-1 (1User possui 1Address) Parte-se da table de origem da informação(User, pois User possui Address, Address é dependente de User) Para saber de qual Address é determinado User (Caminho de ida) 1.Em Model User, criar método de relacionamento 'address', que retornará o relacionamento com as keys relacionáveis 2.Em UserController, no método show, adicionar método $address 3.Testar: http://localhost/projetos/laravel/projeto6/public/usuario/1 Para saber de qual User é determinado Address (Caminho de volta) 4.Em route 'web.php', inserir route /endereco/{address} //Informar 'use' também 5.Em AddressController, popular metodo show 6.Testar: http://localhost/projetos/laravel/projeto6/public/endereco/1 7.Em Model Address, adicionar método user 8.Em AddressController, no método show, adicionar método $user 9.Testar: http://localhost/projetos/laravel/projeto6/public/endereco/1 RELACIONAMENTO 1-N (1User escreve NPosts) Processo similar ao acima, só muda o nome do método de relacionamento de keys Para saber de quais Posts é determinado User (Caminho de ida) 1.Inserir dados no BD: INSERT INTO posts(author,title,slug,content,created_at,updated_at) VALUES (1,'titulo','titulo','testeContent',now(),now()),(1,'titulo2','titulo2','testeContent2',now(),now()),(2,'titulo3','titulo3','testeContent3',now(),now()); 2.Em Model User, criar método de relacionamento 'posts' 3.Em UserController, no método show, adicionar método $posts 4.Testar: http://localhost/projetos/laravel/projeto6/public/usuario/2 Para saber de qual User são determinados Posts (Caminho de volta) 5.Em Model Post, propriedade $table e método de relacionamento 'author' 6.Em PostController, no método show, echo de volta, somente a linha 7.Em route 'web.php', inserir route /artigo/{post} 8.Testar: http://localhost/projetos/laravel/projeto6/artigo/1 9.Em PostController, método show, informar $user e listagem 10.Testar: http://localhost/projetos/laravel/projeto6/artigo/3 RELACIONAMENTO N-N (NPosts possuem NCategories) Precisa-se de table pivô para fazer a união dos registros (Ex: table posts_categories). 1.Criar Migration php artisan make:migration create_posts_categories_table --create=posts_categories php artisan migrate 2.Popular migrations 3.Inserir dados no BD: INSERT INTO categories(title,description,created_at,updated_at) VALUES ('cat1','descCat1',now(),now()),('cat','descCat2',now(),now()); 4.Inserir dados de relações no BD: INSERT INTO posts_categories(post,category) VALUES (1,1),(1,2),(2,1),(3,2); Quais Posts são determinadas Categories (Ida) 5.Em Model Category, informar $table 6.Em Model Post, informar método de relacionamento categories 7.Em PostController, no método show, informar $categories e listagem 8.Testar: http://localhost/projetos/laravel/projeto6/artigo/3 Quais Categories são determinados Posts (Volta) 9.Em route 'web.php', inserir route /categoria/{category} //Informar 'use' também 10.No CategoryController, no método show, informar Html Categories 11.Testar: http://localhost/projetos/laravel/projeto6/categoria/2 12.Em Model Category, informar método de relacionamento posts 13.No CategoryController, no método show, informar Html de Posts 14.Testar: http://localhost/projetos/laravel/projeto6/categoria/2
7.Login com artisan e hardcode
No Laravel 8, há novas maneiras de autenticação. Elas funcionam por meio do Laravel Jetstream e Fortify, juntamente com serviços de autenticação token API Laravel Livewire e Inertia.js, além de pacotes de autenticação como o Passport Sanctum, ambas libraries baseadas em cookies embutidos no Laravel, onde uma delas deverá ser escolhida para criação do projeto. No entanto, como tudo ainda encontra-se muito novo, instável e pouco padronizado, utilizaremos o meio mais utilizado na versão 6, através do Laravel UI, de uma forma simples com Bootstrap, ao invés do Vue. Isso, além do fato de que desenvolveremos toda a estrutura de login para maior entendimento. Por fim, o processo é bastante similar entre as versões, desde que conheça-se a estrutura e funcionamento da mesma. //Criar projeto Projeto7.8 e, dentro do projeto, instalar dependências: 1.Com Laravel Installer (laravel new nomeProjeto --jet) 2.php artisan migrate 3.Verificar arquivos e inserir código faltando 4.Inserir BD: INSERT INTO user(name,email,password) VALUES ('ubsocial','ubsocial@gmail',123); 5.Resetar BD: php artisan migrate:fresh Instalação Clássica Laravel 6 Authentication: composer require laravel/ui --dev php artisan ui bootstrap --auth npm install && npm run dev (Serão geradas migrations, route, controllers e views específicas para authentication) Testar registro: http://localhost/projetos/laravel/projeto7/public Criar Painel de Administração Manualmente: 1.Em routes 'web.php', adicionar route comentada /admin (Descomentar após feitos respectivos Controller e método envolvidos) 2.Criar controller AuthController: php artisan make:controller AuthController 3.Criar método dashboard no AuthController 4.Criar, em views, diretório admin 5.Em views/admin criar View dashboard 6.Testar: http://localhost/projetos/laravel/projeto7/public/admin 7.Inserir, dentro do método dashboard do AuthController, condição if da facade Auth 8.Em routes 'web.php', adicionar route /admin/login 9.Em AuthController, inserir método showLoginForm 10.Em views/admin, adicionar view formLogin 11.Em AuthController, informar return redirect 12.Testar: http://localhost/projetos/laravel/projeto7/public/admin será redirecionado à /login Validar iserção dos dados e exibir dashboard: 13.Em routes 'web.php', informar route '/admin/login/do' 14.Em AuthController, informar método login com somente dd() 15.Testar formulário no Browser 16.Em AuthController, método login, informar $credentials e Auth::attempt() 17.Testar: http://localhost/projetos/laravel/projeto7/public/admin/login e, após isso voltar para /admin, encontrarei o painel de admin 18.Em AuthController, informar no if dd(Auth::user) Logout: 19.Em routes 'web.php', informar route '/admin/logout' 20.Em AuthController, informar método logout 21.Em view dashboard, informar link com route logouts 22.Testar: http://localhost/projetos/laravel/projeto7/public/admin/login Validar Erros: 23.AuthController, informar if Auth::attempt e return redirect back 24.Em view formLogin, informar @if 25.Testar login incorreto: http://localhost/projetos/laravel/projeto7/public/admin/login Validar email: 26.Em view formLogin, trocar a propriedade email para text no input email 27.AuthController, método login, informar if filter_var $request->email 28.Testar email login incorreto: http://localhost/projetos/laravel/projeto7/public/admin/login
8.Laravel Frontend com Blade
1.Em routes 'web.php' criar routes /cursos e /contato, inserindo name() nas routes, e alterar view 'welcome' para 'site.home' 2.Em views, criar diretório 'site' e, dentro dele, criar view home 3.Acessar site do Bootstrap > Examples > Carousel, acessar código fonte, copiar todo o <body> até o </main>, colar o código na view 'home' e fechar o </body> 4.No Browser, página 'public', recarregar página e testar site Interpolation (Mesclar Php com Html usando o Blade): 5.Em view 'home', alterar, no footer, o ano para Php {{date('Y')}} Diretivas (@if, @foreach, @while...): 6.Em view 'home', inserir if de condição bom dia, boa tarde, boa noite (Aprox linha 47) e foreach modelo 7.Em Config/app.php, alterar timezone para 'America/Sao_Paulo' (UTC é o padrão do Laravel, 3 hrs a mais...) 8.No Browser, página 'public', recarregar página e testar site Exemplo: @foreach() <p>Código aqui</p> @endforeach Criar página de contato: 9.No navbar, criar links de routes para os itens home, cursos e contato (Retirar 'disable' do contato) 10.Criar views, no diretório site, 'contact' e 'courses' Herança (@extends: Layout Filho herda de Layout Master): 11.No diretório 'site', criar diretório 'master' 12.Em 'master', criar view 'layout' (Layout Master). Recortar todo conteúdo da view 'home' na view 'layout' 13.Em view 'home' informar @extends 14.Em view 'layout', informar links de routes nos itens do navbar 15.Em routes 'web.php', alterar routes /cursos e /contato de view 'welcome' para suas respectivas views 16.Em view 'layout' recortar conteúdo de <main> até </main> (Mas manter o footer, tag main deve ser mantida) 17.Dentro da tag main informar @yield('content') 18.View 'home', informar @section('content'), colar conteúdo recortado de layout abaixo da section, após informar @endsection 19.Testar, no Browser, página home 20.View 'contact', informar @section('content') e @endsection e conteúdo interno à ela 21.Testar, no Browser, página contact 22.View 'courses', informar @section('content') e @endsection e conteúdo interno à ela 23.Testar, no Browser, página courses Menu itens ativos/selecionados: 24.View 'layout', em nav-item do navbar, informar condição ternária {{Route...}}
9.Gerenciar assets com Laravel Mix
Laravel Mix: Ferramenta do ecossistema Laravel para gestão de webpacks Codificação diretório site: 1.Diretório 'views', criar novo diretório 'site', criando dentro desse uma view 'home' 2.Diretório 'site', criar novos diretórios 'css' e 'js' 3.Diretório 'css', criar arquivo 'style.css' 4.Diretório 'js', criar arquivo 'script.js' Instalar dependências de acesso à arquivos que não estão no diretório public: npm install (Instalará dependências presentes no arquivo package.json. Criará diretório 'node_modules', com dependências js) Parametrizar arquivos css que serão vinculados ao diretório 'public': 1.Arquivo 'webpack.mix.js', comentar entradas e informar mix styles 2.npm run dev (Atualizar arquivos com mix, gera arquivo de destino no diretório 'public') 3.Em 'views/site/css/style.css', inserir estilos para * (Sempre alterar arquivos no 'resources', os de 'public' serão gerados automaticamente à partir destes) 4.Atualizar arquivos mix: npm run dev Inserir novo arquivo de css para parametrizar: 5.Em views/site/css criar novo arquivo 'reset.css', recortar conteúdo do 'style.css' e colar no 'reset.css' 6.Em views/site/css/style.css, informar estilos de h1 7.Em 'webpack.mix.js' informar, no caminho de origem, arquivo 'reset.css' 8.Atualizar arquivos mix: npm run dev Vincular arquivos css com view home: 9.View 'home', informar <link> com asset, que linkará arquivos no diretório 'public' 10.Em routes 'web.php', alterar route '/' 11.Testar: http://localhost/projetos/laravel/projeto9/public Otimizar chamada de arquivos origem/destino, para melhor compatibilidade com futuras versões css e js: 12.Em 'webpack.mix.js', informar .version() no mix.styles 13.Atualizar arquivos mix: npm run produtcion (Gerará, em public, arquivo 'mix-manifest.json', com link Hash de versão do css e js) 14.Linkar Hash na view home: View 'home', alterar link asset por url(mix) Parametrizar arquivos js que serão vinculados ao diretório 'public': 15.Em 'views/site/js/script.js' popular arquivo com alert 16.Em 'webpack.mix.js', criar mix.scripts e informar caminhos 17.Atualizar arquivos mix: npm run produtcion Vincular arquivos js com view site home: 18.View 'site.home', informar <script> com url(mix) 19.Testar: http://localhost/projetos/laravel/projeto9/public Automatizar atualização dos arquivos mix: npm run watch (Lê arquivos e assiste-os. Qualquer modificação nos arquivos, o npm fará a atualização automaticamente) 20.Em views/site/css/style.css, alterar tamanho de fonte 21.Testar: http://localhost/projetos/laravel/projeto9/public Codificação diretório admin: 22.Em diretório views, criar novo diretório 'admin' 23.Diretório admin, criar novos diretórios 'css' e 'js' 24.Diretório admin, criar view 'home' 25.Em routes 'web.php', criar route '/admin' 26.Testar: http://localhost/projetos/laravel/projeto9/public/admin Criar css do admin: 27.Em 'views/admin/css' criar arquivo 'style.css' 28.Em 'views/admin/js' criar arquivo 'script.js' Vincular arquivos com diretório public: 29.Em 'webpack.mix.js', acrescentar novos mix.styles() e mix.scripts() 30.Matar processo de watch: ctrl+c no terminal 31.Rodar watch novamente para sincronizar: npm run watch Vincular css e js com view admin home: 32.View 'admin.home', informar <link css> e <script> com url(mix) 33.Testar: http://localhost/projetos/laravel/projeto9/public/admin (Proibirá acesso: Conflito entre routes e diretórios - caminho da route e diretório com mesmo nome) (Resolver alterando o caminho da route, ou nome do diretório) 34.Mudar nome do caminho da route '/admin' para '/painel' 35.Testar: http://localhost/projetos/laravel/projeto9/public/painel
10.Bootstrap local no Laravel
1.Criar view 'home' 2.Em routes 'web.php', alterar route 'welcome' para 'home' Instar dependências: 3.Instalar, no diretório do projeto, jQuery via terminal usando npm: npm install jquery (Diretório node_modules será criado com dependências js) Vincular jQuery com o public do projeto: 4.Arquivo 'webpack.mix.js', apagar/comentar mix padrão e criar novo mix.scripts 5.Vincular com public: npm run dev Implementar jquery dentro da view 'home': 6.View 'home', informar <script> com asset 7.Instalar Bootstrap no projeto: npm install bootstrap (Diretório bootstrap será criado em node_modules) 8.Arquivo 'webpack.mix.js', criar mix.scripts do bootstrap 9.Vincular com public: npm run dev 10.Arquivo 'webpack.mix.js', criar mix.sass do bootstrap acima do mix.scripts (Poderia-se vincular somente os arquivos .css no dist do Bootstrap para usar o framework comum, mas não poderia-se criar estilos próprios) 11.Vincular com public: npm run dev Implementar bootstrap dentro da view 'home': 12.View 'home', informar <script> do Bootstrap, e <link css> do Bootstrap (Acima dos <script>) e conteúdo Html de teste 13.Testar, no Browser: http://localhost/projetos/laravel/projeto10/public/ Alterar propriedades do Bootstrap (Personalização): 14.Diretório 'views', criar novo diretório 'scss' e, dentro desse, criar arquivo 'style.scss' 15.Em 'webpack.mix.js', recortar caminho de origem do mix.sass, e colar dentro de um @import do style.scss 16.Em 'webpack.mix.js', em mix.sass, informar novo caminho de origem com relação ao arquivo style.scss em views. Modificar nome do arquivo de saída de bootstrap para style.css 17.Vincular com public: npm run dev (Apagar arquivo antigo public/site/bootstrap.css) Atualizar vinculação com view 'home': 18.Em view 'home', alterar <link css> do bootstrap para novo arquivo (style.css) Alterar o Theming (Vars de Personalização) do Bootstrap: 19.Adicionar novo padrão de cor (Theme Colors) 20.Em 'resources/views/scss/style.scss', informar Theme Colors informando cores personalizadas 21.Vincular com public: npm run dev 22.Na view 'home', informar button de class danger 23.Testar: http://localhost/projetos/laravel/projeto10/public/
11.Uploads automatizados
1.Criar Migrations (Informar dados também): php artisan make:migration create_products_table --create=products php artisan make:migration create_products_images_table --create=products_images 2.Resetar BD: php artisan migrate:fresh 3.Criar Models Product e ProductImage UPLOAD SIMPLES 1.Em 'views', criar diretórios 'upload' e 'products', em 'upload' criar view 'form', em web.php' criar route 'form' 2.Testar: http://localhost/projetos/laravel/projeto11/public/form 3.Criar controller: php artisan make:controller UploadConttroller 4.UploadConttroller, criar método upload, em branco 5.'web.php', criar route 'upload' 6.View 'form', informar action 'route()' 7.UploadConttroller, popular método upload com 'dd()' 8.Testar, no Browser, uma submissão 9.UploadConttroller, método upload, informar $request->file()->store(), comentar 'dd()' (No Laravel, arquivos são salvos na pasta 'storage', gerenciado pelo arquivo config/filesystems.php, 'default'. A filesystem_driver está configurada, ou não, no arquivo .env. Se não existir, utilizará a 'local', configurada em 'disks', abaixo no mesmo arquivo) Criar filesystem_driver como public, para ser acessada: 1.Em .env, abaixo de LOG_CHANNEL, informar FILESYSTEM_DRIVER=public 2.Testar, no Browser, uma submissão (Verificar se diretório e upload fora feito) (Agora, conforme filesystems.php, os arquivos upload serão salvos em 'storage/app/public') (Conforme UploadConttroller, método store, ao fazer upload, arquivo será salvo em 'storage/app/public/pastaTeste') UPLOAD MÚLTIPLO e BD 1.Criar controller: php artisan make:controller ProductController --resource 2.Em views/products criar views create e show 3.ProductController, popular método create 4.'web.php', criar route resource ('produtos') 5.Verificar se traduziu names: php artisan route:list 6.Testar: http://localhost/projetos/laravel/projeto11/public/produtos/create 7.ProductController, popular método store com 'dd()' 8.Testar, no Browser, submissão de 2 arquivos 9.ProductController, popular método store parte de Add Product, comentar 'dd()' 10.Testar, no Browser, submissão de 2 arquivos (Verificar se gravou no BD) 11.ProductController, popular método store parte de Add Image(s), com 'var_dump()' no for e no início 12.Testar, no Browser, submissão de 2 arquivos 13.ProductController, popular método store parte de Add Image(s), comentar var_dumps 14.Testar, no Browser, submissão de 2 arquivos (Verificar se gravou no BD) 15.ProductController, popular método show 16.Testar: http://localhost/projetos/laravel/projeto11/public/produtos/4 17.Em .env, APP_URL, informar url do projeto (http://localhost/projetos/laravel/projeto11/public) 18.Atualizar Laravel url de storage à Public: php artisan storage:link 19.Testar: http://localhost/projetos/laravel/projeto11/public/produtos/4
12.Ajax no Laravel
(Baseado no Projeto7, Laravel6 login) 1.Resetar BD: php artisan migrate:fresh 2.Inserir user no Register 1.Atualizar jQuery, informando link na view 'formLogin', inserir também arquivo Ajax (https://github.com/jquery-form/form), informando link CDN 2.No final do código, informar área de código (<script>) com função Ajax, com alert teste 3.Testar: http://localhost/projetos/laravel/projeto12/public/admin/login 4.Remover method e action do form, e informar name no <form> 5.Inserir função de submissão, com alert teste2 e testar, no Browser, submissão 6.Inserir vars do form e testar, no Browser, submissões com os alerts 7.Comentar vars, inserir função $.ajax 8.Controller AuthController, alterar if de feedback de validação de email 9.Da mesma forma, informar no if Auth::attempt e abaixo, fora, dele 10.Testar, no Browser, informando email inválido e dados inválidos (Verificar console se json fora informado) 11.View formLogin, alterar, na $.ajax, console por resposta 12.Remover blocos @if e @foreach, bloco {{$error}} também. Alterar class da <div> 13.Função $.ajax, abaixo do else para erro, informar messageBox 14.Testar, no Browser, informando dados inválidos (Verificar se mensagem <div> aparecerá) 15.Testar, no Browser, informando dados corretos (Verificar se será redirecionado)
13.Enviar emails automaticamente
1.Arquivo .env, parte de mail, configurar autenticação com servidor 2.Se o remetente for Gmail, ative a opção de segurança 'Acesso a app menos seguro', nas configurações de sua conta Gmail 3.Criar objeto de email: php artisan make:mail laravelUBSocial (No diretório app, cria-se diretório Mail) 4.Em routes 'web.php', informar route 'envio-email' 5.Em 'views', criar diretório 'mail', com view 'laravelUBSocial' e populá-la 6.Em classe laravelUBSocial, método build, alterar nome da view de retorno 7.Testar: http://localhost/projetos/laravel/projeto13/public/envio-email 8.Classe laravelUBSocial, popular método build com parâmetros 9.Views 'web.php' popular view 'envio-email' com objeto std e parâmetros 10.Classe laravelUBSocial, informar parâmetro $user no método construct, populá-lo, e atributos acima dele Disparar email teste: 11.View laravelUBSocial, informar vars{{}} 12.Testar se variáveis foram informadas: http://localhost/projetos/laravel/projeto13/public/envio-email 13.web.php, comentar return new, e informar Facade Mail 14.Testar se variáveis foram informadas: http://localhost/projetos/laravel/projeto13/public/envio-email (Verificar caixa de email do destinatário) Criar template markdown de Email: 15.Importar templates markdown personalizáveis de email do Laravel: php artisan vendor:publish --tag=laravel-mail (Em resources/views cria-se diretório 'vendor/mail' com temas e configuráveis) 16.web.php, comentar linha de Mail send() e descomentar linha acima, de return 17.Testar: http://localhost/projetos/laravel/projeto13/public/envio-email 18.Classe laravelUBSocial, alterar return this->view para markdown 21.View laravelUBSocial, informar @component e @endcomponent 22.Testar: http://localhost/projetos/laravel/projeto13/public/envio-email Disparar email: 23.web.php, comentar return e descomentar Mail send() 24.Testar: http://localhost/projetos/laravel/projeto13/public/envio-email (Verificar caixa de email do destinatário)
14.Fila e processamento assíncrono
(Replica do projeto 13) Enviar requisições ao BD, para depois executá-las, ao invés de executar tudo no momento 1.web.php, alterar método send() para queue() 2.Em .env, alterar QUEUE_CONNECTION para modo 'database' 3.Adicionar table específica no BD: php artisan queue:table (Cria migrations específicas: jobs e failed_jobs) 4.Atualizar BD: php artisan migrate:fresh 5.Testar se carregamento da página ficou mais rápido: http://localhost/projetos/laravel/projeto14/public/envio-email (Ctrl+c para parar) 6.Executar queue: php artisan queue:work Criar tarefas programadas (Jobs): 1.Criar job: php artisan make:job laravelUBSocial (Em app, cria-se diretório 'jobs', com classes dentro) 2.web.php, alterar método queue por send() novamente, e recortar linha da classe job laravelUBSocial, método handle 3.web.php, informar dispatch() 4.Classe job laravelUBSocial, popular método construct, criar atributo acima 5.Executar queue: php artisan queue:work 6.Testar: http://localhost/projetos/laravel/projeto14/public/envio-email (Após delay 15seg, jobs são processados e, se houver falha, fará até 3 tentativas)
15.Autenticação com Socialite (Google,Facebook)
1.Instalar Socialite: composer require laravel/socialite 2.Diretório config, services.php, inserir trecho de configuração 'facebook' 3.Arquivo .env, informar todas as chaves do trecho de configuração 'facebook', no final do arquivo (Valores serão informados em breve) FACEBOOK: (Página Facebook Developers) 1.Meus Apps/Criar novo: Pegar id do app gerado e colá-lo no FACEBOOK_CLIENT_ID 2.Configurar, na página, em Facebook Login/Web, infrmar url (http://localhost/projetos/laravel/projeto15/public/), avançar até finalizar 3.Em configurações/basico, copiar key e colá-la no FACEBOOK_CLIENT_SECRET, informar domínio (localhost) e urls de privacidade e termos de uso (Da aplicação/github como exemplo), tipo de uso comercial (Apoia minha própria empresa) e salvar alterações Criar routes: 4.Criar controller SocialiteController: php artisan make:controller SocialiteController 5.Em SocialiteController, informar métodos 6.Em routes 'web.php', informar routes 7.Testar login: http://localhost/projetos/laravel/projeto15/public/login/facebook, clicar em 'continuar', e um erro 404 de feedback aparecerá 8.Em .env, alterar APP_URL com url informada (http://localhost/projetos/laravel/projeto15/public) 9.Testar login (http://localhost/projetos/laravel/projeto15/public/login/facebook), cairá em uma página em branco GOOGLE: 1.Diretório config, services.php, inserir trecho de configuração 'google' 2.Arquivo .env, informar todas as chaves do trecho de configuração 'google', no final do arquivo (Valores serão informados em breve) 3.Em SocialiteController, informar métodos Google 4.web.php, informar routes google Página Google Developers Console: Credenciais / Criar Credenciais / ID do Cliente OAuth / Tipo de Aplicativo(App da web) / Nome(Laravel Socialite) / Origens JS autorizadas(http://localhost) / URLs de Redirecionamento Autorizados(http://localhost/projetos/laravel/projeto15/public/login/google)(http://localhost/projetos/laravel/projeto15/public/login/google/callback) / Create 1.Copiar id e chave, colá-los no .env do Google 2.Testar login: http://localhost/projetos/laravel/projeto15/public/login/google
16.Sessões com Helper e Facade
1.Em config/session.php e .env alterar SESSION_DRIVER de 'file' para 'cookie' 2.Criar controller SessionController: php artisan make:controller SessionController 3.SessionController, criar método session com somente dd() 4.Em routes 'web.php', criar route session 5.Testar: http://localhost/projetos/laravel/projeto16/public/session Gravar dados na sessão: 6.SessionController, método session, popular método e testar, no Browser, mesma url 7.Testar: http://localhost/projetos/laravel/projeto16/public/session (1ª vez confira flash, comente a Session::flash, depois recarregue a página novamente (Ainda à exibirá), depois novamente (sumirá))
17.Autenticação JWT em API REST
1.Resetar BD: php artisan migrate:fresh 2.Inserir 1 user na table Users 3.Criar controller Api\UserController: php artisan make:controller Api\UserController --api 4.Controller UserController, popular méotodo index 5.Em routes 'api.php', comentar primeira route, criar route 'users' 6.Testar se retornará json: http://localhost/projetos/laravel/projeto17/public/api/users Proteger EndPoint público: 7.Instalar JWT-Auth: composer require tymon/jwt-auth 1.0.1 8.Em config/app.php, inserir linha em 'providers' 9.Publicar configurações: php artisan vendor:publish --provider="Tymon\JWTAuth\Providers\LaravelServiceProvider" 10.Gerar Key: php artisan jwt:secret (Key estará no final do .env) 11.Atualizar Mode User, informando 'implements' e métodos 12.Em config/auth.php, inserir 'defaults' e 'guards' 13.Criar controller AuthController (Populá-lo após criá-lo): php artisan make:controller Api\AuthController 14.Em routes 'api.php', informar route 'login' 15.Em routes 'api.php', informar route '/home' 16.Criar view 'home' 17.Criar middleware apiProtectedRoute (Populá-lo após criá-lo): php artisan make:middleware apiProtectedRoute 18.Em Controllers/kernel.php, informar apelido do middleware 19.Em routes 'api.php', informar route group, colocar route 'users' dentro dela 20.Testar se retornará json: http://localhost/projetos/laravel/projeto17/public/api/users, informando token bear, válido por 3600 segundos


Laravel 9: Novidades

Recursos
  • Requer Php 8.1 ou superior (8 para funcionalidades principais, superior para funcionalidades específicas). Com isso, houve-se inclusão de funções String como str_contains(), str_starts_with() e str_ends_with()
  • Utilização da library Symfony Mailer no lugar do Swift Mailer para emissões de emails
  • Atualização do sistema de gerenciamento de arquivos, Flysystem 3.x
  • Adesão à banco de dados Scout (Propriedade Scout) para pequenas/médias bases de dados de cargas de trabalho, com cláusulas 'where like' e índices fullText, ao invés de serviços dedicados, como Algolia ou MeiliSearch
  • Laravel Breeze recebeu novo modo de scaffolding 'API' e implementação front-end no Next.js, para que possam ser utilizados em aplicações back-end e API autenticada via Laravel Sanctum para front-end JavaScript
  • Pagina de depuração de exceção de código fora redesenhada e com temas personalizados (Light/Dark)
  • Saída CLI do route:list fora redesenhada e melhor organizada
  • Comando 'php artisan test --coverage --min=80.3' para explorar quantidade de cobertura de código aos testes realizados, com min para limitação de tempo, via Xdebug
  • Aprimoramento da documentação do servidor web socket Soketi, parceiro do Laravel, compatível com Laravel e escrito com Node.js
  • Suporte aprimorado para Collections IDE, adiciona definições genéricas aprimoradas às collections, aprimorando para IDEs e editores de código, com suporte à análise e estatística
  • Arquivo 'server.php' removido, fora incluso dentro do próprio framework, podendo somente ser usado com 'php artisan serve'
  • Proteção contra falhas em filas em jobs com 'php artisan queue:flush', como 'php artisan queue:flush --hours=24'
  • Tempo limite padrão, em segundos, nas requisições do Guzzle HTTP para timeout como 'Http::timeout(60)->get(...);'
  • Inclusão da propriedade 'sticky', no arquivo de configuração do BD, para proteção de escrita / gravação em base de dados, em casos de replicação de dados

Definir acessores e mutadores do Eloquent

Anteriormente, a maneira de realizar trabalhos com gets e sets ocorria no seguinte formato


public function getNameAttribute($value) {
    return strtoupper($value);
}

public function setNameAttribute($value) {
    $this->attributes['name'] = $value;
}

Agora, a maneira fora simplificada


use Illuminate\Database\Eloquent\Casts\Attribute;

public function name(): Attribute {
    return new Attribute(
        get: fn ($value) => strtoupper($value),
        set: fn ($value) => $value,
    );
}

Além disso, pode-se armazenar, em cache, os valores de objeto que são retornados pelo atributo, assim como classes de conversão


use App\Support\Endereco;
use Illuminate\Database\Eloquent\Casts\Attribute;

public function endereco(): Attribute {
    return new Attribute(
        get: fn ($value, $attributes) => new endereco(
            $attributes['endereco_linha_um'],
            $attributes['endereco_linha_dois'],
        ),
        set: fn (Endereco $value) => [
            'endereco_linha_um' => $value->linhaUm,
            'endereco_linha_dois' => $value->linhaDois,
        ],
    );
}

Conversão de valores de atributos para Enums

use App\Enums\ServerStatus;
/**
* The attributes that should be cast.
*
* @var array
*/

protected $casts = [
    'status' => ServerStatus::class,
];

Para finalizar a conversão, basta interagir com o mesmo


if ($server->status == ServerStatus::provisioned) {
    $server->status = ServerStatus::ready;
    $server->save();
}

Enum em definição de rota

Pode-se informar Enum em definição de rota, onde o Laravel o invocará somente no caso de valor válido no URI. Caso contrário, retornará erro 404. Dado o seguinte Enum


enum Categoria: string {
    case Frutas = 'frutas';
    case Pessoas = 'pessoas';
}

Se o segmento da rota Categoria for frutas ou pessoas, a rota será invocada. Caso contrário, retornará erro 404


Route::get('/categorias/{categoria}',function(Categoria $categoria) {
    return $categoria->value;
});

Associação de escopo ou agrupamento de rotas

Anteriormente, podia-se definir escopos Eloquent aninhados/filhos de outro anterior na definição de rota


use App\Models\Post;
use App\Models\User;

Route::get('/users/{user}/posts/{post:slug}',function(User $user, Post $post) {
    return $post;
});

Agora, pode-se definir as ligações filhas mesmo sem chave de ligação, via método scopeBindings


use App\Models\Post;
use App\Models\User;

Route::get('/users/{user}/posts/{post}',function(User $user, Post $post) {
    return $post;
})->scopeBindings();

Ou via definição do grupo inteiro com associações de escopo


Route::scopeBindings()->group(function () {
    Route::get('/users/{user}/posts/{post}',function(User $user, Post $post) {
        return $post;
    });
});

Agrupamento de rotas controladoras

Com um controlador comum para todas as rotas do mesmo grupo, basta, ao definir as rotas, fornecer o método controlador para invocá-las


use App\Http\Controllers\OrderController;

Route::controller(OrderController::class)->group(function() {
    Route::get('/orders/{id}','show');
    Route::post('/orders','store');
});

Índices fullText e cláusulas Where

Via MySQL ou PostgreSQL, o método fullText pode ser adicionado às definições de colunas para gerar índices fullText


$table->text('funcao')->fullText();

Além disso, métodos whereFullText e orWhereFullText podem ser usados para adicionar cláusulas where em queries para colunas fullText ao banco de dados do projeto


$users = DB::table('funcionario')
        ->whereFullText('funcao','desenvolvedor laravel')
        ->get();

Renderização inline de templates Blade

Para transformar uma String Blade em Html, basta usar o método de renderização


use Illuminate\Support\Facades\Blade;
return Blade::render('Olá, {{$nome}}',['nome'=>'UB Social']);

Da mesma forma, pode-se renderizar determinado componente de classe passando sua instância


use App\View\Components\HelloComponent;
return Blade::renderComponent(new HelloComponent('UB Social'));

Atalhos para Slot Name

Anteriormente, os Slot Names eram fornecidos usando atributo name na tag x-slot


<x-alert>
    <x-slot name="title">Server Error</x-slot>
    <p>Erro na comunicação com o servidor!</p>
</x-alert>

Agora, a maneira fora simplificada


<x-slot:title>Server Error</x-slot>

Diretivas Blade checadas / selecionadas

Pode-se utilizar diretiva @checked para indicar caixa de seleção Html como marcada


<input type="checkbox"
    name="active"
    value="active"
    @checked(old('active',$user->active))/>

Da mesma forma, utilizar diretiva @selected para indicar caixa de seleção Html como selecionada


<select name="version">
    @foreach ($product->versions as $version)
        <option value="{{ $version }}" @selected(old('version') == $version)>
            {{ $version }}
        </option>
    @endforeach
</select>

Visões de paginação com Bootstrap 5

Para indicar esse novo formato, ao invés do anterior com Tailwind, basta chamar o método useBootstrapFive no paginador dentro do método de inicialização do AppServiceProvider


use Illuminate\Pagination\Paginator;
/**
* Bootstrap any application services.
*
* @return void
*/

public function boot() {
    Paginator::useBootstrapFive();
}

Validação aprimorada de dados em matriz aninhada

Para acessar elemento de matriz aninhada, pode-se usar o método Rule::forEach, que aceitará closure invocada a cada nova iteração, pegando o valor do atributo


use App\Rules\HasPermission;
use Illuminate\Support\Facades\Validator;
use Illuminate\Validation\Rule;
 
$validator = Validator::make($request->all(), [
    'companies.*.id' => Rule::forEach(function($value,$attribute) {
        return [
            Rule::exists(Company::class,'id'),
            new HasPermission('manage-company',$value),
        ];
    }),
]);

Novos helpers

A função str retorna nova instância para a String fornecida. A função to_route gera resposta HTTP de redirecinamento para determinada rota. Neste caso, se necessário, pode-se informar o código de status HTTP que deve ser atribuído ao redirecionamento e quaisquer headers de respostas adicionais como terceiros e quartos argumentos ao método to_route


$string = str('UB')->append(' Social'); //'UB Social'
$snake = str()->snake('UBSocial'); //'UBSocial'

return to_route('users.show',['user'=>1]);
return to_route('users.show',['user'=>1],302,['X-Framework'=>'Laravel']);

Migrations anônimas

Para evitar colisão de nomes com classes migrations, fora padronizada a criação de migrations 'php artisan make:migration'


use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;

return new class extends Migration {
    /**
    * Run the migrations.
    *
    * @return void
    */

    public function up() {
        Schema::table('people', function (Blueprint $table) {
            $table->string('first_name')->nullable();
        });
    }
};

Nova interface Query Builder

# Essa feature inclui 'lluminate\Contracts\Database\QueryBuilder', 'Illuminate\Database\Eloquent\Concerns\DecoratesQueryBuilder' no lugar da implementação '_call'
return Model::query()
    ->whereNotExists(function($query) {
        //$query via Query\Builder
    })
    ->whereHas('relation',function($query) {
        //$query via Eloquent\Builder
    })
    ->with('relation',function($query) {
        //$query via Eloquent\Relation
    });

Chaves inválidas em arrays

O Laravel mostrará somente tipos citados elencados ao mesmo array, conforme resposta do código abaixo, onde anteriormente criaria-se novo array com o segundo componente (Mostrará os 2 nomes strings elencados ao único array 1). O método de validação também pode ser utilizado em outros momentos


validator(
    [
        'users' => [
            ['name'=>'UB Social', 'id'=>89],
            ['name'=>'Laravel', 'id'=>9],
        ]
    ],
    [
        'users.*.name' => 'string'
    ]
)->validate();

Elaborado por Mateus Schwede
ubsocial.github.io