Permettez-moi d'expliquer le traitement d'une demande par WordPress et une méthode pour changer le comportement de WordPress pour atteindre vos objectifs en conséquence.
Analyse de la demande
Lorsque WordPress reçoit une demande, il démarre un processus de dissection de la demande et de la transformer en page. Le cœur de ce processus commence lorsque la méthode de requête principale WordPress WP::main()
est appelée. Cette fonction analyse la requête, comme vous l'avez correctement identifié, dans parse_request()
(in includes/class-wp.php
). Là, WordPress essaie de faire correspondre l'URL avec l'une des règles de réécriture . Lorsque l'URL correspond, il crée une chaîne de requête des parties d'URL et code ces parties (tout entre deux barres obliques) à l'aide de urlencode()
, pour empêcher les caractères spéciaux tels que &
de gâcher la chaîne de requête. Ces caractères codés peuvent vous avoir fait penser que le problème résidait là, mais ils sont en fait transformés en leurs "vrais" caractères correspondants lors de l'analyse de la chaîne de requête.
Exécution de la requête associée à la demande
Après que WordPress a analysé l'URL, il configure la classe de requête principale WP_Query
, ce qui se fait selon la même main()
méthode que la WP
classe. Le boeuf de WP_Query
peut être trouvé dans sa get_posts()
méthode où tous les arguments de requête sont analysés et nettoyés et la requête SQL réelle est construite (et, éventuellement, exécutée).
Dans cette méthode, sur la ligne 2730, le code suivant est exécuté:
$q['name'] = sanitize_title_for_query( $q['name'] );
Cela désinfecte le message pour le récupérer dans la table des messages. La sortie des informations de débogage à l'intérieur de la boucle montre que c'est là que réside le problème: votre nom de publication,, my-permalink~
est transformé en my-permalink
, qui est ensuite utilisé pour récupérer la publication dans la base de données.
La fonction de nettoyage du titre du message
La fonction sanitize_title_for_query
appelle sanitize_title
avec les paramètres appropriés, ce qui procède à la désinfection du titre. Maintenant, le cœur de cette fonction applique le sanitize_title
filtre:
$title = apply_filters( 'sanitize_title', $title, $raw_title, $context );
Ce filtre a, dans WordPress natif, une seule fonction attachée à elle: sanitize_title_with_dashes
. J'ai écrit un aperçu complet de ce que fait cette fonction, qui peut être trouvé ici . Dans cette fonction, la ligne à l'origine de votre problème est
$title = preg_replace('/[^%a-z0-9 _-]/', '', $title);
Cette ligne supprime tous les caractères à l'exception des caractères alphanumériques, des espaces, des tirets et des traits de soulignement.
Résoudre votre problème
Il existe donc essentiellement une seule façon de résoudre votre problème: supprimer la sanitize_title_with_dashes
fonction du filtre et la remplacer par votre propre fonction. Ce n'est en fait pas si difficile à faire, mais :
- Lorsque WordPress modifie le processus interne de désinfection des titres, cela aura des effets majeurs sur votre site Web.
- D'autres plugins connectés à ce filtre peuvent ne pas gérer correctement la nouvelle fonctionnalité.
Plus important encore : WordPress utilise le résultat de la sanitize_title
fonction directement dans la requête SQL par cette ligne:
$where .= " AND $wpdb->posts.post_name = '" . $q['name'] . "'";
Si jamais vous envisagez de changer le filtre, assurez-vous d'avoir correctement échappé le titre avant qu'il ne soit utilisé dans la requête!
Conclusion: la résolution de votre problème n'est pas nécessaire en ce qui concerne la sécurité, mais si vous voulez le faire, remplacez le sanitize_title_with_dashes
par votre propre fonctionnalité et faites attention à l'échappement SQL.
NB tous les noms de fichiers et numéros de ligne correspondent aux fichiers WordPress 4.4.2.