Skip to content

Commit

Permalink
Overall revision. Close Notes for LBAW 23/24 edition
Browse files Browse the repository at this point in the history
  • Loading branch information
Fabio-A-Sa committed Oct 29, 2023
1 parent e8b2d97 commit c8c0d46
Show file tree
Hide file tree
Showing 3 changed files with 38 additions and 63 deletions.
27 changes: 1 addition & 26 deletions Notes/4 - Web Applications and Frameworks.md
Original file line number Diff line number Diff line change
Expand Up @@ -120,31 +120,6 @@ Uma forma simples de apresentar a API de um servidor:
- Ações como POST, GET, DELETE, PUT;
- Retornos JSON ou HTML;

```api
openapi: 3.0.0
info:
title: Sample API
description: Optional multiline or single-line description in [CommonMark](http://commonmark.org/help/) or HTML.
version: 0.1.9
servers:
- url: http://api.example.com/v1
description: Optional server description, e.g. Main (production) server
paths:
/users:
get:
summary: Returns a list of users.
description: Optional extended description in CommonMark or HTML.
responses:
'200': # status code
description: A JSON array of user names
content:
application/json:
schema:
type: array
items:
type: string
```

No documento `.yaml` deve existir uma parte dedicada aos metadados, à documentação externa (no nosso caso, um link de retorno à wiki), aos servidores ligados à API, a definição de tags para melhor representar os dados redundantes, paths da API. <br>
Exemplo da página de login:

Expand All @@ -168,7 +143,7 @@ Exemplo da página de login:

responses:
'200':
description: 'Success. Returns some HTML text containing notification context (post, comment, subcomment) information'
description: 'Success. Returns some HTML text containing notification context'
'403':
description: 'Forbiden action. You need to be logged in first'

Expand Down
56 changes: 28 additions & 28 deletions Notes/5 - Laravel.md
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,8 @@ $ php artisan make:model <MODEL_NAME>
Conteúdo de `app/Models/Post.php` após executar o comando com MODEL_NAME=Post:

