badge Dotclear 2.36

Le mécanisme de session de Dotclear dans ces versions inférieures à 2.36 était très stricte et écrit en dur là ou il y en avait besoin. La version 2.36 introduit des outils de connexions variés et la possibilité d'utilser des sessions coté publique, ce qui a obligé la team à revoir le fonctionnement des sessions. Pas de révoluton, les classes de sessions n'ont quasi pas été modifié, mais des changements qui peuvent porter à consequence.

Backend

Précedement, les sessions coté admin (backend) n'existait que lorsqu'on en avait besoin, c'est à dire lorsque l'utilisateur était connu. On pouvait donc faire simplement un test d'existence de session pour diverses routines. Mais depuis la version 2.36, les sessions sont toujours démarrées et existantes. Elle peuvent donc être vide et sans valeur de test.

Frontend

Coté publique, les sessions fournies par Dotclear n'existaient tout simplement pas avant la version 2.36. Depuis si un plugin veut utiliser des sessions coté publique, une simple ligne de code suffira à la démarrer.

App::session()->start();

Et si plusieurs plugins utilisent des sessions coté publique, chacun ajoutera cette ligne de code. Pas de soucis à l'appeler plusieurs fois, elle teste qu'elle a déjà été appelé. Ce nouveau système de session commune coté publique risque de poser problème avec de vieux plugins pas à jour utilisant leurs propres sessions, ce qui provoquera des erreurs assez fatales ! Un bien pour un mal, car avec la 2.36 on met tout le monde d'accord.

A noter que si un plugin utilise App::session()->destroy(); il détruira la session pour tous les autres plugins en même temps, ce n'est peut-être pas le comportement souhaité par les autres plugins !

Sans me faire de pub (qui risque plutôt de m'apporter des problèmes) un plugin FrontendSession propose de gérer les sessions coté publique avec tous les points d'entrée nécessaire à d'autres plugins. Widget, formulaire de login, menu utilisateur, page de gestion des options publique de l'utilisateur, etc...

Accès aux valeurs

Dans les versions précédentes de Dotclear, l'accès aux valeurs de session se faisait classiquement par $_SESSION, mais cela change. Le service de session contient trois nouvelles méthodes pour lire, écrire et effacer ces valeurs.

Leurs définition est très simple :

interface SessionInterface
{
    // ...

    /**
     * Set a value to session.
     *
     * @param   string  $key    The key
     * @param   mixed   $value  The value
     */
    public function set(string $key, mixed $value): void;

    /**
     * Get a value from session.
     *
     * @param   string  $key    The key
     *
     * @return  mixed   The value or null if not set
     */
    public function get(string $key): mixed;

    /**
     * Unset values from session.
     *
     * @param   string  $keys   The keys
     */
    public function unset(...$keys): void;
}

Le plugin n'a plus qu'à lire et écrire des valeurs de session avec par exemple :

if (App::session()->get('ma_valeur') == '' && !empty($__POST['mon_formulaire'])) {
    App::session()->set('ma_valeur', '1');
}
if (!empty($_POST['reset'])) {
    App::sesssion()->unset('ma_valeur');
}

La valeur sera automatiquement enregistrée en session à la fin du script, le plugin n'a pas à gérer cette partie non plus. Et l'ancienne écriture avec $_SESSION est encore valable mais pas récommander.

Configuration

Précédement la configuration du gestionnaire de session se faisait à sa construction. Une méthode désormais présente pour configurer le service avant de démarrer une session. Cela permet d'avoir un seul service App::session() qui peut être configurer suivant si on est en frontend ou backend.

Elle est définie dans son interface comme suit :

Interface SessionInterface
{
    //...

    /**
     * Configure session cookie.
     *
     * This MUST be done before session starts.
     *
     * @param   string          $cookie_name    Cookie name
     * @param   null|string     $cookie_path    Cookie path
     * @param   null|string     $cookie_domain  Cookie domain
     * @param   bool            $cookie_secure  Cookie secure
     * @param   null|string     $ttl            The ttl
     *
     * @throws  Dotclear\Exception\SessionException     if session is already configured
     */
    public function configure(
        string $cookie_name, 
        ?string $cookie_path = null, 
        ?string $cookie_domain = null, 
        bool $cookie_secure = false, 
        ?string $ttl = null
    ): void;
}

Mais pas besoin de retenir cette mécanique, les "Utility" (backend, frontend, upgrade) gère cette méthode et prépare le service avant l'appel aux plugins et thèmes.

.