Upload drag & drop via DropZoneJS + Symfony2 sur le CLOUD Amazon S3

Upload drag & drop via DropZoneJS + Symfony2 sur le CLOUD Amazon S3

Cette article est très vieux et ne devrait pas être utilisé comme support pour votre travail.



Glissez-déposez dans le CLOUD

Si ça c’est pas la classe !

Hop un drag & drop depuis l’OS d’un paquet d’images dans une zone de la page qui fera l’upload direct dans le CLOUD Amazon S3 !
Ho et puis en plus, avec une belle présentation génération de thumb dynamique pour chaque image et une barre de progression pour que notre utilisateur s’impatiente pas trop !
Le tout avec une gestion multiupload, des évents et de la customisation à gogo! Que demande le peuple ?

Aujourd’hui on va voir comment réaliser ça avec DropZone, une librairie javascript, et notre merveilleux framework Symfony 2 avec le bundle SonataMedia.



Javascript sans les mains

On aime le javascript, mais pas besoin d’en faire ici ! En effet DropZone nous facilite la tâche.

Alors, commençons par le commencement :  Télécharger DropZone et mettez les fichiers dans votre « /Resources/public/js  » et  « /Resources/public/css »du bundle de votre choix !

Détail qui a son importance, DropZone n’a pas besoin de jQuery !

Notre template twig va s’appeler « dropzone.html.twig »  et va ressembler à ça :

{% extends '::layout.html.twig' %}

{% block stylesheets %}
    {% stylesheets '@AcmeBundle/Resources/public/css/dropzone.css' filter='cssrewrite' %}
        <link rel="stylesheet" href="{{ asset_url }}" />
    {% endstylesheets %}
{% endblock %}

{% block body %}
    
    <form enctype="multipart/form-data" class="dropzone" action="{{ app.request.uri }}" method="post" name="acme_dropzone_form" id="acme_dropzone_form">
        {{ form_widget(form) }}
    {{ form_end(form) }}
    
{% endblock %}

{% block javascripts %}
    {% javascripts '@AcmeBundle/Resources/public/js/dropzone.min.js' filter='yui_js' %}
        <script src="{{ asset_url }}"></script>
    {% endjavascripts %}
{% endblock %}


Alors on a fait quoi ?

– On a étendu notre template layout de base. Basique me direz vous ? Je suis d’accord mais je fais juste un copier-coller ici  !

– Ensuite,  on a appelé notre block stylesheet pour le css de base de dropzone en utilisant Assetic avec le bon gros filter des familles « cssrewrite ».

– Le block body sur lequel on va mettre un formulaire de base en Symfony2. Point important :  la class « dropzone » et le action en « app.request.uri » qui sont primordiale au bon fonctionnement de DropZone !

– Enfin notre block javascript avec le script DropZone. Le tout forcement via Assetic et un bon gros filter « yui_js » des familles ! Voir comment faire fonctionner cette merveille. OUI vous en avez besoin !

Et mon petit script d’instanciation hein ? Mon petit javascript il est ou ?

Hé bien nulle part ! Pas besoin la petite classe « dropzone » sur la balise form déclenche le script et met en place toute la machine ! Sans les mains je vous ai dit.

Bon si vous voulez vraiment faire du  javascript sachez que c’est possible, notamment si vous voulez créer une zone de drop à la volée ou l’intégrer à un formulaire déjà existant etc etc :  Rendez-vous sur la page de dropzone dont j’ai donné le lien plus haut.



Media management bundle on steroid !

Hey vous connaissez SonataMediaBundle ? C’est une des solutions de gestion de médias que j’utilise le plus, tant pour sa puissance que pour ces possibilités !
Seul vrai problème : il a des dépendances, dont le générateur d’administration SonataAdminBundle. Il faut le savoir avant de vous lancer dedans !
Mais si vous avez prévu un magnifique backoffice dans votre appli ou si vous voulez tout simplement le découvrir, je vous le recommande chaudement ! Parole de dev : Ça vaut vraiment le coup !

De toute façon la suite de l’article est basée sur Sonata Media. On installe tout ça et on revient.

