Permítanme explicar el procesamiento de WordPress de una solicitud y un método para cambiar el comportamiento de WordPress para lograr sus objetivos en consecuencia.
Analizando la solicitud
Cuando WordPress recibe una solicitud, comienza un proceso de disección de la solicitud y la transforma en una página. El núcleo de este proceso comienza cuando WP::main()
se llama al método de consulta principal de WordPress . Esta función analiza la consulta, como identificó correctamente, en parse_request()
(in includes/class-wp.php
). Allí, WordPress intenta hacer coincidir la URL con una de las reglas de reescritura . Cuando la URL coincide, crea una cadena de consulta de las partes de la URL y codifica estas partes (todo entre dos barras) usando urlencode()
, para evitar que caracteres especiales como &
estropeen la cadena de consulta. Estos caracteres codificados pueden haberle hecho pensar que el problema residía allí, pero en realidad se convirtieron en sus caracteres "reales" correspondientes al analizar la cadena de consulta.
Ejecutando la consulta asociada con la solicitud
Después de que WordPress haya analizado la URL, configura la clase de consulta principal WP_Query
, que se realiza con el mismo main()
método de la WP
clase. La esencia de WP_Query
se puede encontrar en su get_posts()
método donde todos los argumentos de consulta se analizan y desinfectan y se construye la consulta SQL real (y, finalmente, se ejecuta).
En este método, en la línea 2730, se ejecuta el siguiente código:
$q['name'] = sanitize_title_for_query( $q['name'] );
Esto desinfecta la publicación para obtenerla de la tabla de publicaciones. La salida de información de depuración dentro del bucle muestra que aquí es donde reside el problema: su nombre de publicación my-permalink~
, se transforma en my-permalink
, que luego se utiliza para recuperar la publicación de la base de datos.
La función de desinfección del título de la publicación
La función sanitize_title_for_query
llama sanitize_title
con los parámetros adecuados, lo que procede a desinfectar el título. Ahora el núcleo de esta función es aplicar el sanitize_title
filtro:
$title = apply_filters( 'sanitize_title', $title, $raw_title, $context );
Este filtro ha, en WordPress nativa, una única función que se le atribuye: sanitize_title_with_dashes
. He escrito una extensa descripción de lo que hace esta función, que se puede encontrar aquí . En esta función, la línea que está causando el problema es
$title = preg_replace('/[^%a-z0-9 _-]/', '', $title);
Esta línea elimina todos los caracteres, excepto los caracteres alfanuméricos, espacios, guiones y guiones bajos.
Resolviendo tu problema
Entonces, básicamente hay una única forma de resolver su problema: eliminar la sanitize_title_with_dashes
función del filtro y reemplazarla con su propia función. En realidad, esto no es tan difícil de hacer, pero :
- Cuando WordPress cambia el proceso interno de desinfección de títulos, esto tendrá efectos importantes en su sitio web.
- Es posible que otros complementos conectados a este filtro no manejen correctamente la nueva funcionalidad.
Lo más importante : WordPress usa el resultado de la sanitize_title
función directamente en la consulta SQL por esta línea:
$where .= " AND $wpdb->posts.post_name = '" . $q['name'] . "'";
¡Si alguna vez considera cambiar el filtro, asegúrese de escapar correctamente del título antes de que se use en la consulta!
Conclusión: resolver su problema no es necesario en lo que respecta a la seguridad, pero si desea hacerlo, reemplácelo sanitize_title_with_dashes
con su propia funcionalidad y preste atención al escape de SQL.
NB todos los nombres de archivos y números de línea corresponden a archivos de WordPress 4.4.2.