Come gestire le virgolette negli attributi degli shortcode in WordPress
Sto cercando di capire come gestire le virgolette (singole e doppie) negli attributi degli shortcode.
Il problema è che il contenuto viene inserito dall'utente e quindi potrebbe potenzialmente includere virgolette " e '. Con le virgolette doppie, l'attributo dello shortcode smette di funzionare correttamente, ad esempio:
attributo="testo qui con "virgolette" che interrompe l'attributo..."
Invece di ottenere l'intera stringa, si ferma alla seconda coppia di virgolette.
So che si potrebbe usare le virgolette singole, ma questo creerebbe lo stesso problema se l'utente usasse virgolette singole nel testo.
Ho esaminato varie soluzioni PHP/WP ma nessuna sembra funzionare, come esc_html, htmlspecialchars, htmlentities.
Forse ho configurato male o non sto applicando la codifica nel punto giusto.
Attualmente sto usando questo codice per lo shortcode (semplificato):
function aps_person_schema_shortcode( $atts, $content = null) {
extract( shortcode_atts( array(
'aps_person_description' => ''
), $atts
)
);
$aps_person_return = '<div class="aps_person_container aps_container">';
$aps_person_return .= '<p class="aps_person_description" itemprop="description">' . $aps_person_description . '</p>';
$aps_person_return .= '</div>';
return $aps_person_return;
}
add_shortcode('aps_person', 'aps_person_schema_shortcode');
Ho provato ad aggiungere dopo l'array extract cose come:
$aps_person_description = esc_html($atts['aps_person_description']);
ma poiché l'attributo è già rotto (print_r mostra che la stringa dopo la virgoletta è separata in un elemento array per ogni parola), l'escape della stringa non funziona.
Provato anche prima dell'array ma non funziona e ottengo un Notice: Undefined index
Quindi, per chiarire, come si può sanificare l'input utente per i dati degli attributi degli shortcode?

Si scopre che il sistema degli shortcode di WordPress utilizza la funzione shortcode_parse_atts($text);
per analizzare una voce di shortcode e recuperare i nomi e i valori degli attributi, memorizzandoli in coppie nell'array $atts
, che viene poi passato alla funzione dello shortcode. Quindi, nel tuo caso, aggiungere azioni di escape nella funzione dello shortcode come questa:
$aps_person_description = esc_html($atts['aps_person_description']);
non funzionerà perché shortcode_parse_atts()
ha già recuperato i nomi e i valori degli attributi e potrebbe aver interpretato erroneamente le virgolette nei valori degli attributi.
Per approfondire, la funzione shortcode_parse_atts()
utilizza questo pattern regex:
/(\w+)\s*=\s*"([^"]*)"(?:\s|$)|(\w+)\s*=\s*\'([^\']*)\'(?:\s|$)|(\w+)\s*=\s*([^\s\'"]+)(?:\s|$)|"([^"]*)"(?:\s|$)|(\S+)(?:\s|$)/
per riconoscere i nomi e i valori degli attributi nei seguenti formati:
1. attr1="value1"
2. attr2='value2'
3. attr3=value3
4. "value4"
5. value5
Quindi, se un utente inserisce virgolette nei valori, può facilmente andare storto. Ad esempio:
[my_shortcode dog='Santa's Little Helper' /]
// $attr è Array ( [0] => dog='Santa's [1] => Little [2] => Helper' )
// dovrebbe essere Array ( [dog] => Santa's Little Helper )
Sanificare dopo l'analisi è ovviamente troppo tardi, che ne dici di sanificare prima dell'analisi? Dovremmo sanificare l'intera voce poiché non abbiamo ancora alcun valore di attributo su cui lavorare. Ma anche questo causa problemi, ad esempio:
html_entities("[my_shortcode dog='Santa's Little Helper' /]", ENT_QUOTES);
// ora la voce è [my_shortcode dog='Santa's Little Helper' /]
// dopo l'analisi:
Array
(
[dog] => 'Santa's
[0] => Little
[1] => Helper'
)
Il paradosso è: per assicurarsi che il motore di analisi analizzi correttamente, devi sanificare i valori degli attributi; ma per farlo devi prima eseguire il motore di analisi per ottenere i valori.
In conclusione, penso che il modo ragionevole per assicurarsi che tutto vada bene sia garantire che gli utenti inseriscano gli attributi in formati corretti. Una volta che gli utenti inseriscono attributi mal formattati, sarà un grosso problema. Per tua informazione, la mia esperienza è di utilizzare $content
. Nel tuo caso, metterei aps_person_description
nel $content
, potrebbe apparire così:
[my_shortcode]testo qui con "virgolette" che interrompono l'attributo...[/my_shortcode]
e le virgolette saranno meno un problema.

Non c'è alcun paradosso, è un semplice ma significativo difetto in shortcode_parse_atts()
. Semplicemente non è così che si dovrebbero analizzare gli attributi tra virgolette. Le sequenze di escape sono fondamentali, non troverai un linguaggio di programmazione senza di esse. Avrebbe dovuto includere questa funzionalità fin dall'inizio. Il tuo esempio potrebbe essere facilmente scritto come [my_shortcode dog='Santa\'s Little Helper' /]
se il parser avesse un minimo di intelligenza.

Sembra che tu stia lavorando sull'estremità sbagliata.
Prova a sanitizzare l'input dell'utente, ad esempio utilizzando sanitize_text_field
, non l'output dello shortcode.

Mi sono trovato di fronte a un problema simile quando dovevo stampare una variabile PHP all'interno di un attributo di uno shortcode. Nel mio caso, il valore era il nome di un termine di tassonomia, non un contenuto generato dall'utente, quindi non c'era input da sanitizzare.
Utilizzando htmlentities()
con il flag ENT_QUOTES
è possibile utilizzare stringhe che includono '
e "
come attributi di shortcode. Tuttavia, questa funzione converte anche altri caratteri in entità HTML, ad esempio &
in &
, il che non era ideale per il mio caso.
Per convertire solo i caratteri '
e "
in entità HTML, senza modificare altri caratteri come &
:
htmlspecialchars_decode( htmlentities($value_to_print, ENT_QUOTES), ENT_NOQUOTES )
htmlspecialchars_decode()
inverte tutte le entità HTML convertite da htmlentities()
. Utilizzando il flag ENT_NOQUOTES
si impedisce che i caratteri '
e "
vengano riconvertiti.
