Giter Site home page Giter Site logo

lpdim2016's Issues

[Exercices] Liste des exercices à réaliser

Travaux Pratiques à Réaliser

Les sections suivantes décrivent les différents exercices à réaliser et à rendre sous la forme d'une pull request Github avant le mardi 23 février 2016 à 23:59:59, heure de Paris.

Exercice 1 : Routes au Format YAML ou JSON

Le framework actuel supporte la définition des routes de l'application dans les formats de configuration PHP et XML. Il vous est demandé d'implémenter, au choix, le support des routes au format JSON ou YAML. Néanmoins, la contrainte imposée pour ces formats consiste à suivre le formalisme suivant :

# app/config/routes.yml
homepage:
    path: /home
    params: { _controller: "Application\\Controller\\HomePageAction" }
    methods: [ GET, POST ]

# ...
# app/config/routes.json
{
    "routes": {
        "homepage": {
            "path": "/home",
            "params": {
                "_controller": "Application\\Controller\\HomePageAction"
            },
            "methods": [ "GET", "POST" ]
        }
    }
}

Vous devrez bien sûr livrer avec le code qui réalise cette fonctionnalité les tests unitaires qui prouvent son bon fonctionnement comme c'est le cas actuellement dans le dépôt de code.

Exercice 2 : Création de Blog Post

L'application doit proposer une page pour ajouter un nouveau blog post à la liste actuelle. Pour cet exercice, il vous est demandé de répondre aux exigences suivantes :

  • Vérifier que tous les champs du formulaire soient bien remplis,
  • Réafficher le formulaire avec les bons messages d'erreur en cas d'erreur,
  • Insérer les données de l'article en base de données avec une transaction SQL,
  • Rediriger l'utilisateur vers la page de l'article inséré.

Pour cet exercice, vous serez évalué sur le respect du principe MVC. Vous devrez faire attention à mettre le code au bon endroit.

Astuce : N'hésitez pas à créer de nouveaux composants génériques dans l'espace de nommage du framework !

Exercice 3 : Articles en Markdown

Dans cet exercice, il vous est demandé de stocker les contenus des articles au format Markdown. Markdown est le format textuel utilisé pour écrire et formater les différentes parties du fichier README.

Pour ne pas réinventer la route, vous devrez choisir une bibliothèque de code tierce pour analyser du Markdown et le transformer en chaîne HTML correspondante.

De plus, la base de données devra contenir pour chaque article, le contenu Markdown et sa version HTML. La version Markdown sert à pouvoir éditer l'article tandis que la version HTML sert à alimenter la vue Twig.

Vous devrez répondre aux exigences suivantes pour réaliser cet exercice :

  • Mettre à jour le schéma de votre base de données et conserver dans un fichier SQL la requête de modification du schéma,
  • Télécharger une bibliothèque de code PHP tierce de votre choix pour transformer du contenu Markdown en contenu HTML,
  • Transformer le contenu Markdown en HTML à chaque nouvelle sauvegarde de l'article en base de données,
  • Afficher dans la vue la version HTML correspondant au Markdown sauvegardé.

Astuce : pensez à utiliser Composer et le site Packagist.org pour gérer le code tiers !

Exercice 4 : Sécurité des Accès

Afin de sécuriser certaines pages du site, il est demandé de réaliser un système d'authentification et de gestion de droits d'accès. Chaque compte utilisateur doit avoir au moins un identifiant unique, un mot de passe et une liste de permissions associées. Le mot de passe doit obligatoirement être encrypté avec un algorithme de hachage de votre choix (md5, sha1, bcrypt, etc.) et une graine aléatoire (seed ou salt).

Vous êtes libre de stocker les identifiants utilisateurs et les permissions associées où vous le souhaitez (fichier YAML, fichier XML, base de données, etc.).

Seulement deux pages doivent être sécurisées par le système :

  • La page à l'URL /dashboard nécessite seulement d'être identifié, peu importe les permissions associées au compte utilisateur,
  • La page de création d'un blog post créée à l'exercice 2 nécessite d'être authentifié avec une permission AUTHOR.

