# Symfony

## Liens utiles

[Documentation](https://symfony.com/doc/current/setup.html)
[Résumé](https://github.com/devoreve/lessons/blob/main/cours/php/Symfony.md)

## Installation

[Lien vers la doc](https://symfony.com/doc/current/setup.html)

* Se placer dans le dossier *module4* à l'aide de la commande *cd*
* Taper les commandes suivantes :
  1. composer create-project symfony/skeleton symfony
  2. cd symfony
  3. composer require webapp

## Structure du framework

* vendor : bibliothèque de classes et fonctions
* bin : outils pour le terminal
* translations : traductions du site
* var : fichiers spécifiques (caches et logs)
* assets : outils pour le front
* config : configuration (routes...)
* migrations : fichiers qui vont contenir des requêtes sql pour créer la base de données
* public : fichiers publics (index.php, css/, js/, ...)
* src : code source de l'application (contrôleurs, modèles...)
* template : vues de l'application

## Lancement de l'application web

* Copier/coller le contenu de *src/kernel.php* de l'ide live72 sur votre ide
* Aller sur le fichier *public/index.php* puis faites *run* pour lancer le site web

## Créer une page

[Lien vers la doc](https://symfony.com/doc/current/page_creation.html)

Pour créer une page sur Symfony, il faut suivre le processus suivant :
1. Créer une route
2. Créer un contrôleur (si ce dernier n'existe pas déjà)
3. Créer la méthode dans le contrôleur

### Créer une route

Dans le fichier *config/routes/yaml*, effacer le contenu s'il n'est pas vide puis créer une nouvelle route de la manière suivante :

```yaml
nom_de_la_route:
    path: /url/souhaitée
    controller: App\Controller\NomDuController::nomDeLaMethod
```

### Créer le contrôleur

Dans le dossier *src/Controller/* créer la classe et la méthode indiquées dans le fichier de routes.

```php
namespace App\Controller;

use Symfony\Component\HttpFoundation\Response;

class NomDuController
{
    public function home(): Response
    {
        return new Response('<h1>Accueil</h1>');
    }
}
```

### Créer une vue

Dans un premier temps, il faut faire hériter nos contrôleurs du contrôleur de Symfony ([Lien vers la doc](https://symfony.com/doc/current/controller.html#the-base-controller-class-services)).

Appeler la méthode *render* qui va prendre en paramètre le nom du fichier vue à afficher.

```php
return $this->render('base.html.twig');
```

Mettre à jour le fichier *base.html.twig* comme sur l'ide de la session.

### Mise en pratique

[Lien vers la doc](https://symfony.com/doc/current/setup/web_server_configuration.html)

Créer une page *hello* qui affiche le texte "Hello world" lorsque l'on va sur l'url */index.php/hello* (path: /hello)

## Réécriture d'URL

Pour ne pas afficher "index.php" dans l'url (bien qu'il soit tout de même appelé), il faut passer par ce qu'on appelle de la réécriture d'url. Pour ce faire il utiliser un fichier bien particulier, propre à Apache, qui s'appelle ".htaccess".

Sur Symfony il est possible de le mettre en place avec une ligne de commande : *composer require symfony/apache-pack* (sélectionner "y" à la question posée).

## Exercices

### Liste des articles

* Créer une route */posts* (qui appellera la méthode *index* du *PostController*)
* Créer un contrôleur *PostController* et une méthode *index*
* Dans cette méthode *index*, récupérer tous les articles (titre, contenu, nom de l'utilisateur, nom de la catégorie) de la base de données avec PDO
* Afficher dans un template *users/index.html.twig* la liste de tous les articles
* Créer le lien "Tous les articles" dans la barre du navigation du site
*

### Création d'une classe modèle

* Créer la classe *PostModel* dans le dossier *Model* (le namespace sera App\Model)
* Créer la méthode *findAll* qui renvoie tous les articles de la base de données
* Instancier ce modèle dans la méthode *index* du *PostController* pour récupérer tous les articles


### Détail de l'article

* Créer une route qui s'appellera *posts.show* dont l'url sera */posts/{id}* et appellera la méthode *show* du *PostController*
* Créer la méthode *show* qui récupère l'id dans le paramètre de l'url
* Créer la méthode *find* dans le modèle qui permet de récupérer un article à partir de son id
* Instancier ce modèle dans la méthode *show* du *PostController* pour récupérer l'article dont on veut le détail
* Afficher le titre, contenu, utilisateur, catégorie, date de création de l'article dans un template *users/show.html.twig* 
* Tester en allant sur la page */posts/le numéro d'un article existant*
* 

### Pré-requis

* Lancer les 2 commandes d'installation pour ajouter doctrine - [voir la doc](https://symfony.com/doc/current/doctrine.html#installing-doctrine)
* Commenter les routes *posts.index* et *posts.show* dans le fichier de routing
* Commenter la ligne DATABASE_URL dans votre fichier *.env*

### Configuration

* Ajouter la ligne suivante dans votre fichier *.env* (ne créer pas cette base de données)
```
DATABASE_URL="mysql://{votre nom utilisateur}:{votre mot de passe}@db.3wa.io:3306/{votre nom utilisateur}_symfony?serverVersion=5.7&charset=utf8mb4"
```
* Taper la commande dans le terminal (vérifiez que vous êtes dans le bon dossier, sinon déplacez-vous avec cd) *php bin/console doctrine:database:create*

Après toutes ces opérations, la base de données {votre nom d'utilisateur}_symfony doit être créée dans phpmyadmin.

### Création de tables et d'entités

#### Créer la table "product"

[Lien vers la doc](https://symfony.com/doc/current/doctrine.html#creating-an-entity-class)

* Créer une entité *Product*
* Cette entité a 2 propriétés non nulles : name (string, 255 caractères) et price (integer)
* Quand il n'y a plus de propriétés à ajouter, taper simplement "entrée"
* Un fichier Entity/Product.php a été créé
* Créer la migration *php bin/console make:migration*
* Lancer la migration *php bin/console doctrine:migrations:migrate*

Si tout s'est bien passé, la table *product* a été créée dans la base de données.