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.
NA PRÁTICA
(Atente-se com os 'use' e 'namespace', para checar se os mesmos encontram-se e correspondem à árvore de diretórios)
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
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,
],
);
}
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();
}
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;
});
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;
});
});
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');
});
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();
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'));
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>
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>
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();
}
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),
];
}),
]);
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']);
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();
});
}
};
# 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
});
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