Utiliser Uploadify avec les sessions Symfony2

Pour uploader des images avec Uploadify tout en conservant la même session Symfony2 dans un environnement sécurisé, il est necessaire de passer le paramètre de session pour récupérer la même session lors de l’appel Flash.

Passer son identifiant de session à Uploadify

Dans notre template Twig, nous allons passer notre identifiant de session (app.session.id) au script javascript d’Uploadify pour pouvoir le récupérer par la suite dans sf2.

{% extends "::base.html.twig" %}
{% block css %}
    {{ parent() }}
    <link href="{{ asset('bundles/novawaycms/js/uploadify/uploadify.css') }}" rel="stylesheet" type="text/css" />
{% endblock %}

{% block body %}
<form><input id="file_upload" type="file" name="file_upload" /></form>
{% endblock %}

{% block js %}
    {{ parent() }}
<script type="text/javascript" src="{{ asset('bundles/novawaycms/js/uploadify/swfobject.js') }}"></script>
<script type="text/javascript" src="{{ asset('bundles/novawaycms/js/uploadify/jquery.uploadify.v2.1.4.min.js') }}"></script>

<script type="text/javascript">

$(document).ready(function() {
    $('#file_upload').uploadify({
        'uploader'  : '{{ asset('bundles/novawaycms/js/uploadify/uploadify.swf') }}',
        'script'    : '{{ path("processUpload") }}',
        'scriptData': {'sid':'{{app.session.id}}'},
        'cancelImg' : '{{ asset('bundles/novawaycms/js/uploadify/cancel.png') }}',
        'auto'      : true,
        'buttonText'  : 'Parcourir ...',
        'multi'          : true,
        'fileExt'     : '*.jpg;*.gif;*.png',
        'fileDesc'    : 'Fichiers Images Web (.JPG, .GIF, .PNG)',
        'onComplete'  : function(event, ID, fileObj, response, data) {

        }
    });
});
{% endblock %}

On ajoute le paramètre sid qui contient notre identifiant de session Symfony2 à la requête qui sera éxécutée par la librairie.

Récupérer l’identifiant de session dans Symfony2

Puis, on crée notre listener de session UploadifySessionListener que nous ajouterons dans un dossier EventListener de notre bundle.

<?php

/*
 * Override Session listener for uploadify
 */

namespace Novaway\Bundle\CmsBundle\EventListener;

use Symfony\Component\DependencyInjection\ContainerInterface;

use Symfony\Component\HttpKernel\HttpKernelInterface;
use Symfony\Component\HttpKernel\Event\GetResponseEvent;

/**
 * Sets the session on the request.
 *
 * This will also start the session if it was already started during a previous
 * request.
 *
 */
class UploadifySessionListener
{
    private $container;
    private $autoStart;

    public function __construct(ContainerInterface $container, $autoStart = false)
    {
        $this->container = $container;
        $this->autoStart = $autoStart;
    }

    public function onKernelRequest(GetResponseEvent $event)
    {
        if (HttpKernelInterface::MASTER_REQUEST !== $event->getRequestType()) {
            return;
        }

        if (!$this->container->has('session')) {
            return;
        }

        $request = $event->getRequest();
        if ($request->hasSession()) {
            return;
        }

        $request->setSession($session = $this->container->get('session'));

        if ($request->getMethod() == 'POST' &&
            $this->container->get('request')->request->has('Filename') &&
            $this->container->get('request')->request->has('sid')) {

            session_id($this->container->get('request')->request->get('sid'));

            //fix problème de récuperation du token
            $this->container->get('request')->cookies->set(session_name(), $session->getId());
        }

        if ($this->autoStart || $request->hasPreviousSession()) {
            $session->start();
        }
    }
}

Il ne reste plus qu’à dire à notre application d’utiliser notre listener de session à la place de celui par défaut.

Pour cela, nous allons surcharger celui-ci grâce à l’injection de dépendance dans notre fichier de configuration (app/config/config.yml) :

    parameters:
        session_listener.class: Novaway\Bundle\CmsBundle\EventListener\UploadifySessionListener

Uploadify est désormais utilisable en mode connecté.

Note: pour illustrer ce billet, nous passons directement l’id de session brute. Dans un environnement de production, il serait préférable de le crypter/décrypter pour éviter des injections de session.