Une fois que tout fonctionne on s’attaque au contrôleur qui devrait ressembler à ça :



<?php

namespace Acme\AcmeBundle\Controller;

use Symfony\Bundle\FrameworkBundle\Controller\Controller;

use Symfony\Component\HttpFoundation\Request;

use Application\Sonata\MediaBundle\Entity\Media;

class DefaultController extends Controller
{

    public function uploadAction(Request $request)
    {
        $form = $this->createFormBuilder()->getForm();

        $form->handleRequest($request);

        if ($form->isValid()) {
            
            // Getting sonata media manager service
            $mediaManager = $this->container->get('sonata.media.manager.media');
            
            // Getting sonata media object and saving media
            $media = new Media;
            $media->setBinaryContent($request->files->get('file'));
            $media->setContext('default');
            $media->setProviderName('sonata.media.provider.image');
            $mediaManager->save($media);

            
        }

        return $this->render('AcmeAcmeBundle:Default:dropzone.html.twig', array(
            'form' => $form->createView()
        ));
    }
    
}


Ici on a créé un formulaire vide. Au post et après validation on a instancié un media auquel on rentre les infos nécessaires, dont le fichier image.
Ensuite on utilise le service de management des médias pour l’enregistrer. Enfin on envoie notre formulaire au twig. EASY !

En l’état ça marche !! WOOOT ! Sauf que sans toucher au config de base du bundle de média, votre image sera bien uploadée, mais sur le disque de votre serveur. C’est cool mais sans plus !

Une envie de faire un tour dans les nuages ?



Il est temps de parler directement au CLOUD



Je suis tombé sur le service Amazon S3 un peu par hasard comme souvent en cliquant partout quand je voyais un truc intéressant.Et je dois dire que ça m’a tout de suite séduit ! Tous les avantages pro mais aussi et surtout le niveau gratuit d’AWS qui comprend :  5 Go de stockage, 20 000 requêtes GET et 2 000 requêtes PUT disponible  sans frais d’installation sans abonnement. Bref, c’est totalement un compte de test ! Et on aime ça tester des choses 🙂

Par contre, je vous préviens, en plein milieu de l’inscription ils vous demandent votre numéro de carte bleu les coquins ! Hé oui le compte à beau être gratuit et n’empêche que vous utiliser leur serveur  dans le cloud avec des services hyper pro (console web, api et tout ce qui va avec). Si vous dépassez les limitations ils vous factureront. Ceci dit pas de panique,  avec le calculateur de coût d’Amazon vous pouvez vous donner un ordre d’idée des coûts.

Mais peu importe le prix finalement, ça ne vous concerne pas. Faite vos tests avec, amusez-vous un coup et supprimés simplement les images de votre espace, ou mettez les simplement en privé. Rappelez-vous que vous ne payez que ce que vous consommez !

Bref vous êtes inscrit ? Très bien on peut passer à la suite.

– Aller dans la console. Cliquer sur « Identity and Access Management » puis « Users ». Vous l’aurez compris on va créer un utilisateur. Il pourra taper ensuite sur votre espace via des clefs privées.

– Cliquer sur « Create new users » rentrer un nom d’utilisateur et pensé bien à cocher la case « Generate an access key for each user ». Une fois votre utilisateur crée ils vous filent deux clefs : « Access Key ID » et « Secret Access Key » copier/coller dans un coin on en aura bientôt besoin.

– Retourner à la console, cliquer sur « S3 », puis cliquer sur « Create Bucket ».





– Mettez un nom à votre « seau » en Français et choisissez une région. L’Ireland c’est le plus près, alors c’est parti.

– Une fois dans l’interface, cliquer sur le nom de votre Bucket, cliquer sur « Properties » en haut à droite, puis sur « Permissions » dans le menu qui apparaît. Cliquer sur « Add more permissions » puis donner l’accès à votre utilisateur créé juste avant comme ci-dessous :

– Dernière étape cliquée sur « Add bucket policy ». Par défaut, personne ne peut faire de requêtes sur votre bucket, pas même vous ! Il faut donner l’autorisation à internet de consulter vos images. Pour ce faire, copier/coller ce bout de code dans la fenêtre qui apparaît :

