Deixe-me explicar o processamento de uma solicitação pelo WordPress e um método para alterar o comportamento do WordPress para atingir seus objetivos de acordo.
Analisando a solicitação
Quando o WordPress recebe uma solicitação, ele inicia um processo de dissecação da solicitação e transformá-lo em uma página. O núcleo desse processo começa quando o método de consulta principal do WordPress WP::main()
é chamado. Esta função analisa a consulta, como você identificou corretamente, em parse_request()
(in includes/class-wp.php
). Lá, o WordPress tenta combinar a URL com uma das regras de reescrita . Quando o URL é correspondido, ele cria uma cadeia de consulta das partes da URL e codifica essas partes (tudo entre duas barras) usando urlencode()
, para impedir que caracteres especiais, como por exemplo, &
atrapalhem a cadeia de consulta. Esses caracteres codificados podem ter levado você a pensar que o problema residia lá, mas na verdade eles são transformados nos caracteres "reais" correspondentes ao analisar a sequência de caracteres da consulta.
Executando a consulta associada à solicitação
Depois que o WordPress analisa a URL, ele configura a classe de consulta principal WP_Query
, que é feita no mesmo main()
método da WP
classe. O beef of WP_Query
pode ser encontrado em seu get_posts()
método em que todos os argumentos da consulta são analisados e higienizados e a consulta SQL real é construída (e, eventualmente, executada).
Nesse método, na linha 2730, o seguinte código é executado:
$q['name'] = sanitize_title_for_query( $q['name'] );
Isso limpa a postagem para buscá-la na tabela de postagens. A saída de informações de depuração dentro do loop mostra que é aqui que reside o problema: seu nome da postagem,, my-permalink~
é transformado em my-permalink
, que é usado para buscar a postagem do banco de dados.
A função de higienização do título da postagem
A função sanitize_title_for_query
chama sanitize_title
com os parâmetros adequados, que procede à limpeza do título. Agora, o núcleo desta função está aplicando o sanitize_title
filtro:
$title = apply_filters( 'sanitize_title', $title, $raw_title, $context );
Este filtro tem, no WordPress nativa, uma única função ligado a ele: sanitize_title_with_dashes
. Eu escrevi uma extensa visão geral do que essa função faz, que pode ser encontrada aqui . Nesta função, a linha que está causando seu problema é
$title = preg_replace('/[^%a-z0-9 _-]/', '', $title);
Essa linha retira todos os caracteres, exceto caracteres alfanuméricos, espaços, hífens e sublinhados.
Resolvendo seu problema
Portanto, existe basicamente uma maneira única de resolver seu problema: remover a sanitize_title_with_dashes
função do filtro e substituí-la por sua própria função. Na verdade, isso não é tão difícil de fazer, mas :
- Quando o WordPress altera o processo interno de higienização de títulos, isso terá grandes efeitos no seu site.
- Outros plugins conectados a esse filtro podem não lidar corretamente com a nova funcionalidade.
Mais importante : o WordPress usa o resultado da sanitize_title
função diretamente na consulta SQL por esta linha:
$where .= " AND $wpdb->posts.post_name = '" . $q['name'] . "'";
Se você já pensou em mudar o filtro, não se esqueça de escapar corretamente do título antes que ele seja usado na consulta!
Conclusão: a solução do seu problema não é necessária no que diz respeito à segurança, mas, se você desejar, substitua-a sanitize_title_with_dashes
por sua própria funcionalidade e preste atenção ao escape do SQL.
NB: todos os nomes de arquivos e números de linha correspondem aos arquivos do WordPress 4.4.2.