Laravel
===
###### tags: `php` `estudos` `laravel`
# Dicas
Preenchimento do formulários com os valores digitados antes do submit
* https://laracasts.com/discuss/channels/general-discussion/keeping-input-on-form-validation-request
Reaproveitar formulário tanto para criação como edição:
* https://laracasts.com/discuss/channels/requests/keep-inputs-after-failed-validation
## Blade Docs
* https://laravel.com/docs/master/blade
## Laravel DataBase Migrations
* https://laravel.com/docs/master/migrations
## Laravel Eloquent ORM
* https://laravel.com/docs/master/eloquent
## Laravel Database
* https://laravel.com/docs/master/database
## API para testes...
https://swapi.co/
## Criacao de API baseada em arquivo json
https://github.com/typicode/json-server
## Lara Notification -> telegram...
composer require laravel-notification-channels/telegram
## exemplo de implementacao de jwt similar ao apresentado em aula...
https://medium.com/@aschmelyun/securing-your-laravel-api-with-jwts-in-10-minutes-or-less-9622541244f6
# Dia 01
Para criar um projeto com Laravel:
No Linux:
`composer create-project laravel/laravel --prefer-dist projeto`
## 1 - Configurar ENV
Alterar o arquivo “.env”
### .env
```bash=
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=bdmnlar2
DB_USERNAME=root
DB_PASSWORD=coti
```
## 2 - Criar o banco...
```bash=
create database bdmnlar2;
use bdmnlar2;
```
## 3 - Criar Model
Criar uma classe...
==php artisan make:model Pessoa==
### 3.1 Pessoa.php
```php=
<?php
namespace App;
use IlluminateDatabaseEloquentModel;
class Pessoa extends Model{
protected $fillable= [
'id','nome','idade'
];
protected $table='pessoas';
}
```
## 4 - Criar Migration
Criar a base da tabela..
==php artisan make:migration pessoas==
### 4.1 - NossaMigration gerada...
```php=
<?php
use IlluminateSupportFacadesSchema;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateDatabaseMigrationsMigration;
class Pessoas extends Migration{
//Criando a tabela pessoa com 3 campos ...
public function up() {
Schema::create('pessoas', function (Blueprint $table){
$table->increments('id');
$table->string('nome',50);
$table->integer('idade');
$table->string('endereco',50)->nullable();
$table->timestamps();
});
}
public function down() {
Schema::drop('pessoas');
}
}
```
### 4.2 - aplicar nossa migration (criando a tabela no banco)
==php artisan migrate==
Forçar a execução
==php artisan migrate --force==
ou
==php artisan migrate:rollback==
Em últimos casos
==php artisan migrate:reset==
ou
==php artisan migrate:refresh --seed==
## 5 - Criar Controller
Criar o controller:
==php artisan make:controller pessoaController==
### 5.1 - PessoaController.php
```php=
<?php
namespace AppHttpControllers;
use AppPessoa;
use IlluminateHttpRequest;
class PessoaController extends Controller{
protected $pessoas;
public function __construct(Pessoa $pessoas) {
$this->pessoas = $pessoas;
}
//index está buscando todos os dados de pessoa
public function index() {
//$pessoas = $this->pessoas->paginate(3);
$pessoas = $this->pessoas->all();
// olha o nome do blade aqui
//return view('pessoas',compact('pessoas'));
return view('pessoas', ['pessoas' => $pessoas]);
}
//Metodo Show (buscar pelo Codigo)
public function show($id) {
//pessoa (id pre, nome pre, idade pre)
//Eloquent
$pessoa = $this->pessoas->find($id);
//nomedoBlade
return view('buscapessoa', compact('pessoa'));
}
// /form ele irá entrar em Cadastrar ...
public function create() {
//É uma entrada
return view('cadastrar');
}
public function posts(Request $request) {
//resgata TUDO
//dd($request);
$request->validate([
'idade' => 'required|numeric|min:18|max:150',
]);
$pessoa = $request->all();
//dd($pessoa);
$this->pessoas->create($pessoa); //esta Gravando aqui
return redirect()->route('listar')->
with('success', 'Pessoa Cadastrada com Sucesso');
}
}
```
---
## 6 - Adicionar ROTAS
Criar as rotas...
### 6.1 - web.php
```php=
Route::get('/','PessoaController@index')->name('listar');
Route::get('id/{id}','PessoaController@show')->name('buscar');
Route::get('/form','PessoaController@create')->name('formulario');
Route::post('/salvar','PessoaController@posts')->name('salvarPessoa');
```
## 7 - Criar Views VIEWs
Criar as telas (views)...
### 7.1 - pessoas.blade.php
```php=
<h2>Listagem de Pessoas</h2>
<p/>
<!--tem sessao se tiver imprime-->
@if(session('success'))
<div>
{{session('success')}}
</div>
@endif
<table border="1">
<tr>
<td>Id</td>
<td>Nome</td>
<td>Endereco</td>
<td>Idade</td>
<td>Detalhar</td>
</tr>
@foreach ($pessoas as $p)
<tr>
<td>{{$p->id}}</td>
<td>{{$p->nome}}</td>
<td>{{$p->endereco}}</td>
<td>{{$p->idade}}</td>
<td><a href="{{route('buscar',$p->id)}}">find</a></td>
</tr>
@endforeach
</table>
<br/>
<a href="{{route('formulario')}}">Cadastrar Pessoa</a>
```
----
### 7.2 - cadastrar.blade.php
```php=
<!doctype html>
<html lang="pt">
<head>
</head>
<body>
<form method="post" action="{{route('salvarPessoa')}}">
@csrf
<br/>Nome<br/>
<input type="text" name="nome" id="nome"
required="required" />
<br/>Idade<br/>
<input type="number" name="idade" id="idade" required="required" value="{{old('idade')}}" />
@if ($errors->has('idade'))
{{$errors->first('idade')}}
@endif
<br/>Endereco<br/>
<input type="text" name="endereco" id="endereco" required="required" />
<br/>
<button type="submit">Enviar os Dados</button>
</form>
<br/>
<a href="{{route('listar')}}">Listar Pessoas</a>
</body>
</html>
```
----
### 7.3 - buscapessoa.blade.php
```php=
<h2>Detalhes da Pessoa</h2>
<hr/>
Id :{{$pessoa->id}}<br/>
Nome :{{$pessoa->nome}}<br/>
Endereco :{{$pessoa->endereco}}<br/>
Idade :{{$pessoa->idade}}<br/>
<br/>
<a href="{{route('listar')}}">Voltar Listagem</a>
```
----
## 8 - Rodar o projeto..
`php artisan serve --port=8888`
Digitar a URL passada...
http://127.0.0.1:8888/
Criar controller e model...
`php artisan make:controller NameController --resource --model=NameModel`
---
---
# Dia 02
## Criado Model clientes
==php artisan make:model Model/Clientes==
```php=
<?php
namespace App\Model;
use Illuminate\Database\Eloquent\Model;
class Cliente extends Model
{
protected $primaryKey = "id";
protected $fillable = [
"nome", "email", "sexo", "idade"
];
protected $table = "clientes";
}
```
## Criando Migration clientes
==php artisan make:migration clientes==
```php=
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class Clientes extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('clientes', function (Blueprint $table) {
$table->Increments('id');
$table->string('nome',50);
$table->string('email',100)->unique();
$table->enum('sexo', ['m', 'f']);
$table->integer('idade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('clientes');
}
}
```
==php artisan migrate==
[Campos permitidos para mirations](https://laravel.com/docs/5.8/migrations#columns)
## Se precisar alterar o banco de dados
Usa o mesmo arquivo *migrate* e cria a estrutura no novo banco de dados informado no arquivo **/.env**.
:::danger
:warning: Limpa os dados (Cuidado!!!)
==php artisan migrate:refresh==
:warning: Apaga a tabela (Cuidado!!!)
==php artisan migrate:refresh --seed==
:::
## Seeder
Procedimento teste para popular com dados randomicos nossa tabela...
==php artisan make:seeder ClientesTableSeeder==
```php=
<?php
use Illuminate\Database\Seeder;
use Illuminate\Support\Str;
use Illuminate\Support\Facades\DB;
class ClientesTableSeeder extends Seeder
{
/**
* Run the database seeds.
*
* @return void
*/
public function run()
{
DB::table('clientes')->insert([
'nome' => Str::random(10),
'email' => Str::random(10).'@gmail.com',
'sexo' => 'm',
'idade' => '10'
]);
}
}
```
==php artisan db:seed --class ClientesTableSeeder==
---
## Exemplo de migration para ajuste de posicao de campo
==php artisan make:migration add_idade_table_clientes --table=clientes==
```php=
<?php
use IlluminateSupportFacadesSchema;
use IlluminateDatabaseSchemaBlueprint;
use IlluminateDatabaseMigrationsMigration;
class AddIdadeTableClientes extends Migration
{
public function up()
{
Schema::table('clientes', function (Blueprint $table) {
$table->integer('idade')->after('email');
});
}
public function down()
{
}
}
```
==php artisan migrate==
---
## Criando controller ClienteController
==php artisan make:controller ClienteController==
---
## Implementando Bootstrap no Lara
```bash=
composer require laravel/ui
php artisan ui bootstrap
npm install && npm run dev
```
---
composer require laravel/ui &&
php artisan ui bootstrap --auth&&
npm install && npm run dev
## Inclusao de idiomas...
Baixar repo e incluir em ==resources/lang==
https://github.com/caouecs/Laravel-lang
ajustar locale dentro do "/config/app.php"
---
---
## Relacionamento Um pra Um...
```bash=
php artisan make:model Model/Endereco
php artisan make:model Model/Funcionario
```
```php=
<?php
namespace App\Model;
use Illuminate\Database\Eloquent\Model;
class Funcionario extends Model
{
protected $primaryKey = "id";
protected $fillable = [
'id',
'nome',
'email'
];
protected $tables = "funcionarios";
public function endereco()
{
return $this->hasOne(Endereco::class, 'funcionario_id', 'id');
}
}
```
```php=
<?php
namespace App\Model;
use Illuminate\Database\Eloquent\Model;
class Endereco extends Model
{
protected $primaryKey = "funcionario_id";
protected $fillable = [
'funcionario_id',
'logradouro',
'bairro',
'cidade',
'estado',
'cep'
];
protected $tables = "enderecos";
public function funcionario()
{
return $this->belongsTo(Funcionario::class, 'funcionario_id', 'id');
}
}
```
```bash=
php artisan make:migration funcionarios
php artisan make:migration enderecos
```
---
```php
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class Funcionarios extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('funcionarios', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('nome', 50);
$table->string('email',50)->unique();
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('funcionarios');
}
}
```
---
==php artisan make:controll FuncionarioController --resource==
# Exemplo do Controller
Ver o método findFuncionario onde aplicamos filtros tanto na tabela principal (funcionarios) a secundária
```php
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Model\Funcionario;
use App\Model\Endereco;
use DB;
class FuncionarioController extends Controller
{
protected $funcionarios;
public function __construct(Funcionario $funcionarios)
{
$this->funcionarios = $funcionarios;
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index(Request $req)
{
$lista = $this->funcionarios->all();
//dd($lista);
if ($req->session()->has('message')===false) {
$req->session()->put("message", "Bem vindo");
}
return view('index', [ "funcionarios" => $lista ]);
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
//Não esquecer do @csrf
public function createFuncionario()
{
return view('createFuncionario');
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
//dd($request);
$ende=null;
$message=null;
$request->validate([
'nome'=>'required|string|max:50|min:2',
'email'=>'email',
'cep'=>'required|string|min:8|max:10',
'logradouro'=>'required',
'bairro'=>'required',
'cidade'=>'required',
'estado'=>'required|string|max:2|min:2',
]);
try {
DB::beginTransaction();
$funcionario = Funcionario::create([
'nome' => $request->get('nome'),
'email' => $request->get('email')
]);
if ($funcionario) {
$ende=$funcionario->endereco()->create([
//'funcionario_id' => $funcionario->attributes['id'],
'logradouro' => $request->get('logradouro'),
'bairro' => $request->get('bairro'),
'cidade' => $request->get('cidade'),
'estado' => $request->get('estado'),
'cep' => $request->get('cep')
]);
}
if ($funcionario && $ende) {
DB::commit();
$message='Funcionário cadastrado com sucesso';
} else {
DB::rollBack();
$message='Erro ao cadastrar funcionário';
}
return redirect()->route('index')->
with('message', $message);
} catch(\Exception $ex) {
return redirect()->route('formulario')->
with('message', 'Erro ao criar funcionário: '.$ex->getMessage());
}
}
public function erros(Reques $ex) {
return view('erros');
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function findFuncionario(Request $request)
{
$request->session()->forget('message');
//dd(Endereco::where('logradouro', '=', 'Rua a')->get() );
$query=
$funcs = $this->funcionarios->where('nome', '=', $request->get('buscar'))
->orWhere('email', '=', $request->get('buscar'))
->orWhere('id', '=', $request->get('buscar'))
->orWhereHas('Endereco', function ($query) use ($request) {
//dd($request);
$query->where('logradouro', '=', $request->get('buscar'));
})->get();
/*
$funcs = DB::select('select * from funcionarios
where nome = ? OR email = ? OR id = ? ', [
$request->get('buscar'),
$request->get('buscar'),
$request->get('buscar')]);
*/
$message='';
if (count($funcs)==0) {
$message="Não foram encontrados funcionarios para a consulta: "
.$request->get('buscar');
$request->session()->put("message", $message);
}
return view('index', [ "funcionarios" => $funcs ])->
with('message', $message);
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request, $id)
{
//
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function destroy($id)
{
//
}
}
```
# Dia 06
## 1 para muitos - Relacionamentos - hasMany
### Projeto Correntista - Laravel
Neste estudo não vamos usar o diretório ==/app/Model== para as nossas classes modelo.
Vamos criar seguindo o novo padrão do Laravel que é deixá-las no diretório ==/app==
:::info
A regra é:
- Em casos de poucas models, podemos deixar no local default (==/app==);
- para projetos maiores, a fim de uma melhor organização, utilizar a pasta Model(==/app/Model==).
:::
Inicialmente teremos duas tabelas, "correntista" e "movimentacoes".
A tabela correntista terá realcionamento de um para muitos com a tabela movimentacoes.
```graphviz
digraph G {
size="5,5"
node[shape=record,style=filled,fillcolor=gray95]
edge[dir=back, arrowtail=empty]
1[label = "{Correntista|- id\n- nome\n- saldo\n}"]
2[label = "{Movimentacoes|-id\n- operacao\n- valor}"]
1->2 }
```
Seguem os arquivo migrations:
**2019_09_16_122315_create_correntistas_table.php**
```php=
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateCorrentistasTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('correntistas', function (Blueprint $table) {
$table->increments('id');
$table->string('nome', 50);
$table->decimal('saldo', 8 ,2);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('correntistas');
}
}
```
**2019_09_16_122326_create_movimentacoes_table**
```php=
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class CreateMovimentacoesTable extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('movimentacoes', function (Blueprint $table) {
$table->increments('id');
$table->string('operacao', 20);
$table->double('valor');
$table->integer('correntista_id')->unisigned();
$table->foreign('correntista_id')->references('id')->on('correntistas');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('movimentacoes');
}
}
```
Para cada tabela temos um arquivo de classe (modelo). Segue abaixo:
**Correntista.php**
```php=
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\Movimentacao;
class Correntista extends Model
{
protected $primaryKey = "id";
protected $fillable = ['id', 'nome', 'saldo'];
protected $table = 'correntistas';
public function movimentacoes()
{
return $this->hasMany(Movimentacao::class);
}
}
```
**Movimentacao.php**
```php=
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\Correntista;
class Movimentacao extends Model
{
//Many to One
protected $primaryKey = "id";
protected $fillable = ['id', 'operacao', 'valor', 'correntista_id'];
protected $table = 'movimentacoes';
//Muitos para um singular (chamando a classe com hasMany)
public function correntista()
{
return $this->belongsTo(Correntista::class);
}
}
```
## Criando o controller
php artisan make:controller correntistaController
```php=
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Correntista;
use App\Movimentacao;
use DB;
class CorrentistaController extends Controller
{
protected $correntistas;
public function __construct(Correntista $correntistas)
{
$this->correntistas = $correntistas;
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index(Request $req)
{
$lista = $this->correntistas->all();
//dd($lista);
if ($req->session()->has('message')===false) {
$req->session()->put("message", "Bem vindo");
}
return view('index', [ "correntistas" => $lista ]);
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function rest(Request $req)
{
//$lista = $this->correntistas->all();
//dd($lista);
//return json_encode($lista);
return response()->json(Correntista::all(), 200);
}
public function cadastro()
{
return view('cadastro');
//return view('cadastrar', compact('cliente'));
}
public function create(Request $req)
{
$req->validate([
'nome'=>'required|string|max:50|min:2',
'saldo'=>'required|numeric'
]);
//dd($req->id);
/* Meu código */
$correntista = $req->all();
$this->correntistas->create($correntista);
return redirect()->route('index')->
with('message', 'Correntista cadastrado com sucesso');
}
public function deposito($id)
{
$correntista = $this->correntistas->find($id);
return view('deposito', compact('correntista'));
}
public function retirada($id)
{
$correntista = $this->correntistas->find($id);
return view('retirada', compact('correntista'));
}
public function depositopost(Request $req)
{
$movimentacao=null;
$message=null;
$req->validate([
'id'=>'required|numeric',
'nome'=>'required|string|max:50|min:2',
'valor'=>'required|numeric|min:1'
]);
try {
DB::beginTransaction();
$correntista = $this->correntistas->findOrFail($req->get('id'));
$movimentacao = Movimentacao::create([
'operacao' => 'deposito',
'valor' => $req->get('valor'),
'correntista_id' => $req->get('id')
]);
if ($movimentacao) {
$novoSaldo=($correntista->saldo + $req->get('valor'));
//dd($params['id']);
$correntista->update(['saldo' => $novoSaldo]);
//OU
//$correntista = $this->correntistas->findOrFail($req->get('id'));
//deposito=$req->valor;
//$correntista->saldo = $correntista->saldo + deposito;
//$correntista->save();
}
if ($movimentacao && $correntista) {
DB::commit();
$message='Depósito realizado com sucesso.';
} else {
DB::rollBack();
$message='Falha ao registrar depósito.';
}
return redirect()->route('index')->
with('message', $message);
} catch(\Exception $ex) {
return redirect()->route('formulario')->
with('message', 'Falha ao registrar depósito: '.$ex->getMessage());
}
}
public function retiradapost(Request $req)
{
$movimentacao=null;
$message=null;
$req->validate([
'id'=>'required|numeric',
'nome'=>'required|string|max:50|min:2',
'valor'=>'required|numeric'
]);
try {
DB::beginTransaction();
$correntista = $this->correntistas->findOrFail($req->get('id'));
$movimentacao = Movimentacao::create([
'operacao' => 'retirada',
'valor' => $req->get('valor'),
'correntista_id' => $req->get('id')
]);
if ($movimentacao) {
$novoSaldo=($correntista->saldo - $req->get('valor'));
//dd($params['id']);
$correntista->update(['saldo' => $novoSaldo]);
//OU
//$correntista = $this->correntistas->findOrFail($req->get('id'));
//deposito=$req->valor;
//$correntista->saldo = $correntista->saldo + deposito;
//$correntista->save();
}
if ($movimentacao && $correntista) {
DB::commit();
$message='Depósito realizado com sucesso.';
} else {
DB::rollBack();
$message='Falha ao registrar depósito.';
}
return redirect()->route('index')->
with('message', $message);
} catch(\Exception $ex) {
return redirect()->route('formulario')->
with('message', 'Falha ao registrar depósito: '.$ex->getMessage());
}
}
}
```
# Muitos para muitos - Relacionamentos - many2Many
Neste projetos usaremos a estrutura de **alunos** e **cursos** onde o relacionamento entre ambos é de muitos para muitos.
```graphviz
digraph G {
size="5,5"
node[shape=record,style=filled,fillcolor=gray95]
edge[dir=back, arrowtail=empty]
1[label = "{Alunos|- id\n- nome\n- email\n}"]
2[label = "{Aluno_Curso|-id\n- aluno_id\n- curso_id}"]
3[label = "{Cursos|-id\n- descrição}"]
1->2
2->1
2->3
3->2}
```
---
# DIA 7
## JWT (Json Web Token)
### Referências
[https://jwt.io/](https://jwt.io/)
fluxo padrao:

É um padrão de autenticação que utiliza token
Sistema de proteção.
Bearer - padrão de autenticação simples - necessita de um token
Rota livre - onde se pode fazer o que quiser
Rota segura - só entra autenticado
### Início
```bash=
php artisan make:model Model/Aluno
php artisan make:migration alunos
php artisan make:controller AlunoController
```
Editar o arquivo .env com os dados do exemplo.
/.env
```bash=9
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=BDOICOTIREST
DB_USERNAME=root
DB_PASSWORD=coti
```
App/Model/Aluno.php
```php=
<?php
namespace App\Model;
use Illuminate\Database\Eloquent\Model;
class Aluno extends Model
{
protected $table = 'alunos';
protected $primaryKey = 'id';
protected $fillable = [
'id',
'nome',
'email',
'password',
];
}
```
### Instalar JWT no Laravel
```bash=
composer require tymon/jwt-auth:1.0.*
php artisan vendor:publish --provider="TymonJWTAuthProvidersLaravelServiceProvider"
php artisan jwt:secret
```
### Exemplo de implementação de RateLimit, sendo para esta rota 5 chamadas/minuto autorizado
Route::get('/lista','AlunoController@listar')->middleware('throttle:5,1')->name('listagem');
# Exemplo 7
## Chamadas Rest
Pessoa.php
```php=
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
class Pessoa extends Model
{
protected $table = 'pessoas';
protected $primaryKey = 'id';
protected $fillable = [
'nome',
'email',
'idade',
];
}
```
web.php
```php=
<?php
Route::prefix('pessoa')
->middleware('throttle:5,1')
->group(function () {
Route::get('/', 'PessoaController@index')->name('index');
Route::get('/{id}', 'PessoaController@findById')->name('find');
Route::post('/', 'PessoaController@store')->name('store');
Route::put('/', 'PessoaController@update')->name('update');
Route::delete('/{id}', 'PessoaController@delete')->name('delete');
});
```
---
PessoaController.php
```php=
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Pessoa;
class PessoaController extends Controller
{
protected $pessoas;
public function __construct(Pessoa $pessoas)
{
$this->pessoas = $pessoas;
}
public function index()
{
return response()->json(['lista' => Pessoa::all() ],200 );
}
public function store(Request $req)
{
$pessoa = new Pessoa($req->all());
$pessoa->save();
return response()->json(['msg'=>'Store OK','pessoas' => Pessoa::all()]);
}
public function delete($id)
{
$pessoa = Pessoa::find($id);
$pessoa->delete();
return response()->json(['msg'=>'Delete OK','pessoas' => Pessoa::all()]);
}
public function update(Request $req)
{
$pessoa = Pessoa::find($req->input('id'));
$pessoa->fill($req->all());
$pessoa->save();
return response()->json(['msg'=>'Update OK','pessoas' => Pessoa::all()]);
}
public function findById($id)
{
return response()->json(['pessoa', Pessoa::find($id)], 200);
}
}
```
---
migration_pessoas.php
```php=
<?php
use Illuminate\Database\Migrations\Migration;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Support\Facades\Schema;
class Pessoas extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('pessoas', function (Blueprint $table) {
$table->bigIncrements('id');
$table->string('nome');
$table->string('email')->unique();
$table->integer('idade');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('pessoas');
}
}
```
---
---
# Email Mail
[http://dontpad.com/emailmail](http://dontpad.com/emailmail)
---
---
# Projeto Final
```graphviz
digraph G {
size="5,5"
node[shape=record,style=filled,fillcolor=gray95]
edge[dir=back, arrowtail=empty]
1[label = "{Artigo|-id\n- titulo\n- conteudo\n|escritor()}"]
2[label = "{Escritor|- id\n- nome\n- email\n- foto\n|artigos()}"]
3[label = "{ControllerEscritor|+index()\n+ create()\n+ update()\n+ delete()\n}"]
1->2}
```
---
---
## Criando os modelos
php artisan make:model Escritor
php artisan make:model Artigo
## Criando as "migrations" para os Banco de dados
php artisan make:migration escritores
php artisan make:migration artigos
## Criando a Controller
php artisan make:controller ControllerEscritor --resource
## Criando a base de dados (MySQL)
```bash=
mysql -u root -p
mysql> create database COTIOIFINAL;
Query OK, 1 row affected (0,02 sec)
mysql> use COTIOIFINAL
Database changed
mysql>
```
.env
```bash
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=COTIOIFINAL
DB_USERNAME=root
DB_PASSWORD=coti
```
# Arquivos modelos gerados
## Escritor.php
```php=
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\Artigo;
class Escritor extends Model
{
protected $primaryKey = "id";
protected $fillable = [
'id',
'nome',
'email',
'foto'
];
protected $table = 'escritores';
public function artigos()
{
return $this->hasMany(Artigo::class);
}
}
```
## Artigos.php
```php=
<?php
namespace App;
use Illuminate\Database\Eloquent\Model;
use App\Escritor;
class Artigo extends Model
{
//Many to One
protected $primaryKey = "id";
protected $fillable = [
'id',
'titulo',
'conteudo',
'escritor_id'
];
protected $table = 'artigos';
//Muitos para um singular (chamando a classe com hasMany)
public function escritor()
{
return $this->belongsTo(Escritor::class);
}
}
```
# Arquivos gerados para migration
## 2019_09_18_140150_escritores.php
```php=
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class Escritores extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('escritores', function (Blueprint $table) {
$table->increments('id');
$table->string('nome', 50);
$table->string('email', 50)->unique();
$table->string('foto', 255);
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('escritores');
}
}
```
## 2019_09_18_140155_artigos.php
```php=
<?php
use Illuminate\Support\Facades\Schema;
use Illuminate\Database\Schema\Blueprint;
use Illuminate\Database\Migrations\Migration;
class Artigos extends Migration
{
/**
* Run the migrations.
*
* @return void
*/
public function up()
{
Schema::create('artigos', function (Blueprint $table) {
$table->increments('id');
$table->string('titulo', 50);
$table->longText('conteudo');
$table->integer('escritor_id')->unsigned();
$table->foreign('escritor_id')->references('id')->on('escritores');
$table->timestamps();
});
}
/**
* Reverse the migrations.
*
* @return void
*/
public function down()
{
Schema::dropIfExists('artigos');
}
}
```
## Adicionar excessao de csrf em App\Http\Middleware\VerifyCsrfToken.php
Temos que adicionar esta exceção para que seja possível realizar o post via REST.
Para o curso colocamos tudo liberado '*'.
```php=22
protected $except = [
'*'
];
```
# Arquivo controller: ControllerEscritor.php
```php=
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Escritor;
use App\Artigo;
use DB;
class ControllerEscritor extends Controller
{
protected $escritores;
public function __construct(Escritor $escritores)
{
$this->escritores = $escritores;
}
/**
* Display a listing of the resource.
*
* @return \Illuminate\Http\Response
*/
public function index()
{
//Vamos exibir a listagem em JSON
return response()->json(
[
'lista' => $this->escritores->all(),
'message' => 'Dados retornados com sucesso'
], 200
);
}
/**
* Show the form for creating a new resource.
*
* @return \Illuminate\Http\Response
*/
public function create()
{
//
}
/**
* Store a newly created resource in storage.
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function store(Request $request)
{
DB::beginTransaction();
try{
//Vamos verificar se o escritor já existe
$escritor = $this->escritores
->where('email', $request->email)
->first();
if (!isset($escritor)) {
$escritor = new Escritor();
//Solução do Woney usa o método fill ($escritor->fill($request->all()));
$escritor->nome = $request->input("nome");
$escritor->email = $request->input("email");
$escritor->foto = $request->input("foto");
$escritor->save();
}
//return response()->json(['message' => $escritor], 200);
$artigo = new Artigo();
//Solução do Woney usa o método fill ($escritor->fill($request->all()));
$artigo->titulo = $request->input("titulo");
$artigo->conteudo = $request->input("conteudo");
$escritor->artigos()->save($artigo);
DB::commit();
return response()->json(['message' => 'Dados gravados'], 200);
} catch (\Exception $e) {
DB::rollback();
return response()->json(
['message' => 'Erro ao gravar os dados: '.$e->getMessage()]
, 200
);
}
}
/**
* Display the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function show($id)
{
//
}
/**
* Show the form for editing the specified resource.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function edit($id)
{
//
}
/**
* Update the specified resource in storage.
*
* @param \Illuminate\Http\Request $request
* @param int $id
* @return \Illuminate\Http\Response
*/
public function update(Request $request)
{
$escritor = $this->escritores->find($request->input('id'));
if (isset($escritor)) {
$escritor->fill($request->all());
$escritor->save();
$message='Dados atualizados';
} else {
$message = 'Registro não encontrado';
}
return response()->json(['message' => $message], 200);
}
/**
* Remove the specified resource from storage.
*
* @param int $id
* @return \Illuminate\Http\Response
*/
public function delete($id)
{
$escritor = $this->escritores->find($id);
if (isset($escritor)) {
$escritor->delete();
$message = 'Dados apagados';
} else {
$message = 'Registro não encontrado';
}
return response()->json(['message' => $message], 200);
}
}
```
# Arquivo de rotas "web.php"
```php=
<?php
Route::prefix('api')
->middleware('throttle:5,1')
->group(function () {
Route::get('/', 'ControllerEscritor@index')->name('escritor.lista');
Route::get('/{id}', 'ControllerEscritor@show')->name('escritor.show');
Route::post('/', 'ControllerEscritor@store')->name('escritor.create');
Route::put('/', 'ControllerEscritor@update')->name('escritor.update');
Route::delete('/', 'ControllerEscritor@delete')->name('escritor.delete');
});
```
### Exemplos de relacionamentos Laravel.
```php=
// Relacionamento 1 para 1
class Usuario extends Eloquent {
public function conta()
{
return $this->hasOne('Conta');
}
}
class Conta extends Eloquent {
public function usuario()
{
return $this->belongsTo('Usuario');
}
}
// Relacionamento 1 para N
class Estado extends Eloquent {
public function cidades()
{
return $this->hasMany('Cidade');
}
}
class Cidade extends Eloquent {
public function estado()
{
return $this->belongsTo('Estado');
}
}
// Relacionamento N para N
class Pessoa extends Eloquent {
public function cidades()
{
return $this->belongsToMany('Cidade');
}
}
class Cidade extends Eloquent {
public function pessoas()
{
return $this->belongsToMany('Pessoa');
}
}
```