{
  "Version":"2012-10-17",
  "Statement":[{
 "Sid":"AddPerm",
        "Effect":"Allow",
   "Principal": "*",
      "Action":["s3:GetObject"],
      "Resource":["arn:aws:s3:::examplebucket/*"
      ]
    }
  ]
}

Pensez à remplacer « examplebucket » par votre nom de bucket. Ce petit bout de code permet à n’importe qui (avec l’adresse) de consulter les images que vous aurez mit sur votre bucket.

Vous pouvez le changer à volonté et à tout moment, consulter la liste officielle des bucket policies d’Amazon pour plus d’info. Sachez juste que vous pouvez tout fermer, tout fermer sauf pour une IP, interdire le hot linking. Bref vous avez le contrôle.

Retour à notre code : on va commencer par installer le SDK pour PHP d’Amazon. Dans le composer.json :

"require": {
  ...
  "amazonwebservices/aws-sdk-for-php": "dev-master"
  ...
}

Un coup de composer

php composer.phar update

Étape finale direction le fichier config : app/config/config.yml et mettez les directives suivantes pour sonata media.

sonata_media:
    default_context: default
    db_driver: doctrine_orm
    contexts:
        default:
            providers:
                - sonata.media.provider.image
            formats:
                small: { width: 100 , quality: 70}
                big:   { width: 500 , quality: 70}

    cdn:
        server:
            path: http://s3-eu-west-1.amazonaws.com/exampleBucket

    filesystem:
        s3:
            bucket: exampleBucket
            accessKey: exampleAccessKey
            secretKey: exampleSecretKey
            region: s3-eu-west-1.amazonaws.com
            storage: standard
            acl: private

    providers:
        image:
            filesystem: sonata.media.filesystem.s3


Et voilà !

Re-Uploadé donc une image et tout se fera automatiquement !
Félicitation, vous êtes dans le CLOUD, vous pouvez laisser exploser votre joie.





Épilogue

Je n’ai pas insisté dessus du tout, mais côté front, vous pouvez tout faire. Écouter des événements, changer l’affichage de la zone de drop mais aussi les petites thumbs générées automatiquement jusqu’à la barre de progression. Aller voir sur la page officielle, tout y est.
Si vous ne voulez pas de SonataMedia, la même solution est possible si vous gérez l’enregistrement des médias vous-même, mais il vous faudra utiliser également le SDK à la main.
Enfin sachez que si vous détestez Amazon, Google à également des solutions similaires.

Qui me parle ?

jesuisundev
Je suis un dev. En ce moment, je suis développeur backend senior / DevOps à Montréal pour un géant du jeux vidéo. Le dev est l'une de mes passions et j'écris comme je parle. Je continue à te parler quotidiennement sur mon Twitter. Tu peux m'insulter à cet e-mail ou le faire directement dans les commentaires juste en dessous. Y'a même une newsletter !

Pour me soutenir, la boutique officielle est disponible ! Sinon désactiver le bloqueur de pub et/ou utiliser les liens affiliés dans les articles, ça m'aide aussi.

9 commentaires sur “Upload drag & drop via DropZoneJS + Symfony2 sur le CLOUD Amazon S3”

  1. Voilà donc un bon article, bien passionnant. J’ai beaucoup aimé et n’hésiterai pas à le recommander, c’est pas mal du tout ! Elsa Mondriet

  2. Article fort sympathique, une lecture agréable. Ce blog est vraiment pas mal, et les sujets présents plutôt bons dans l’ensemble, bravo ! Virginie Brossard LETUDIANT.FR

  3. Article très intéressant, collant parfaitement à mon besoin actuel, un grand merci !
    Néanmoins une petite relecture s’impose, j’ai vu pas mal de fautes ici et là… dommage car l’article est de qualité 😉

  4. Merci bien pour ton post !

    Je teste ça demain, parcontre pour mon frontend j’utilise Angular et non pas Twig, Symfony me sert juste d’API. Mais je ne pense pas que ça pose de soucis particuliers… On verra bien 🙂 !

T'en penses quoi ?

Your email address will not be published. Required fields are marked *