Skip to content
Snippets Groups Projects
Commit 6aa4d6a6 authored by Luc Burckel's avatar Luc Burckel
Browse files

Remise à 0

parents 62ef66f6 caf97616
Branches
No related merge requests found
Showing
with 1233 additions and 0 deletions
Laravel
=======
**Préférez une installation sur votre ordinateur... si vous disposez d'un OS digne de ce nom ;).**
Installation de composer sur votre ordi personnel
-------------------------------------------------
```
$ sudo apt install composer
```
Installation de Laravel
-----------------------
**Attention : ce qui suit est valable sur votre ordinateur personnel ET SUR WEBETU UNIQUEMENT.**
1. Initialisation d'un projet `[NOM_DU_PROJET]` :
```
$ composer create-project --prefer-dist laravel/laravel [NOM_DU_PROJET]
```
2. Lancement d'un serveur local :
```
$ cd [NOM_DU_PROJET]
$ php artisan serve
Starting Laravel development server: http://127.0.0.1:8000
```
Si tout s'est bien passé, votre navigateur affiche une page blanche avec le contenu suivant avec l'URL `http://127.0.0.1:8000` :
```
Laravel
|---------------|-------------------|
| Documentation | Laracasts |
|---------------|-------------------|
| Laravel News | Vibrant Ecosystem |
|---------------|-------------------|
```
JAC - Just Another CMS
======================
Vous devez développer une application de publication d'articles, c'est-à-dire un mini-[CMS](https://fr.wikipedia.org/wiki/Syst%C3%A8me_de_gestion_de_contenu).
Article
-------
Un **article** est constitué de ces éléments :
- un identifiant,
- un auteur,
- un titre,
- une phrase d'accroche,
- un contenu textuel,
- un statut indiquant s'il est publié ou non,
- la date de la dernière publication,
- la date de la dernière modification.
Un **résumé d'un article** sera constitué de son titre, sa date de publication et sa phrase d'accroche.
Partie publique
---------------
La partie publique doit proposer les 3 vues principales :
- la page principale avec **le résumé** des 3 derniers articles publiés,
- un formulaire de création de compte "auteur",
- un formulaire d'authentification comme auteur.
Sur chaque vue, un menu doit permettre de naviguer vers les autres vues.
Sur la page principale, un clic sur le titre d'un article doit mener à la page de l'intégralité de l'article.
Compte "Auteur"
---------------
Un utilisateur authentifié, i.e; un auteur, doit pouvoir :
- changer son mot de passe
- supprimer son compte : tous ses articles sont supprimés
- se déconnecter
mais aussi :
- créer un nouvel article
- voir la liste de ses articles, publiés et non publiés
- modifier un article qu'il a lui-même créé
- publier/dé-publier un article
Un article non publié n'est donc visible que pour son auteur s'il est authentifié.
Conseils
--------
- Nous vous recommandons de réaliser ce projet en partant de la base de code obtenue à l'issue du TP n°8.
- Fixez-vous des objectifs progressifs : il n'est pas nécessaire que votre application soit entièrement fonctionnelle pendant son développement.
- Ne passez pas trop de temps sur le CSS : gardez à l'esprit que l'aspect esthétique ne sera pas évalué lors du TP noté.
Bonus pour les plus rapides
---------------------------
Ça tient en 5 mots mais cela devrait largement vous occuper : ajoutez la catégorisation des articles.
Cela signifie qu'un article peut appartenir à une ou plusieurs catégories, modifiables à tout instant. Il faudra donc ajouter une vue publique permettant d'afficher les articles d'une catégorie donnée.
TP5.md 0 → 100644
TP5 - Prise en main de Laravel
==============================
Objectif
--------
Intégrer l'application d'authentification au framework Laravel.
Vous pouvez vous baser au choix :
- sur vos propres sources résultant du TP4
- sur la proposition du répertoire [correction/TP4](correction/TP4)
Notez que le but de ce TP est d'obtenir une application fonctionnelle **mais qui ne respectera pas encore le découpage MVC**.
Les TPs suivants permettront de séparer progressivement les parties Modèle, Vue et Contrôleur en utilisant à bon escient les fonctionnalités offertes par Laravel.
Exercice 1 : Installation
-------------------------
Suivez les indications données dans [LARAVEL-installation.md](LARAVEL-Installation.md).
**Attention : `composer` n'est installé que sur webetu, pas sur troglo.**
Exercice 2 : Préparation des vues
---------------------------------
1. Copiez les fichiers suivants du TP4 dans `resources/views/` :
- `account.php`
- `adduser.php`
- `authenticate.php`
- `changepassword.php`
- `deleteuser.php`
- `formpassword.php`
- `signin.php`
- `signout.php`
- `signup.php`
1. Dans `routes/web.php` :
- Écrivez les routes GET et POST pour les fichiers ci-dessus (ne pas utiliser `Route::view`)
- Faites en sorte qu'une requête vers la racine du site propose la vue `signin.php`
- Testez toutes les routes GET. Regardez ce qu'il se passe lorsqu'on demande une route qui n'a pas été prévue dans `routes/web.php`
1. Dans chaque fichier, remplacez toutes les références à des fichiers PHP par des références à des routes.
1. Dans le fichier `app/Http/Kernel.php`, commenter les lignes qui font référence au middleware `VerifyCsrfToken`.
Exercice 3 : Modèle MyUser et PDO
---------------------------------
1. Copiez le fichier de BDD sqlite `tp4.db` du TP4 dans `database/tp5.db`.
1. Dans le fichier `.env`, modifiez les champs `DB_CONNECTION` et `DB_DATABASE` avec les informations de l'ancien fichier `bdd.php` et en suivant [cette documentation](https://laravel.com/docs/8.x/database).
1. Copiez le fichier `models/User.php` du TP4 dans le répertoire `app/Models` de votre application et renommez-le `MyUser.php`. **Attention, n'écrasez pas le fichier `User.php` existant déjà dans ce répertoire.**
1. Dans `MyUser.php` :
- déclarez le namespace `App\Models`
- remplacez le nom de la classe par `MyUser`
- remplacer les `User::USER_TABLE` par `MyUser::USER_TABLE`
- remplacer tous les `MyPDO::pdo()` par `DB::connection()->getPdo()`
- ajouter en entête les deux `use` suivants :
```php
use Illuminate\Support\Facades\DB;
use PDO;
```
1. Dans chacun des fichiers `adduser.php`, `authenticate.php`, `changepassword.php`, `deleteuser.php` et `signout.php` :
- remplacer les `require_once('models/User');` par des `use App\Models\MyUser;`
- remplacer les `new User` par des `new MyUser`
**À ce stade, l'application devrait être entièrement fonctionnelle. Solutionner les problèmes avant de passer à la suite.**
> Note : il est important d'avoir des `exit()` après chaque `header("Location: xxx")`... même si c'est la dernière instruction du fichier.
Exercice 4 : Le grand nettoyage
-------------------------------
1. Supprimer toutes les vérifications de `REQUEST_METHOD` de tous vos fichiers : c'est maintenant le routage qui le gère.
1. Supprimer tous les `session_start()` de tous vos fichiers.
1. Dans `routes/web.php`, mettre toutes les routes dans un groupe. Dans la fonction qui contient les routes de ce groupe, ajouter en première instruction un `session_start()`.
1. Dans `routes/web.php`, remplacer l'appel à la vue `signout` par le code du fichier `signout.php` et remplacer l'appel à `header()` par un appel à la méthode `redirect()` de Laravel. Supprimer `signout.php`.
1. Dans `routes/web.php`, placer les routes `changepassword`, `deleteuser`, `formpassword`, `account` et `signout` dans un groupe préfixé par `admin`. Ajouter `admin/` à ces routes dans tous les `header()` de tous vos fichiers de vues.
1. Ajouter au début de la fonction du groupe `admin` la vérification de l'existence de la variable de session `user`. Si elle n'existe pas, faire une redirection vers `signin` en utilisant `redirect` de Laravel.
**Vérifier que tout fonctionne.**
TP6.md 0 → 100644
TP6 - Blade, le moteur de vues
==============================
Objectif
--------
Dans le TP précédent, nous avons migrer notre application dans le framework Laravel pour obtenir une version fonctionnelle mais qui ne respecte ni les principes de Laravel, ni les principes MVC.
Dans ce TP6, l'objectif est de mettre en place la partie "Vue" grâce à Blade.
[Toute la documentation officielle se trouve ici](https://laravel.com/docs/8.x/blade)
Exercice 1 : Le layout principal
--------------------------------
1. Dans `resources/views`, créez un répertoire `shared` avec un fichier `message.blade.php` qui :
- vérifie que la variable `$message` existe et n'est pas nulle
- si c'est le cas, l'affiche
1. Dans `resources/views`, créez un répertoire `layouts` avec un fichier `app.blade.php` contenant la structure HTML de base et les directives blade suivantes :
- un élément `<title>` paramétrable avec `@yield`
- une `@section` pour le contenu principal du corps HTML contenant elle-même déjà un élément `<h1>` identique au `<title>`
- un `@include` du fichier de la question précédente
Exercice 2 : Les héritiers
--------------------------
Appliquer chaque étape aux quatre fichiers suivants :
- `formpassword.php`
- `signin.php`
- `signup.php`
- `account.php`
1. Renommer le fichier en `.blade.php`.
1. Adapter le fichier en le faisant étendre `app.blade.php `.
Exercice 3 : Les messages comme paramètres
------------------------------------------
À ce stade tout devrait fonctionner excepté les messages qui ne s'affichent plus.
Pour remédier à cela, dans `routes/web.php`, pour chaque directives `view(...)` qui pointent vers l'un des 4 fichier de l'exercice 2, ajoutez en paramètre une variable nommée `message`. Elle a pour valeur le contenu de la variable de session "message" ou `null` si cette dernière n'existe pas.
> Conseil n°1 : Utilisez le second argument des directives `view(...)`.<br>
> Conseil n°2 : Regardez la syntaxe [`??`](https://www.php.net/manual/fr/migration70.new-features.php) de PHP.
Exercice 4 : Finitions
----------------------
1. Afin de rendre les vues totalement indépendantes des sessions, faites-en sorte que la variable de session `user` affichée dans `account.blade.php` soit transmise à la vue dans une variable `$user` depuis `routes/web.php`.
1. Maintenant que Blade est utilisé, nous pouvons remettre en place la vérification CSRF des formulaires. Ajouter la directive requise aux formulaires Blade (voir [CSRF Protection](https://laravel.com/docs/6.x/csrf)) et dé-commenter la ligne correspondante dans `app/Http/Kernel.php`.
TP7.md 0 → 100644
TP7 - Controller et Middleware
==============================
Objectif
--------
Dans le TP précédent, nous avons mis en place la partie Vue du MVC avec Blade.
Dans ce TP7, nous allons mettre en place la partie Contrôleur du MVC, en créant un contrôleur d'utilisateur auquel nous ferons appel via le contrôleur de routage.
Exercice 1 : Un Middleware d'authentification
---------------------------------------------
> Si besoin, la documentation est ici : [https://laravel.com/docs/8.x/middleware](https://laravel.com/docs/8.x/middleware)
1. Créez le middleware `EnsureMyUserIsAuthenticated` grâce à **artisan** avec la commande suivante (il faut être à la racine de votre projet Laravel) :
```sh
$ php artisan make:middleware EnsureMyUserIsAuthenticated
```
1. Déplacez les instructions de vérification de la variable de session `user` du fichier `routes/web.php` vers la fonction `handle(...)` de `EnsureMyUserIsAuthenticated.php`.
1. Dans `app/Http/Kernel.php`, ajoutez le middleware comme **middleware de routes**, avec pour nom `auth.myuser`.
1. Dans `routes/web.php`, ajoutez le middleware au groupe de routes préfixé `admin`.
Exercice 2 : Un Contrôleur pour les gouverner tous
--------------------------------------------------
1. Créez un contrôleur `UserController` avec la commande suivante (il faut être à la racine du projet Laravel) :
```sh
$ php artisan make:controller UserController
```
Exercice 3 : Le contrôle dans ses plus simples éléments
-------------------------------------------------------
1. Dans `UserController.php`, créez la fonction suivante :
```php
/**
* Show the signin page
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function signin( Request $request )
```
et copiez-y le code de la fonction associée à la route `signin` de `routes/web.php`.
1. Modifiez les routes `/` et `signin` de `routes/web.php` pour qu'elles appellent la méthode `signin` du contrôleur `UserController`.
1. Appliquez les deux étapes précédentes aux routes `signup`, `formpassword`, `signout` et `account`.
Exercice 4 : Le contrôle de l'authentification
----------------------------------------------
1. Dans `UserController.php`, créez une fonction `authenticate` sur le même modèle que celles de l'exercice précédent.
1. Copiez le code du fichier `resources/view/authenticate.php` dans la méthode `authenticate` de `UserController.php` et effectuez tous les changements possibles pour utiliser :
- l'objet `$request` pour manipuler les données GET et POST transmises par l'utilisateur (voir [HTTP Requests](https://laravel.com/docs/8.x/requests))
- la directive [`redirect`](https://laravel.com/docs/8.x/routing#redirect-routes) de Laravel au lieu de `header`.
1. Les exceptions ne sont plus "catchées". Pour que le mécanisme fonctionne à nouveau, remplacez tous les `Exception` et `PDOException` par `\Exception` et `\PDOException`. Pour en savoir plus, regardez les explications sur l'[espace de noms global](https://www.php.net/manual/fr/language.namespaces.global.php)).
1. Supprimez le fichier `resources/view/authenticate.php`.
1. Appliquez l'ensemble des étapes étapes précédentes aux routes `adduser`, `changepassword` et `deleteuser`.
Exercice 5 : Les routes nommées
-------------------------------
L'objectif des routes nommées est de décorréler l'URL d'une route de la façon de la mentionner dans votre application.
1. Nommez toutes les routes dans `routes/web.php` ([voir doc ici](https://laravel.com/docs/8.x/routing#named-routes)).
1. Dans `UserController.php` et `EnsureMyUserIsAuthenticated.php`, modifiez toutes les redirections pour faire appel aux routes nommées en utilisant `redirect()->route(...)`.
1. Dans toutes les vues, replacez toutes les références à des routes par des références à des routes nommées avec `{{ route(...) }}`
Exercice 6 : Les sessions selon Laravel
---------------------------------------
Cet exercice va permettre de déléguer l'intégralité de la gestion des sessions à Laravel (qui fait ça très bien), avec pour effet de rendre le code plus lisible.
Le choix vous est laissé d'utiliser les sessions à travers l'objet `$request->session()` ou à travers la fonction globale `session` (voir la documentation disponible sur la page [HTTP Session](https://laravel.com/docs/8.x/session)).
1. Remplacez tous les appels au tableau `$_SESSION` du fichier `UserController.php` par l'utilisation des sessions de Laravel. En particulier :
- utilisez [`put`](https://laravel.com/docs/8.x/session#storing-data) pour sauvegarder le nom de l'utilisateur
- détruisez les sessions avec [`flush`](https://laravel.com/docs/8.x/session#deleting-data)
- utilisez le second paramètre de la directive `view` et combiner `with` avec `redirect` pour transmettre les messages d'information et le nom de l'utilisateur. Vous n'avez plus besoin de supprimez les messages de la session.
> Note : À ce stade, l'authentification ne fonctionne plus.
1. Faite de même pour le middleware `EnsureMyUserIsAuthenticated.php`.
> Note : Maintenant l'authentification fonctionne.
1. Finalement, supprimez l'appel à `session_start()` du fichier `routes/web.php` et supprimez le groupe global.
**Félicitation : votre application est maintenant entièrement MVC !**
TP8.md 0 → 100644
TP8 - Eloquent ORM
==================
Objectif
--------
Dans le TP précédent, nous avons mis en place la partie Contrôleur de notre application Laravel qui est maintenant totalement MVC.
Dans ce TP6, l'objectif est d'utiliser les fonctionnalités de l'ORM Eloquent pour gérer les modèles sans se soucier de leur enregistrement en base de données.
Exercice 1 : Un utilisateur qui manie le verbe
----------------------------------------------
Pour cet exercice, référez-vous aux documentations sur [la migration](https://laravel.com/docs/6.x/migrations) et sur [Eloquent ORM](https://laravel.com/docs/6.x/eloquent).
1. Supprimez tous les fichiers du répertoire `databases/migrations`.
1. Créez un modèle d'utilisateur `UserEloquent` avec artisan et générez le fichier de migration en une seule commande :
```sh
$ php artisan make:model UserEloquent -m
```
1. Modifiez le fichier de migration `database/migrations/2020_..._create_user_eloquents_table.php` pour avoir une table :
- qui s'appelle `UserEloquent`,
- qui possède un champ numérique `user_id` qui est clé primaire,
- qui possède un champs varchar `user` unique,
- qui possède un champ varchar `password` de taille 256.
1. Effectuez la migration avec la commande :
```sh
$ php artisan migrate
```
et vérifiez que la table `UserEloquent` a bien été créée avec `sqlite3` ou `sqlitebrowser`.
1. Dans `app/Models/UserEloquent.php`, indiquez :
- que la table s'appelle `UserEloquent`
- que la clé primaire s'appelle `user_id`
- qu'il n'y a pas de `timestamps` dans les attributs
> Note : pour effectuer une nouvelle migration (qui supprimera également toutes les données) utilisez la commande suivante :
> ```sh
> $ php artisan migrate:fresh
> ```
Exercice 2 : De MyUser à UserEloquent
-------------------------------------
Cet exercice a pour objectif de remplacer l'utilisation du modèle `MyUser` par `UserEloquent` dans `UserController.php`.
1. Commencez par effectuer le remplacement dans la méthode `addUser` en :
- réintroduisant le principe de `password_hash` mais avec la [facade `Hash`](https://laravel.com/docs/8.x/hashing) de Laravel,
- "try-catchant" les exceptions de type `\Illuminate\Database\QueryException` pouvant survenir lors de la sauvegarde du nouvel utilisateur.
1. Continuez avec la méthode `authenticate` en :
- réintroduisant la méthode `password_verify` mais avec la [facade `Hash`](https://laravel.com/docs/8.x/hashing) de Laravel,
- utilisant `firstOrFail()` pour déclencher une exception de type `\Illuminate\Database\Eloquent\ModelNotFoundException` (à "try-catcher") lorsque l'utilisateur n'est pas trouvé dans la BDD
1. Poursuivez avec `changePassword` en :
- réintroduisant la méthode `password_hash`mais avec la [facade `Hash`](https://laravel.com/docs/8.x/hashing) de Laravel,
- "try-catchant" les exceptions de type `\Illuminate\Database\QueryException` pouvant survenir lors de la sauvegarde de l'utilisateur.
1. Modifiez enfin `deleteUser` en utilisant `firstOrFail()` pour déclencher une exception de type `\Illuminate\Database\Eloquent\ModelNotFoundException` (à "try-catcher") lorsque l'utilisateur n'est pas trouvé dans la BDD.
1. Finalement, supprimez le fichier `MyUser.php` et toutes les instructions qui y font référence.
Exercice 3 : Un UserEloquent en session
---------------------------------------
Actuellement, nous considérons qu'un utilisateur est connecté si on a stocké son login en session. Cet exercice a pour but de stocker directement l'objet UserEloquent en session, ce qui aura pour conséquence de réduire le nombre de requêtes et de simplifier l'écriture des contrôleurs et des vues.
Modifiez :
- les méthodes `authenticate` pour sauvegarder l'objet UserEloquent en session
- les méthodes `changePassword` et `deleteUser` pour manipuler directement l'utilisateur stocké en session
- la vue `account.blade.php` pour d'adapter l'affichage du login de l'utilisateur connecté
TP noté
=======
## Contexte
La startup dans laquelle vous venez d'être recruté s'agrandit et il devient primordial de mettre en place une **gestion mutualisée du parc informatique**.
C'est en partie pour vos compétences en développement web que vous avez tapé dans l'œil de votre chef de projet : votre première mission consiste à concevoir une application back-end (partie serveur) Lumen avec un front-end (site web) minimaliste pour la gestion du parc informatique, répondant au cahier des charges qui suit.
## Rendu
- Pensez à "commiter" au fur et à mesure du TP
- Ne "pusher" l'ensemble de votre code sur Gitlab qu'au moment où vous terminez.
- Attention, **seul les commits effectués AVANT la fin de la séance seront pris en compte** : pensez à prendre le temps nécessaire à ces opération avant la fin de l'examen.
## Évaluation
- L'évaluation ne tiendra pas compte de la qualité de l'interface et de l'ergonomie : concentrez-vous sur le PHP, pas sur le HTML.
- Les intentions seront prises en compte : si vous savez comment faire mais êtes bloqués par un problème technique, signalez-le par un commentaire et passez aux autres fonctionnalités.
## Base de données
Le modèle de données utilisé doit être composé des 3 tables suivantes :
- `Users` : login (varchar,255), password (varchar,255)`
- `Postes` : id (int,11), salle (int,3), os (varchar,255)`
- `Reservations` : id (int,11), user_id (varchar,255), poste_id (int,11), date_debut (date), date_fin (date), est_root (tinyint,1)`
Dans la table `Users` :
- la colonne `login` est la clé primaire et unique de la table `Users`
Dans la table `Reservations` :
- les colonnes `user_id` et `poste_id` sont des clés étrangères référençant les colonnes `login` et `id` des tables `Users` et `Postes`.
- la colonne `est_root` est un booléen indiquant si l'utilisateur est administrateur ou non.
- Les colonnes `date_debut` et `date_fin` définissent la période sur laquelle un utilisateur est autorisé à utiliser un poste.
- Pour la colonne `est_root`, le type `(tinyint,1)` est identique à un booléen
Le fichier `init_db.sql` contient un script SQL permettant de créer ces tables avec leurs contraintes et des enregistrements. Il doit être importé dans PhpMyAdmin selon les indications ci-dessous.
## Démarrer le TP
1. Exécutez la commande le `git pull prof master` pour récupérer le répertoire `TP_note` qui contient :
- `ParcInfo/` : le répertoire contenant le framework lumen de base.
- `init_db.sql` : le script d'initialisation de la base de données
- `README.md` : l'énoncé du TP noté que vous êtes en train de lire.
2. Importez la base de données dans PhpMyAdmin :
- Créez une nouvelle base de données `ParcInfo` depuis http://ss4s.iutrs.unistra.fr
- Connectez-vous sur PhpMyAdmin à l'adresse http://webetu.iutrs.unistra.fr/phpmyadmin/
- Suivez [cette procédure](https://help.fasthosts.co.uk/app/answers/detail/a_id/3186/~/importing-and-exporting-mysql-databases-using-phpmyadmin) en
choisissant sélectionnant la base `ParcInfo` et le script `init_db.sql` comme fichier à importer.
3. Modifiez le fichier `ParcInfo/.env` avec vos informations de connexion à la base de données.
4. Copiez-collez le répertoire `vendor` de l'un de vos projet Lumen, ainsi que tous les autres fichiers que vous voulez.
5. Votre environnement est prêt.
### Fonctionnalités de gestion du compte
1. Un visiteur anonyme doit pouvoir : (~5 points)
- voir la page d'accueil
- créer un compte
- se connecter
2. Un utilisateur connecté doit pouvoir : (~6 points)
- changer son mot de passe (les mots de passes doivent être chiffrés)
- supprimer son compte
> Note: Au moment de la connexion, c'est le nom de l'utilisateur qui est enregistré dans une variable de session et qui pourra (devra) être réutilisée lors de la gestion des postes.
### Fonctionnalités de gestion du parc informatique
Les fonctionnalités de gestion du parc informatique doivent uniquement être réalisables si l'utilisateur est connecté. Un utilisateur connecté doit pouvoir :
1. Lister tous les postes informatiques avec pour chacun son id, sa salle et l'OS installé.
2. Ajouter un nouveau poste informatique en indiquant :
- le numéro de la salle (balise `<input>` de type `number`)
- l'OS (balise `<select>` contenant 4 `<option>` : Ubuntu, Debian, MacOS, et Windows)
3. Supprimer un poste depuis la page listant tous les postes, avec un lien spécifique pour chaque poste.
4. Lister toutes les réservations avec le n° de poste concerné, l'id de l'utilisateur concerné (qui peut être présent dans les varaibles de session), les dates de début et de fin, et si l'utilisateur aura les droits d'administration.
5. Réserver un poste pour soi en indiquant :
- l'identifiant du poste (élément `input` de type `number`)
- la date de début d'utilisation (élément `input` de type `date`)
- la date de fin d'utilisation (élément `input` de type `number`)
- les droits sur le poste (élément `<select>` contenant 2 `<option>` : admin ou user)
6. Supprimer une réservation depuis la page listant toutes les réservations avec un lien différent pour chaque réservation
7. Visualiser toutes les réservations liées à un poste donné depuis la page listant tous les postes, avec un lien spécifique ajouté au niveau de chaque poste.
8. Lister toutes mes réservations.
> *Indication* :
> Les champs de type `date` doivent être traitée comme une chaîne de caractères au format YYYY-MM-DD lors de la construction de la requête.
> Il se trouve que c'est dans ce format qu'un élément HTML input de type "date" formate la date lors la soumission du formulaire.
File added
Laragames
=========
Objectif
--------
Développer une application Laravel permettant de gérer une collection de jeux vidéos.
Base
----
1. Partez d'une solution fonctionnelle du TP8, la vôtre ou celle proposée dans le répertoire "correction" à la racine de ce dépôt Git.
2. Les parties I et II sont indépendantes.
Rendu
-----
Le rendu se fait sur vôtre fork Gitlab de "W31", **dans un répertoire nommé "Laragames" à la racine de votre dépôt**.
- Pensez à "commiter" (et éventuellement "pusher") au fur et à mesure du TP
- N'oubliez pas de "pusher" à la fin du TP noté
- Attention, **les commits effectués APRÈS l'horaire de fin du TP ne seront pas pris en compte** : pensez à prendre le temps nécessaire à ces opération avant la fin de l'examen.
I. Compte utilisateur
---------------------
L'objectif de cette première partie est d'ajouter un âge au profil d'un utilisateur. Pour cela vous devez :
1. utiliser un `<input>` de type `number` lors de la création du compte.
1. afficher l'âge sur la page d'accueil d'un utilisateur connecté (en plus de son nom).
1. proposer la modification de l'âge sur la même page que la modification du mot de passe. Pour cela vous devez :
- créer un second formulaire
- définir une route spécifique pour traiter ce second formulaire
- afficher à nouveau la page de modification en cas d'erreur
- afficher de la page `welcome` si tout s'est bien passé, avec l'âge mis à jour
1. afficher l'âge courant comme valeur par défaut de l'`<input>` du nouveau formulaire.
II. Jeux vidéos
---------------
Un utilisateur peut gérer sa liste de jeux vidéos. Un jeu vidéo est défini par :
- un id
- un nom
- une URL de la jaquette du jeu
- une description
- un propriétaire (qui référence l'utilisateur qui le possède)
> Note : Dans un premier temps, il est possible de considérer qu'un jeu n'a pas de propriétaire. Tous les utilisateurs accèdent à tous les jeux. Il faudra bien entendu intégrer la relation dans un second temps et adapter votre code.
1. Créer un modèle `VideoGame` avec son contrôleur et son fichier de migration associés, à l'aide de la commande suivante :
```
$ php artisan make:model VideoGame -c -m
```
1. Compléter le fichier de migration créé en 1.
1. Créer une page `gamelist` :
- accessible depuis la page d'accueil d'un utilisateur connecté,
- qui affiche toutes les informations (nom, illustration et description) de tous les jeux de l'utilisateur connecté,
- qui propose un lien pour retourner sur la page d'accueil de l'utilisateur.
1. Créer une page `formgame` :
- accessible depuis la page `gamelist` d'un utilisateur connecté,
- qui propose un formulaire pour ajouter un nouveau jeu à la collection de l'utilisateur connecté. Il faut indiquer nom, url et description du jeu/
1. Pour chaque jeu, ajouter la possibilité de le supprimer depuis la page `gamelist`.
1. Faire en sorte que la suppression d'un compte utilisateur supprime également tous les jeux qu'il possède.
root = true
[*]
charset = utf-8
end_of_line = lf
insert_final_newline = true
indent_style = space
indent_size = 4
trim_trailing_whitespace = true
[*.md]
trim_trailing_whitespace = false
[*.{yml,yaml}]
indent_size = 2
APP_NAME=Laravel
APP_ENV=local
APP_KEY=
APP_DEBUG=true
APP_URL=http://localhost
LOG_CHANNEL=stack
DB_CONNECTION=mysql
DB_HOST=127.0.0.1
DB_PORT=3306
DB_DATABASE=laravel
DB_USERNAME=root
DB_PASSWORD=
BROADCAST_DRIVER=log
CACHE_DRIVER=file
QUEUE_CONNECTION=sync
SESSION_DRIVER=file
SESSION_LIFETIME=120
REDIS_HOST=127.0.0.1
REDIS_PASSWORD=null
REDIS_PORT=6379
MAIL_MAILER=smtp
MAIL_HOST=smtp.mailtrap.io
MAIL_PORT=2525
MAIL_USERNAME=null
MAIL_PASSWORD=null
MAIL_ENCRYPTION=null
MAIL_FROM_ADDRESS=null
MAIL_FROM_NAME="${APP_NAME}"
AWS_ACCESS_KEY_ID=
AWS_SECRET_ACCESS_KEY=
AWS_DEFAULT_REGION=us-east-1
AWS_BUCKET=
PUSHER_APP_ID=
PUSHER_APP_KEY=
PUSHER_APP_SECRET=
PUSHER_APP_CLUSTER=mt1
MIX_PUSHER_APP_KEY="${PUSHER_APP_KEY}"
MIX_PUSHER_APP_CLUSTER="${PUSHER_APP_CLUSTER}"
* text=auto
*.css linguist-vendored
*.scss linguist-vendored
*.js linguist-vendored
CHANGELOG.md export-ignore
/node_modules
/public/hot
/public/storage
/storage/*.key
/vendor
.env
.env.backup
.phpunit.result.cache
Homestead.json
Homestead.yaml
npm-debug.log
yarn-error.log
php:
preset: laravel
disabled:
- no_unused_imports
finder:
not-name:
- index.php
- server.php
js:
finder:
not-name:
- webpack.mix.js
css: true
<p align="center"><a href="https://laravel.com" target="_blank"><img src="https://raw.githubusercontent.com/laravel/art/master/logo-lockup/5%20SVG/2%20CMYK/1%20Full%20Color/laravel-logolockup-cmyk-red.svg" width="400"></a></p>
<p align="center">
<a href="https://travis-ci.org/laravel/framework"><img src="https://travis-ci.org/laravel/framework.svg" alt="Build Status"></a>
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/dt/laravel/framework" alt="Total Downloads"></a>
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/v/laravel/framework" alt="Latest Stable Version"></a>
<a href="https://packagist.org/packages/laravel/framework"><img src="https://img.shields.io/packagist/l/laravel/framework" alt="License"></a>
</p>
## About Laravel
Laravel is a web application framework with expressive, elegant syntax. We believe development must be an enjoyable and creative experience to be truly fulfilling. Laravel takes the pain out of development by easing common tasks used in many web projects, such as:
- [Simple, fast routing engine](https://laravel.com/docs/routing).
- [Powerful dependency injection container](https://laravel.com/docs/container).
- Multiple back-ends for [session](https://laravel.com/docs/session) and [cache](https://laravel.com/docs/cache) storage.
- Expressive, intuitive [database ORM](https://laravel.com/docs/eloquent).
- Database agnostic [schema migrations](https://laravel.com/docs/migrations).
- [Robust background job processing](https://laravel.com/docs/queues).
- [Real-time event broadcasting](https://laravel.com/docs/broadcasting).
Laravel is accessible, powerful, and provides tools required for large, robust applications.
## Learning Laravel
Laravel has the most extensive and thorough [documentation](https://laravel.com/docs) and video tutorial library of all modern web application frameworks, making it a breeze to get started with the framework.
If you don't feel like reading, [Laracasts](https://laracasts.com) can help. Laracasts contains over 1500 video tutorials on a range of topics including Laravel, modern PHP, unit testing, and JavaScript. Boost your skills by digging into our comprehensive video library.
## Laravel Sponsors
We would like to extend our thanks to the following sponsors for funding Laravel development. If you are interested in becoming a sponsor, please visit the Laravel [Patreon page](https://patreon.com/taylorotwell).
### Premium Partners
- **[Vehikl](https://vehikl.com/)**
- **[Tighten Co.](https://tighten.co)**
- **[Kirschbaum Development Group](https://kirschbaumdevelopment.com)**
- **[64 Robots](https://64robots.com)**
- **[Cubet Techno Labs](https://cubettech.com)**
- **[Cyber-Duck](https://cyber-duck.co.uk)**
- **[Many](https://www.many.co.uk)**
- **[Webdock, Fast VPS Hosting](https://www.webdock.io/en)**
- **[DevSquad](https://devsquad.com)**
- **[OP.GG](https://op.gg)**
## Contributing
Thank you for considering contributing to the Laravel framework! The contribution guide can be found in the [Laravel documentation](https://laravel.com/docs/contributions).
## Code of Conduct
In order to ensure that the Laravel community is welcoming to all, please review and abide by the [Code of Conduct](https://laravel.com/docs/contributions#code-of-conduct).
## Security Vulnerabilities
If you discover a security vulnerability within Laravel, please send an e-mail to Taylor Otwell via [taylor@laravel.com](mailto:taylor@laravel.com). All security vulnerabilities will be promptly addressed.
## License
The Laravel framework is open-sourced software licensed under the [MIT license](https://opensource.org/licenses/MIT).
<?php
namespace App\Console;
use Illuminate\Console\Scheduling\Schedule;
use Illuminate\Foundation\Console\Kernel as ConsoleKernel;
class Kernel extends ConsoleKernel
{
/**
* The Artisan commands provided by your application.
*
* @var array
*/
protected $commands = [
//
];
/**
* Define the application's command schedule.
*
* @param \Illuminate\Console\Scheduling\Schedule $schedule
* @return void
*/
protected function schedule(Schedule $schedule)
{
// $schedule->command('inspire')->hourly();
}
/**
* Register the commands for the application.
*
* @return void
*/
protected function commands()
{
$this->load(__DIR__.'/Commands');
require base_path('routes/console.php');
}
}
<?php
namespace App\Exceptions;
use Illuminate\Foundation\Exceptions\Handler as ExceptionHandler;
class Handler extends ExceptionHandler
{
/**
* A list of the exception types that are not reported.
*
* @var array
*/
protected $dontReport = [
//
];
/**
* A list of the inputs that are never flashed for validation exceptions.
*
* @var array
*/
protected $dontFlash = [
'password',
'password_confirmation',
];
/**
* Register the exception handling callbacks for the application.
*
* @return void
*/
public function register()
{
//
}
}
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use App\Models\Article;
use App\Models\UserEloquent;
class ArticleController extends Controller
{
/**
* Show the required article
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function show( Request $request, int $id )
{
return view('article')
->with('article',Article::findOrFail($id))
->with('message',$request->session()->get('message'));
}
/**
* Show the three last articles
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function last( Request $request )
{
$lastArticles = Article::where('published',1)
->orderBy('published_on','desc')
->take(3)
->get();
return view('home')
->with('articles',$lastArticles)
->with('message',$request->session()->get('message'));
}
/**
* Show the form to write a new article
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function formArticle( Request $request )
{
return view('writearticle')
->with('message',$request->session()->get('message'));
}
/**
* Show the form to edit an article
*
* @param \Illuminate\Http\Request $request
* @param int $article_id
* @return \Illuminate\Http\Response
*/
public function formeditarticle( Request $request, int $article_id )
{
return view('articleedit')
->with('article',Article::find($article_id))
->with('message',$request->session()->get('message'));
}
/**
* Add a new article
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function write( Request $request )
{
if ( !$request->filled(['title','abstract','content']) )
return redirect()->route('formarticle')->with('message','Some POST data are missing.');
$article = new Article;
$article->author_id = $request->session()->get('user')->id;
$article->title = $request->title;
$article->abstract = $request->abstract;
$article->content = $request->content;
$article->published = (bool) $request->publish;
$article->published_on = $article->published ? now() : null;
$article->last_update = $article->published_on;
try
{
$article->save();
}
catch (\Illuminate\Database\QueryException $e)
{
return redirect()->route('formarticle')
->with('message','Sorry, an error occur durng article saving. Please try again.');
}
return redirect()->route('account')->with('message','New article created!');
}
/**
* Chnage the publication status on/off
*
* @param \Illuminate\Http\Request $request
* @param int $article_id
* @return \Illuminate\Http\Response
*/
public function toggleStatus( Request $request, int $article_id )
{
// if ( $article_id == NULL )
// return redirect()->route('formarticle')->with('message','Some POST data are missing.');
$currentDate= now();
$article = Article::find($article_id);
if ( $article->published )
{
$article->published = false;
$article->published_on = null;
}
else
{
$article->published = true;
$article->published_on = $currentDate;
}
try
{
$article->save();
}
catch (\Illuminate\Database\QueryException $e)
{
return redirect()->route('myarticles')
->with('message','Sorry, an error occur durng article update. Please try again.');
}
return redirect()->route('myarticles');
}
/**
* Edit an article
*
* @param \Illuminate\Http\Request $request
* @param int $article_id
* @return \Illuminate\Http\Response
*/
public function edit( Request $request, int $article_id )
{
if ( !$request->filled(['title','abstract','content']) )
return redirect()->route('myarticles')->with('message','Some POST data are missing.');
$article = Article::find($article_id);
$article->title = $request->title;
$article->abstract = $request->abstract;
$article->content = $request->content;
$article->last_update = now();
try
{
$article->save();
}
catch (\Illuminate\Database\QueryException $e)
{
return redirect()->route('myarticles')
->with('message','Sorry, an error occur durng article saving. Please try again.');
}
return redirect()->route('myarticles')->with('message','Article updated!');
}
}
<?php
namespace App\Http\Controllers;
use Illuminate\Foundation\Auth\Access\AuthorizesRequests;
use Illuminate\Foundation\Bus\DispatchesJobs;
use Illuminate\Foundation\Validation\ValidatesRequests;
use Illuminate\Routing\Controller as BaseController;
class Controller extends BaseController
{
use AuthorizesRequests, DispatchesJobs, ValidatesRequests;
}
<?php
namespace App\Http\Controllers;
use Illuminate\Http\Request;
use Illuminate\Support\Facades\Hash;
use App\Models\UserEloquent;
class UserController extends Controller
{
/**
* Show the signin page
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function signin( Request $request )
{
return view('signin')
->with('message',$request->session()->get('message'));
}
/**
* Show the signup page
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function signup( Request $request )
{
return view('signup')
->with('message',$request->session()->get('message'));
}
/**
* Show the formpassword page
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function formpassword( Request $request )
{
return view('formpassword')
->with('message',$request->session()->get('message'));
}
/**
* Signout
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function signout( Request $request )
{
$request->session()->flush();
return redirect()->route('home');
}
/**
* Show the account page
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function account( Request $request )
{
return view('account')
->with('user',$request->session()->get('user'))
->with('message',$request->session()->get('message'));
}
/**
* Show the article page
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function articles( Request $request )
{
return view('authorarticles')
->with('user',$request->session()->get('user')->fresh())
->with('message',$request->session()->get('message'));
}
/**
* Authentication
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function authenticate( Request $request )
{
if ( !$request->filled(['login','password']) )
return redirect()->route('signin')->with('message','Some POST data are missing.');
try
{
$user = UserEloquent::where('login',$request->login)->firstOrFail();
}
catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e)
{
return redirect()->route('signin')->with('message','Wrong login.');
}
if ( !Hash::check($request->password,$user->password) )
return redirect()->route('signin')->with('message','Wrong password.');
$request->session()->put('user',$user);
return redirect()->route('account');
}
/**
* Add a user
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function addUser( Request $request )
{
if ( !$request->filled(['login','password','confirm']) )
return redirect()->route('signup')->with('message','Some POST data are missing.');
if ( $request->password !== $request->confirm )
return redirect()->route('signup')->with('message','Error: the two passwords differ. Try again.');
$user = new UserEloquent;
$user->login = $request->login;
$user->password = Hash::make($request->password);
try
{
$user->save();
}
catch (\Illuminate\Database\QueryException $e)
{
return redirect()->route('signup')
->with('message','Sorry, this login still exists. Please choose another one.');
}
return redirect()->route('signin')->with('message','Account created! Now, signin.');
}
/**
* Change the user password
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function changePassword( Request $request )
{
if ( !$request->filled(['newpassword','confirmpassword']) )
return redirect()->route('formpassword')->with('message','Some POST data are missing.');
if ( $request->newpassword != $request->confirmpassword )
return redirect()->route('formpassword')->with('message','Error: the two passwords differ. Try again.');
try
{
$user = $request->session()->get('user');
$user->password = Hash::make($request->newpassword);
$user->save();
}
catch (\Illuminate\Database\QueryException $e)
{
return redirect()->route('formpassword')->with('message','Error: password changing failed. Try again.');
}
return redirect()->route('account')->with('message','Password successfully updated.');
}
/**
* Delete the logged user
*
* @param \Illuminate\Http\Request $request
* @return \Illuminate\Http\Response
*/
public function deleteUser( Request $request )
{
try
{
$request->session()->get('user')->delete();
}
catch (\Illuminate\Database\Eloquent\ModelNotFoundException $e)
{
return redirect()->route('account')->with('message','Error during deletion. Try again.');
}
$request->session()->flush();
return redirect()->route('signin')->with('message','Account successfully deleted.');
}
}
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment