Consentitemi di spiegare l'elaborazione di una richiesta da parte di WordPress e un metodo per modificare il comportamento di WordPress per raggiungere i vostri obiettivi di conseguenza.
Analisi della richiesta
Quando WordPress riceve una richiesta, avvia un processo di dissezione della richiesta e trasformazione in una pagina. Il nucleo di questo processo inizia quando WP::main()
viene chiamato il metodo di query principale di WordPress . Questa funzione analizza la query, come correttamente identificato, in parse_request()
(in includes/class-wp.php
). Lì, WordPress tenta di abbinare l'URL a una delle regole di riscrittura . Quando l'URL viene abbinato, crea una stringa di query delle parti URL e codifica queste parti (tutto tra due barre) usando urlencode()
, per evitare che caratteri speciali come &
incasinare la stringa di query. Questi caratteri codificati potrebbero averti indotto a pensare che il problema risiedesse lì, ma in realtà sono stati trasformati nei corrispondenti caratteri "reali" durante l'analisi della stringa di query.
Esecuzione della query associata alla richiesta
Dopo che WordPress ha analizzato l'URL, imposta la classe di query principale WP_Query
, che viene eseguita nello stesso main()
metodo della WP
classe. Il manzo di WP_Query
può essere trovato nel suo get_posts()
metodo in cui tutti gli argomenti della query vengono analizzati e disinfettati e la query SQL effettiva viene costruita (e, alla fine, eseguita).
In questo metodo, sulla riga 2730, viene eseguito il seguente codice:
$q['name'] = sanitize_title_for_query( $q['name'] );
Questo sanifica il post per recuperarlo dalla tabella dei post. L'output delle informazioni di debug all'interno del ciclo mostra che è qui che si trova il problema: il nome del tuo post my-permalink~
, viene trasformato in my-permalink
, che viene quindi utilizzato per recuperare il post dal database.
La funzione di sanificazione post titolo
La funzione sanitize_title_for_query
chiama sanitize_title
con i parametri corretti, che procede alla sanificazione del titolo. Ora il nucleo di questa funzione sta applicando il sanitize_title
filtro:
$title = apply_filters( 'sanitize_title', $title, $raw_title, $context );
Questo filtro è, in WordPress nativo, una singola funzione collegato ad esso: sanitize_title_with_dashes
. Ho scritto un'ampia panoramica di ciò che fa questa funzione, che può essere trovata qui . In questa funzione, la linea che sta causando il tuo problema è
$title = preg_replace('/[^%a-z0-9 _-]/', '', $title);
Questa riga rimuove tutti i caratteri ad eccezione di caratteri alfanumerici, spazi, trattini e caratteri di sottolineatura.
Risolvere il tuo problema
Quindi, esiste fondamentalmente un solo modo per risolvere il problema: rimuovere la sanitize_title_with_dashes
funzione dal filtro e sostituirla con la propria funzione. In realtà non è così difficile da fare, ma :
- Quando WordPress modifica il processo interno di sanificazione dei titoli, ciò avrà effetti importanti sul tuo sito Web.
- Altri plugin collegati a questo filtro potrebbero non gestire correttamente la nuova funzionalità.
Ancora più importante : WordPress utilizza il risultato della sanitize_title
funzione direttamente nella query SQL da questa riga:
$where .= " AND $wpdb->posts.post_name = '" . $q['name'] . "'";
Se dovessi mai considerare di cambiare il filtro, assicurati di sfuggire correttamente al titolo prima che venga utilizzato nella query!
Conclusione: risolvere il problema non è necessario per quanto riguarda la sicurezza, ma se si desidera farlo, sostituirlo sanitize_title_with_dashes
con la propria funzionalità e prestare attenzione all'evasione dell'SQL.
NB tutti i nomi dei file e i numeri di riga corrispondono ai file WordPress 4.4.2.