```php
class Post extends Model
{
class Post extends Model {

public $timestamps = false; // A
protected $table = 'post'; // B

Expand Down Expand Up @@ -80,7 +80,7 @@ public function likes() {
4. Um Post pode pertencer a um Grupo. O método seguinte retorna o grupo em questão ou NULL se o atributo `group_id` for nulo:

```php
public function group(){
public function group() {
return $this->belongsTo(Group::class);
}
```
Expand Down Expand Up @@ -121,7 +121,7 @@ Exemplos de estrutura:

No exemplo apresentado, uma forma de estruturar os templates pode ser esta:

```bash
```note
$ tree .
.
|____layouts
Expand All @@ -139,7 +139,7 @@ $ tree .

`layouts/app.blade.php`:

```php
```html
<!DOCTYPE html>
<html lang="{{ app()->getLocale() }}">
<head>
Expand All @@ -164,7 +164,7 @@ $ tree .

`pages/home.blade.php`:

```php
```html
@extends('layouts.app') <!-- Estende o layout principal -->

@section('content') <!-- Define o que é o `content` da página -->
Expand All @@ -182,7 +182,7 @@ $ tree .

`pages/profile.blade.php`:

```php
```html
@extends('layouts.app') <!-- Estende o layout principal -->

@section('content') <!-- Define o que é o `content` da página -->
Expand All @@ -201,23 +201,23 @@ $ tree .

`partials/header.blade.php`:

```php
```html
<header>
<h1>LBAW Tutorial 02 - File Storage</h1>
</header>
```

`partials/footer.blade.php`:

```php
```html
<footer>
<p>LBAW @ 2023</p>
</footer>
```

`partials/profile.blade.php`:

```php
```html
<a href="profiles/{{ $id }}"> <!-- Usa o ID injectado para criar o link dinamicamente... -->
<article class="profile">
<h3>Profile {{ $id }}</h3> <!-- ... e o próprio título -->
Expand All @@ -228,7 +228,7 @@ $ tree .

`partials/feedback.blade.php`:

```php
```html
<!-- Só escreve alguma coisa se ocorreu um erro ou um sucesso na ação anterior -->
@if(session('error'))
<h3 class="error">{{ session('error') }}</h3>
Expand All @@ -239,7 +239,7 @@ $ tree .

`partials/form.blade.php`:

```php
```html
<form method="POST" action="/file/upload" enctype="multipart/form-data">

<!-- Nunca esquecer de enviar também o token CSRF em qualquer formulário -->
Expand Down Expand Up @@ -290,14 +290,14 @@ Route::controller(UserController::class)->group(function () {

As rotas podem ser organizadas segundo cada controlador como está no exemplo. A definição das rotas segue uma sintaxe rígida:

```
```php
Route::<TYPE>(<PATH>, <METHOD>);
```

Onde:

- **TYPE** pode ser do tipo get(), post(), delete(), put();
- **PATH** é parte do URL do site que ativa o request, por exemplo "/post/create" mapeava "www.lbaw2255.fe.up.pt/post/create" na OnlyFEUP;
- **PATH** é parte do URL do site que ativa o request, por exemplo "/post/create" mapeava www.lbaw2255.lbaw.fe.up.pt/post/create na OnlyFEUP;
- **METHOD** o método implementado na classe do controlador que irá tratar do request;

Para visualização de páginas, como as páginas estáticas ou o perfil do utilizador, o controlador correspondente recebe um pedido "GET" e retorna uma página HTML. Nas ações relacionadas com a manipulação da base de dados normalmente usamos pedidos "POST", "PUT" ou "DELETE".
Expand Down Expand Up @@ -330,10 +330,10 @@ Route::controller(PostController::class)->group(function () {
Tem o método create() implementado da seguinte forma no ficheiro `app/Http/Controllers/PostController.php`:

```php
class PostController extends Controller
{
public function create(Request $request)
{
class PostController extends Controller {

public function create(Request $request) {

// A
$this->authorize('create', Post::class);

Expand Down Expand Up @@ -373,8 +373,8 @@ php artisan make:policy <MODEL_NAME>Policy --model=<MODEL_NAME>
Se não for indicado o modelo da policy (--model=<MODEL>) é necessário associá-los manualmente. Para isso, dentro do ficheiro `app/Providers/AuthServiceProvider.php`:

```php
class AuthServiceProvider extends ServiceProvider
{
class AuthServiceProvider extends ServiceProvider {

protected $policies = [
Post::class => PostPolicy::class,
//...
Expand All @@ -385,8 +385,8 @@ class AuthServiceProvider extends ServiceProvider
Os ficheiros das policies serão armazenados em `app/Policies`. Exemplo do conteúdo de `app/Policies/PostPolicy.php`:

```php
class PostPolicy
{
class PostPolicy {

use HandlesAuthorization;

public function delete(User $user, Post $post) {
Expand All @@ -401,8 +401,8 @@ class PostPolicy
Cada método pode ter vários argumentos. A Policy de exemplo pode ser invocada com esta chamada no controller de Post:

```php
class PostController extends Controller
{
class PostController extends Controller {

public function delete(Request $request) {
$post = Post::find($request->id); // encontra o post a ser eliminado
$this->authorize('delete', $post); // chama o método "delete" de PostPolicy
Expand Down Expand Up @@ -443,7 +443,6 @@ $ php artisan view:make errors.<N>

```php
public function delete(Request $request) {

try {
$post = Post::find($request->id);
$this->authorize('delete', $post);
Expand Down Expand Up @@ -594,9 +593,10 @@ public function visiblePosts() {
->whereColumn('post.group_id','member.group_id');

// Merge
return $own->union($noGroups)->union($fromGroups)
->orderBy('date','desc');
}
return $own->union($noGroups)
->union($fromGroups)
->orderBy('date','desc');
}
```

## Integrations
Expand Down
18 changes: 9 additions & 9 deletions Notes/6 - Frontend.md
Original file line number Diff line number Diff line change
Expand Up @@ -57,7 +57,7 @@ function encodeForAjax(data) {
return Object.keys(data).map(function(k){
return encodeURIComponent(k) + '=' + encodeURIComponent(data[k])
}).join('&');
}
}

function sendAjaxRequest(method, url, data) {
let request = new XMLHttpRequest();
Expand Down Expand Up @@ -187,21 +187,21 @@ Por isso o HTML de cada secção teve de ser gerado pelo servidor e retornado pe

```html
@forelse ($users as $user)
<article class="search-page-card" id="user{{$user->id}}">
<img class="user-profile-pic" src="{{$user->media()}}" alt="user profile picture">
<a href="../user/{{$user->id}}">{{ $user->name }}</a>
<h3 class="search-user-card-username">&#64;{{$user->username}}</h3>
<article class="search-page-card" id="user{{ $user->id }}">
<img class="user-profile-pic" src="{{ $user->media() }}">
<a href="../user/{{ $user->id }}">{{ $user->name }}</a>
<h3 class="search-user-card-username">&#64;{{ $user->username }}</h3>
</article>
@empty
<h2 class="no_results">
No results found
</h2>
<h2 class="no_results">
No results found
</h2>
@endforelse
```

Note-se que caso não existam objectos também há HTML retornado mas com uma mensagem. É sempre importante dar feedback ao utilizador.

E agora só falta o javascript. Queríamos que que sempre que o utilizador fizesse input de algo na search bar, a função `search` fosse ativada e que invocasse as funções da API. No final é só injectar o HTML retornado pela API em cada secção:
E agora só falta o JavaScript. Queríamos que que sempre que o utilizador fizesse input de algo na search bar, a função `search` fosse ativada e que invocasse as funções da API. No final é só injectar o HTML retornado pela API em cada secção:

```js
async function getAPIResult(type, search) {
Expand Down

0 comments on commit c8c0d46

Please sign in to comment.