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');
1 De Cunégonde -
Si tu le dis, je te crois.
2 De Franck -
J’aime bien quand tu es d’accord avec moi Cunégonde !