Je m'en doutais !

Problème agaçant toujours pas résolu avec notre système de behaviors dans Dotclear : on peut passer un tableau (sous forme de ArrayObject) en argument, ce qui permet à la fonction inscrite et appelée de modifier le contenu d’icelui mais en aucun cas elle ne peut ajouter d’élément à celui-ci !

Je viens de refaire un test avec la gestion des entêtes (headers) HTTP. Voilà le code côté cœur de Dotclear :

$headers = new ArrayObject;
if ($core->blog->settings->system->prevents_clickjacking) {
    if ($_ctx->exists('xframeoption')) {
        $url    = parse_url($_ctx->xframeoption);
        $header = sprintf('X-Frame-Options: %s',
            is_array($url) ? ("ALLOW-FROM " . $url['scheme'] . '://' . $url['host']) : 'SAMEORIGIN');
    } else {
                                                 // Prevents Clickjacking as far as possible
        $header = 'X-Frame-Options: SAMEORIGIN'; // FF 3.6.9+ Chrome 4.1+ IE 8+ Safari 4+ Opera 10.5+
    }
    $headers[] = $header;
}
# --BEHAVIOR-- urlHandlerServeDocumentHeaders
$core->callBehavior('urlHandlerServeDocumentHeaders', $headers);

// Send additional headers if any
foreach ($headers as $header) {
    header($header);
}

Et voilà ce que j’ai placé dans un plugin de test :

$core->addBehavior('urlHandlerServeDocumentHeaders',array('debugPublic','urlHandlerServeDocumentHeaders'));
class debugPublic
{
    public static function urlHandlerServeDocumentHeaders($headers)
    {
        $header[] = 'X-Debug-Options: Dotclear';
    }
}

Eh bien à l’affichage, il n’y a que le premier header qui est présent (X-Frame-Options: SAMEORIGIN). Quant à l’autre, il a disparu pendant l’aller-retour de la gestion des behaviors, gérée par cette fonction :

public function callBehavior($behavior)
{
    if (isset($this->behaviors[$behavior])) {
        $args = func_get_args();
        array_shift($args);

        $res = '';

        foreach ($this->behaviors[$behavior] as $f) {
            $res .= call_user_func_array($f, $args);
        }

        return $res;
    }
}

On avait déjà expérimenté le même problème pour les filtres des templates.

Il va donc falloir que je trouve une solution, quitte à créer une nouvelle chaîne de behaviours — vous aurez noté la légère différence, so british !


Hurrah \o/

Finalement, en jetant un œil à la doc de ArrayObject j’ai fini par me rendre compte qu’il y avait une méthode assez pratique : append(). Alors forcément, quand je modifie le code en conséquence :

$core->addBehavior('urlHandlerServeDocumentHeaders',array('debugPublic','urlHandlerServeDocumentHeaders'));
class debugPublic
{
    public static function urlHandlerServeDocumentHeaders($headers)
    {
        $headers->append('X-Debug-Options: Dotclear');
    }
}

Ça fonctionne beaucoup mieux :

X-Debug-Options: Dotclear
X-Frame-Options: SAMEORIGIN

J’ai plus qu’à retourner m’occuper des filtres de template, avec entre autre une petite réécriture de mon plugin gracefulCut

Au passage on peut utiliser la méthode offsetSet() plutôt que append() pour ajouter des éléments clé/valeur, voire même valeur seule en fin de tableau :

$args->offsetSet('graceful_cut', $args['cut_string']);
$args->offsetSet(null, 'X-Debug-Options: Dotclear'); // Equivalent to $args->append('X-Debug-Options: Dotclear');

Ajouter un commentaire

Comments can be formatted using the Markdown Extra syntax.

Ajouter un rétrolien

URL de rétrolien : https://open-time.net/trackback/13707

Haut de page