Le système d'authentification doit répondre aux deux exigences suivantes :

  • Si l'on tente d'accéder à une page sécurisée sans être authentifié, la requête est automatiquement redirigée vers la page de connexion (url: /login).
  • Si l'on tente d'accéder à une page sécurisée en étant authentifié mais sans avoir les bonnes permissions, la requête est redirigée ou génère une réponse de type 403 (Forbidden). Une vue personnalisée doit être développée pour ce type de réponse.

Astuce : pensez à utiliser le gestionnaire d'événements et l'événement KernelEvents::REQUEST pour brancher le système de sécurité. Aussi, le nouveau service session peut vous aider pour la persistance des données entre deux requêtes HTTP.

Exercice 5 : Générateur d'URLs

Pour ce cinquième exercice, il vous est demandé de modifier le composant Routing afin de proposer un service de génération d'URLs basé sur la configuration des routes. Cet objet doit être disponible depuis n'importe quel contrôleur (action) de votre application afin de pouvoir générer des URLs.

Vous devez proposer une implémentation de l'interface Framework\Routing\UrlGeneratorInterface capable de générer des urls en fonction de la configuration des routes.

Considérez la route suivante :

<?xml version="1.0" encoding="UTF-8" ?>
<routes>
    <route name="blog_post" path="/blog/article-{id}.html" methods="GET">
        <param key="_controller">Application\Controller\Blog\GetPostAction</param>
        <requirement key="id">\d+</requirement>
    </route>
</routes>

Pour chaque route configurée de votre application, votre implémentation de générateur d'URL doit être capable de se comporter de la manière suivante :

# Invalid, must throw exception for missing required parameters.
$url = $generator->generate('blog_post');

# $url == '/index.php/blog/article-42.html'
$url = $generator->generate('blog_post', ['id' => '42']);

# $url == '/index.php/blog/article-42.html?page=2'
$generator->generate('blog_post', ['id' => '42', 'page' => 2]);

# $url == 'http://your-domain-name.tld/index.php/blog/article-42.html'
$url = $generator->generate('blog_post', ['id' => '42'], UrlGeneratorInterface::ABSOLUTE_URL);

# $url == 'http://your-domain-name.tld/index.php/blog/article-42.html?page=2'
$generator->generate('blog_post', ['id' => '42', 'page' => 2], UrlGeneratorInterface::ABSOLUTE_URL);

Dans l'URL générée, le contrôleur frontal index.php ne doit pas apparaître si l'URL appelée dans votre navigateur ne le contient pas. C'est le cas par exemple si votre serveur Apache (ou NGinx) est configuré pour faire de la réécriture automatique d'URLs grâce à un fichier de configuration .htaccess.

Pour valider que votre classe de générateur d'URL fait bien son travail, vous devrez fournir avec une série de tests unitaires qui couvrent notamment les exemples donnés juste au dessus.

En guise de bonus, les plus téméraires d'entre vous peuvent s'essayer à l'écriture d'une classe d'extension Twig (voir documentation officielle) qui fournit deux nouvelles fonctions path() et url() dans tous les templates. La première doit générer des URLs relatives tandis que la seconde doit générer des URLs absolues. Le bout de code ci-dessous illustre le fonctionnement de ces deux nouvelles fonctions Twig :

