https://github.com/adminkit/adminkit
https://www.templateshub.net/template/FlixGo-Online-Movies-Template
Foi usado scaffold bootstrap. Basicamente foram implementadas coisas automaticamente que correspondem ao auth de users e páginas base:
https://laravel.com/docs/7.x/authentication#authentication-quickstart
https://hdtuto.com/article/laravel-8-bootstrap-auth-example-step-by-step
Sempre que se criarem controllers usamos:
php artisan make:controller NomeController --resource
--resource vai criar um controlador com metodos default
https://laravel.com/docs/8.x/controllers#actions-handled-by-resource-controller
Para usarmos os valores nas Rotas usamos:
Route::resource('Url', NomeController::class)
A aplicação vai traduzir as strings automaticamente para português porque no ficheiro config/app.php colocamos o locale a pt_PT. Ao colocamos esse parametro o Laravel vai à pasta resources/lang/pt_PT ver as traduções.
Para usar traducoes que estejam dentro de resources/lang/pt_PT.json podemos usar:
dentro de php:
echo __('Email');
numa view:
{{ __('Register') }}
Uma boa pratica é dar nome às rotas:
https://laravel.com/docs/8.x/routing#named-routes
https://laravel.com/docs/8.x/routing#generating-urls-to-named-routes
Para gerarmos rotas dinamicamente na vista usamos:
route('nome_dado_à_rota')
Para vermos se estamos numa rota com um certo nome usamos:
Route::currentRouteName() == 'nome_dado_à_rota'
php artisan make:model NomeModel
- Para ser mais facil fazer pesquisas à base de dados e organizar os Models do projeto devemos sempre especificar as ligações que temos na base de dadosno codigo dos Modelos ORM, 1:1, 1:n, n:m:;
belongsTo fica sempre no Modelo em que a tabela tem a foreign_key;
Quando se faz uma ligação temos de alterar os dois Modelos ORM que têm ligação entre si. Exemplo:
class User extends Model
{
// A user may have or not a phone
public function phone()
{
return $this->hasOne(Phone::class);
}
}
class Phone extends Model
{
// A phone always belongs to a user
public function user()
{
return $this->belongsTo(User::class);
}
}
// vai buscar o numero de telefone do user com id 123
$phone = User::find(123)->phone;
$phone->number = '99293283';
// vai buscar o user do numero de telemovel com id 324
$user = Phone::find(324)->user;
$str = "I'm calling " . $user->name;
ir buscar um filme que tenha pelo menos uma sessao:
$sessoes = Filme::has('sessoes')->first();
ir buscar todas as sessoes do filme que tem pelo menos uma sessao:
$sessoes = Filme::has('sessoes')->first()->sessoes;
caso a chave primaria de uma tabela seja diferente de id temos de fazer:
protected $primaryKey = "your_key_name";
Servem para executar ou verificar coisas antes do Laravel chamar o controlador.
Por exemplo, podemos criar middlewares para verificar se um user é admin ou para criar logs das ações do users, etc.
php artisan make:middleware IsAdmin
depois dentro do ficheiro gerado dentro de App\Http\Middleware existe uma função handle, e é ai onde fazemos a nossa logica.
chamamos o Closure $next quando a operação é permitida ou correu com sucesso.
Para ser possivel usar o middleware temos de o registar no Kernel, App\Http\Kernel.php.
protected $routeMiddleware = [
. . . ,
'admin' => \App\Http\Middleware\IsAdmin::class,
];
usar num controller:
__construct(){
$this->middleware('isAdmin');
}
usar nas rotas:
route...->middleware('isAdmin');
Estes mecanismos são usados para ajudar na autorização de processos de sistema.
Policies -> são usadas para verificar se um user tem autorização para ver recursos por exmeplo bilhetes, sessões, ficheiros, etc.
php artisan make:policy BilhetePolicy
Criar policies com operacoes basicas de CRUD para um model:
php artisan make:policy BilhetePolicy --model=Bilhete
Adicionar a policy:
App/Providers/AuthServiceProvider.php
protected $policies = [
User::class => UserPolicy::class,
]
Gates -> são usados para verificar se um user tem autorizações globais e de rotas por exemplo.
Para criar temos de ir ao ficheiro
App\Providers\AuthServiceProvider.php
e dentro da funcao boot meter
Gate::define('access-dashboard', function ($user) {
// Only "admin" users can "access-dashboard"
return $user->admin;
});
Podemos colocar dentro de controllers:
$this->authorize('view', $bilhete);
Podemos usar dentro de middlewares:
route...->middleware('can:view,account');
Podemos usar dentro de views:
@can('view, bilhete')
@endcan
cannot('view, bilhete')
@endcannot
soft delete consiste em alterar a coluna deleted_at na tabela em vez de eliminar mesmo a linha da tabela
Os modelos que tenham deleted_at têm de use SoftDeletes;
Verificar se um registo foi soft Deleted:
$user->trashed()
sempre que duas operacoes na DB só fazem sentido serem feitas se outra foi feita usados transactions.
Por exemplo:
Quando damos softDelete do cliente, temos de dar softDelete do user tambem
try {
DB::beginTransaction();
$createdUser = User::create([
'name' => $data['name'],
'email' => $data['email'],
'password' => Hash::make($data['password']),
]);
Cliente::create([
'id' => $createdUser->id,
]);
DB::commit();
return $createdUser;
} catch (\PDOException $e) {
DB::rollBack();
return null;
}
Antes de inserirmos alguma coisa na DB temos de fazer as validacoes necessarias.
É possivel tambem restringir valores passados no Url
https://laravel.com/docs/8.x/routing#parameters-regular-expression-constraints
https://github.com/SimpleSoftwareIO/simple-qrcode
https://github.com/barryvdh/laravel-dompdf
https://github.com/schmich/instascan
É preciso ativar HTTPS no laragon para ser possivel utilizar a camara nos browsers (provavelmente por questoes de seguranca).
Na criacao do bilhete temos de meter url em https, porque se tivessemos com https ativo e estivessemos a dar scan de um url http, iria haver conflito por estamos a fazer pedido num site https para um sitio http.
-
Quando for para validar informação enviada no form devemos usar sempre os
-
Para enviar erros para uma vista podemos usar:
->with('error', 'Mesangem');
-
sempre que usarmos forms onde o user tem de inserir dados temos de usar o old();
-
colocar sempre @csrf nos forms;
-
quando queremos usar outros metodos para além do GET e POST devemos especificar o metodo com @method('DELETE');
-
Rotas de admin têm prefixo de 'admin.';
-
Rotas de admin têm de estar dentro de middleware 'isAdmin'
-
Maior parte dos controllers têm de ter o middleware 'auth' no construtor;
-
Quando queremos verificar alguma policy ou gate devemos meter isto antes de fazer qualquer operacao num controller:
$this->authorize('delete', $user);
ou podemos meter na route um middleware can
dentro das views devemos usar sempre @can e @cannot para so mostrar coisas que os utilizadores podem fazer.
Dentro de loops foreach nas views conseguimos saber se estamos no primeiro loop ou ultimo atraves de $loop->first, ou last;
-
Sempre que validamos alguma coisa numa policy ou Gate devemos fazer desta forma:
if ($user->id == $userToDelete->id) { return $this->deny(__("A User cannot block or unlock himself")); } if (!$user->isAdmin()) { return $this->deny(__("Just the admins can block or unlock users")); } return true;
ou seja tentamos sempre mostrar mensagens de erro consoante as verificações e no fum damos return de true.
é possivel ir buscar um valor dinamico da rota:
por exemplo esta para esta rota users/{user} podemos ir buscar o valor {user} atraves de:
$this->route('user')
-
Laravel UI instalada.
-
Para ser possivel utilizar CORS quando se usa ajax para alterar o estado de um bilhete depois de se ler o qrcode tive de ir a config/cors.php e colocar a path que queria em que os CORS fossem permitidos. https://laravel.com/docs/9.x/routing#cors
-
Gate de entrar no dashboard criada;
-
Email de recuperar senha a ser enviado
-
Saber quais filmes têm sessões futuras:
Filme::with('sessoes')->whereRelation('sessoes', 'data', now()->format('Y-m-d'))->get();
- Rule Payment: serve para verificar os pagamentos;
-
Um utilizador pode adicionar um lugar ao carrinho sem ter previamente selecionado a sessao.
-
Uma sessao unica só é adicionada uma vez ao carrinho. Se o utilizador quiser comprar varios bilhetes de uma sessao, o que vai ter de fazer é selecionar varios lugares quando tiver no checkout;
O carrinho vai ter um array com sessoes e outro array com lugares. Sempre que o utilizador for fazer checkout o que tem de fazer é "transformar" uma sessao em x bilhetes.
-
Um user só pode adicionar uma sessao ao carrinho se ela nao tiver começado até há 5 minutos
-
Podemos permitir que uma sala seja alterada mesmo tendo sessoes anteriores se quando alterarmos uma sala criarmos uma copia dessa sala.
-
Ao criar uma sala podemos especificar o numero de lugares que a sala vai ter;
-
Ao editar uma sala, se aumentarmos o numero de lugares são criados mais lugares. Se diminuirmos o numero de lugares, fazemos soft delete dos lugares a mais, começando a eliminar do fim.
-
Cada fila de lugares é composta por 15 lugares no máximo.
-
Só salas sem sessoes futuras é que podem ser eliminadas.
-
Só salas sem sessoes é que podem ser editadas.
-
Número de filas de uma sala não pode ser maior que o número de lugares;
- Só se podem apagar filmes sem sessoes associadas;
- IsAdmin;
- UserBlocked; (serve para proibir users de entrarem na web); Este middleware foi colocado no Kernel no grupo web porque vai ser aplicado sempre que um user tentar aceder ao website;
- ChangePasswordController (Usado para alterar a password do user);
-
salas 1:n sessoes:
-
filmes 1:n sessoes;
-
sessoes 1:n bilhetes;
-
salas 1:n lugares;
-
bilhetes n:1 lugares;
-
generos 1:n filmes;
-
clientes 1:n bilhetes;
-
clientes 1:n recibos;
-
clientes 1:1 users;
-
recibos 1:n bilhetes;
-
Utilizadores não autenticados só podem tentar fazer login e registar-se. Depois de ser registarem um email de verificação tem de ser enviado;
-
Quando uma pessoa cria conta tem de ser criado um cliente;
-
Só clientes têm acesso ao seu perfil;
-
Os admin podem ver os detalhes do perfil de qualquer user no dashboard excepto clientes; (UserPolicy->view())
-
Os funcionarios não podem ver o seu perfil no dashboard nem no front; (UserPolicy->view(), ClientePolicy-view())
-
Qualquer user pode alterar a sua password;
-
Um administrador pode bloquear/desbloquear utilizador/cliente sem ser a ele proprio;
-
Um administrador pode eliminar utilizador/cliente sem ser a ele proprio;
-
Um utilizador depois de ser bloqueado não pode iniciar sessão;
-
Um administrador pode criar utilizadores e clientes;
-
Um administrador pode consultar filtrar, alterar utilizadores;
-
Um administrador pode consultar e filtrar a lista de clientes
-
Um administrador não pode aceder ao perfil de um cliente;
-
Edições da foto dos utilizadores quando sao criados e editados;
-
Um administrador só pode mudar o tipo de um user para admin ou funcionario (extra)
-
Qualquer utilizador pode ver quais os filmes em exibição, e as sessos dos mesmos;
-
Pesquisar (filtrar) filmes;
-
Adicionar ou remover lugares para qualquer sesssao (ver especificacoes no enunciado);
-
Um user só pode adicionar uma sessao ao carrinho se ela nao tiver começado até há 5 minutos;
-
Qualquer utilizador pode adicionar coisas ao carrinho;
-
Só clientes registados é que podem finalizar uma compra;
-
Se uma compra for feita com sucesso a aplicação cria um recibo e gera os bilhetes relativos à compra e limpa o carrinho de compras;
-
Se der erro na compra o carrinho fica como está e o cliente tem de ser avisado;
-
Apagar ou adicionar lugares ao carrinho;
-
Limpar o carrinho de compras por completo;
-
Cada lugar está associado a um bilhete unico numa sessao, ou a zero bilhetes quando o lugar ainda esta vazio;
-
Quando um utilizador adicionar um bilhete ao carrinho, tem de escolher o lugar que quer;
-
Registar o recibo após o pagamento da compra;
-
Enviar o recibo automaticamente por email ao cliente;
-
Recibo tem de estar sempre disponivel em HTML (POLICIES);
-
Gerar recibo em PDF e armazenar permanentemente (POLICIES);
-
Sempre que é feita a compra os bilhetes são gerados e sao enviados no mesmo email que o recibo;
-
Os bilhetes têm de estar sempre acessiceis em formato HTML (POLICIES);
-
Sempre que o utilizador clicar na opção de fazer download do bilhete, um PDF dinamico é gerado e é feito o download do mesmo, depois disso o PDF não é armazenado;
-
Os clientes devem ter acesso ao histórico de todos os recibos, sendo que podem ver o recibo e os bilhetes em HTML ou descarregra em PDF;
-
Os clientes têm acesso a todos os bilhetes válidos (os que ainda nao foram usados);
-
Os funcionarios têm acesso a uma página em que escolherm qual a sessão que estão a controlar;
-
Depois de escolherem a sessao que estao a controlar o funcionario pode ter acesso a um leitor de qrcode ou alterar o estado do bilhete manualmente;
-
Se o bilhete for invalido a aplicacao avisa o funcionario.
-
Se o bilhete for valido a aplicacao deve mostar os detalhes do bilhete e informa que o bilhete é valido.
-
O funcionario pode ainda clicar no cliente e ver as informações do mesmo, foto, etc;
-
O funcionario deve ter um botao na aplicacao que ao clicar confirma o uso do bilhete, colocando o bilhete invalido;
-
Os administradores podem gerir filmes, sessoes e outros valores que estao no enunciado.
-
Os administradores podem gerir salas e lugares de salas;
-
O admin pode criar, alterar ou apagar (soft delete) as salas.
-
Para cada sala tem de ser possivel definir os lugares que a sala tem.
-
O admin pode criar, alterar e apagar filmes sem sessao e sessoes.
-
Para cada filme deve ser possivel fazer upload do cartaz:
-
As sessoes so podem ser alteradas ou removidas se ainda nao tiverem nenhum bilhete associado;
-
Os admin podem alterar as configurações do preco de bilhete e iva no dashboard;