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.
Merci pour ton article! Exactement ce que je cherchait, un poil de retouche pour coller à mon projet, et tout passe nickel !
Merci pour toutes ces infos, voici une bonne lecture. J’ai appris différentes choses en vous lisant, merci à vous. Fabienne Huillet http://www.neonmag.fr
Merci pour cette article.
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
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
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é 😉
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 🙂 !
hello, super tuto, très utile mais j’ai juste un problème: comment intègres-tu dropzone dans un formulaire sonata-admin?
merci!
Bonjour, comment avez-vous entendu parler du cloud Amazon? c’était sur un forum? une publicité?merciii