<a href="{{ path('blog_post', { 'id': 42, 'page': 2 }) }}">Read</a>
{# <a href="/index.php/blog/article-42.html?page=2">Read</a> #}

<a href="{{ url('blog_post', { 'id': 42, 'page': 2 }) }}">Read</a>
{# <a href="http://your-domain-name.tld/index.php/blog/article-42.html?page=2">Read</a> #}

Enfin, profitez-en pour refactoriser dans votre code tous les endroits dans lesquels vous auriez manuellement généré des URLs en remplaçant ces appels manuels par ceux de votre service de génération d'URLs.

Astuce : pensez à réutiliser, voire enrichir, les objets RouteCollection et RequestContext du composant Routing.

Exercice 6 : Syntaxe Alternative des Contrôleurs

Dans ce dernier exemple, il s'agit au framework de vous proposer une syntaxe alternative pour configurer vos routes et leurs contrôleurs associés. Par exemple, au lieu de spécifier le chemin complet de la classe, il serait plus judicieux de proposer la syntaxe alternative abstraite suivante :

<?xml version="1.0" encoding="UTF-8" ?>
<routes>
    <route name="homepage" path="/" methods="GET">
        <param key="_controller">App:Homepage</param>
    </route>
    <route name="blog_post" path="/blog/article-{id}.html" methods="GET">
        <param key="_controller">App:Blog:GetPost</param>
        <requirement key="id">\d+</requirement>
    </route>
</routes>

Au chargement des routes, c'est alors au framework de se charger d'analyser la syntaxe alternative et d'en déduire la vraie classe de contrôleur à instancier. Ce mécanisme à développer doit être capable de traduire le chemin App:Homepage en Application\\Controller\\HomepageAction et le chemin App:Blog:GetPost en Application\\Controller\\Blog\\GetPostAction.

Bien sûr le comportement actuel doit toujours être garanti ! Par conséquent, si une route est configurée avec un vrai namespace de classe, il est alors inutile de chercher à l'analyser et le transformer.

Pour valider vos changements dans le code du framework, il vous est aussi demandé de livrer une suite de tests unitaires. Cette suite de tests unitaires doit toujours faire passer les anciennes configurations de route avec des namespaces de classes de contrôleurs ainsi que les nouvelles avec la notation raccourcie abstraite.

Astuce : attention à ne pas surcharger les responsabilités de l'objet ControllerFactory !

[Introduction] Modalités de l'évaluation technique et pratique

Module Technos Web / PHP

Introduction

Sur la base du code présent actuellement dans la branche master du dépôt de code, il vous est demandé de réaliser les exercices complémentaires détaillés plus bas.

Vous serez évalué et noté individuellement sur le travail réalisé. La notation portera en particulier sur les critères d'évaluation ci-dessous. Cette liste de critères n'est pas exhaustive et peut évoluer encore d'ici la date de rendu finale.

  • Les fonctionnalités demandées sont implémentées et fonctionnent,
  • Les tests unitaires sont fournis pour valider le code et les bugs potentiels,
  • L'exécution des tests unitaires génère ni erreurs ni échecs,
  • Les bonnes pratiques étudiées en cours (SOLID, injection de dépendance, PSR,
    etc.) sont respectées,
  • Les structures de code telles que les classes, les méthodes et les variables
    sont correctement nommées en anglais,
  • Les morceaux de code potentiellement complexes sont correctement documentés en
    anglais avec des commentaires dans le code,
  • Les outils et librairies tierces importées dans votre code sont distribués
    sous des licences Open-Source compatibles,
  • etc.

Cette évaluation pratique s'ajoutera à votre note obtenue lors de l'évaluation théorique du mardi 12 janvier 2015. Elle comptera pour le même coefficient.

Modalités de Rendu

Vous devrez soumettre individuellement votre travail sous la forme d'une « Pull Request » Github. Pour ce faire, il vous faudra tout d'abord vous créer un compte Github.com si vous n'en possédez pas encore un. Lorsque vous êtes connecté à votre compte Github, rendez-vous sur la page de ce dépôt de code et forkez-le à l'aide du bouton prévu à cet effet en haut à droite.

Vous disposerez désormais d'une copie (aka un fork) de ce dépôt de code dans votre espace Github.com. Il vous suffit alors de cloner ce fork sur votre machine en utilisant la ligne de commande de Github dans un terminal ou bien depuis une interface GUI (exemple : Tower pour Mac OS).

La ligne de commande pour cloner votre fork doit être similaire à celle ci-dessous en prenant soin d'adapter le nom d'utilisateur Github (<username>) par le vôtre.

$ git clone [email protected]:<username>/lpdim2016.git

Lorsque votre clone est téléchargé sur votre machine, déplacez-vous dans le répertoire et créez immédiatement une nouvelle branche dans laquelle vous committerez vos changements. C'est cette branche que vous soumettrez ensuite en tant que Pull Request afin d'être évalué(e).

Le nom de la branche doit être nommée de la manière suivante : prenom-nom. Par exemple, la commande pour créer une nouvelle branche nommée hugo-hamon est la suivante :

$ git checkout -b hugo-hamon

Vous êtes à présent dans votre branche et vous pouvez commencer à implémenter les exercices dans l'ordre que vous souhaitez. Il vous ai demandé néanmoins de réaliser qu'un seul commit pour chaque exercice afin de grouper dans ce dernier tous les fichiers impactés. Cela permettra ainsi au correcteur de revoir plus facilement les changements commit par commit. Vous pouvez par exemple suivre une nomenclature de commits similaire à celle ci-dessous.

$ git add fichier1.php
$ git add fichier2.php
$ git commit -m'[Framework] implemented exercise #1.'
$
$ # ... d'autres modifications
$
$ git add fichierX.php
$ git commit -m'[Application] implemented exercise #2.'

Après chaque commit, n'oubliez pas de pousser votre branche et ses commits sur votre fork avec la commande git push.

$ git push origin hugo-hamon

Lorsque vous êtes prêt(e) à rendre votre devoir, rendez-vous sur la page Github de votre fork et soumettez votre branche en tant que Pull Request. Vous verrez apparaître un bouton vert Pull Request sur votre fork. Lorsque vous aurez validé votre pull request, celle-ci apparaîtra automatiquement dans la liste des demandes de contribution du dépôt initial à l'adresse suivante :

https://github.com/hhamon/lpdim2016/pulls

Vérifiez bien que votre pull request apparaisse dans cette liste ! Bien que branche a été poussée à ce stade, vous pouvez toujours ajouter de nouveaux commits à celle-ci simplement en les poussant depuis votre copie locale grâce à la commande git push origin <prenom-nom>. L'évaluation du code que vous aurez soumis sera réalisée après la date et l'heure maximum autorisée de soumission. N'hésitez donc pas à corriger, revoir, améliorer le code de votre branche en committant souvent dans votre branche et en poussant celle-ci régulièrement.

Rappel : chaque copie rendue est strictement individuelle ! Le travail en
groupe n'est pas autorisé mais cette contrainte ne vous empêche pas de vous
aider mutuellement pour réaliser les travaux demandés. Néamoins, les copies
rendues dans lesquelles il y aura des suspicions fortes de morceaux de code
copiés seront sanctionnées !

Il s'est déjà produit une année que quatre étudiants ont rendu le même code à
la virgule près. Les trois étudiants qui avaient copié ont été sanctionnés
dans leur notre mais aussi par la Direction de la licence professionnelle.

La date de rendu de votre travail sous la forme d'une pull request est fixée au plus tard au mardi 23 février 2016 à 23:59:59, heure de Paris. Toute pull request soumise après ce délai sera ignorée et la note de 0 vous sera attribuée !

Documentation

Il ne vous ai pas interdit de réutiliser du code trouvé sur Internet pour réaliser votre travail. Vous êtes même encouragés à ne pas réinventer la roue, sauf si l'intitulé de l'exercice vous y oblige pour vérifier et valider certaines compétences acquises en formation. Toutefois, si vous décidez de réutiliser des bouts de code téléchargés sur Internet comme des fonctions ou bien des classes, il vous ai demandé de le documenter dans votre code. L'exemple ci-dessous montre comment documenter la source d'une classe ou d'une fonction avec le mot-clé @see.

/**
 * @see http://some-website.com/the/url-of-this-class.html
 */
class ImageResizer
{
    /**
     * @see http://some-website.com/the/url-of-this-function.html
     */
    public function resize($image, $maxWidth, $maxHeight)
    {
        // ...
    }
}

Assurez aussi que vous avez bien le droit de récupérer un bout de code en vérifiant notamment la licence avec laquelle ce bout de code est distribué : MIT, GPL, LGPL, etc.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.