Ciao a tutti.
Ho una view con un filtro esposto "Taxnomy term ID with Depth" e vorrei fare in modo che, in base al termine cercato, il title della view cambiasse. Esempio: se cerco un'azienda a Roma, vorrei un titolo simile a "Cerca un'azienda a Roma". Ho provato ad usare gli argomenti, perché so che è questa la via giusta, ma non ce la faccio proprio a venire fuori. Ho letto e cercato un sacco di informazioni, soprattutto su drupal.org ma niente da fare.
Allora ho cercato di risolvere in un'altra maniera. Nel Header della view, ho inserito il seguente codice:
<?php
$view = views_get_current_view();
$title = 'Cerca un'azienda a '.$view->exposed_input['tax'];
drupal_set_title($title);
?>
Con questo metodo ("tax" è il nome del filtro esposto, che è un autocomplete), ciò che è stato scritto come input dall'utente viene usato nel titolo. questo metodo ha però un sacco di aspetti negativi:
1. non riesco a creare una condizione per fare in modo che il titolo venga assegnato in questo modo solo se la view mi restituisce un risultato
2. per lo stesso motivo, non riesco ad assegnare un titolo di default per la view "vergine", cioè prima che l'utente digiti qualcosa
3. non essendo case sensitive quella casella di ricerca, se l'utente digita "roma" (in minuscolo quindi) e preme invio ignorando il suggerimento del autocomplete, il risultato è "Cerca un'azienda a roma".. senza contare che potrebbe digitare anche "rOmA" per quanto ne sappia!
Insomma, devo tornare agli argomenti nella view ed usare quelli per assegnare il titolo. Qualcuno potrebbe aiutarmi?
E' tutto il giorno che cerco di farcela da solo ma, ahimè, non ne sono in grado..
L'input dell'utente lo puoi normalizzare con strtolower e ucfirst (funzioni PHP). Prima di mettere user input in qualsiasi parte dell'HTML, ti consiglio di verificare che l'input venga filtrato per evitare XSS e problemi simili legati alla sicurezza.
Per la condizione in base ai risultati, nell'oggetto $view è contenuto $view->results (o $view->result, non ricordo), dovrebbe essere sufficiente verificare se ha contenuti e quanti contenuti ha.
Ok, insomma mi consigli di seguire questa strada?
Farò una prova oggi pomeriggio e vi farò sapere.
Ok, dopo aver tribulato sono giunto ad una soluzione!
Ovviamente ho deciso di aggiungere altri problemi oltre a quelli che avevo, tanto per non farmi mancare niente!
Oltre al titolo dinamico, volevo che i risultati della view non fossero mostrati prima della ricerca. Inoltre volevo che fosse visualizzato l'empty text nel caso il termine cercato non appartenesse al vocabolario (invece di " Unable to find term...").
Andiamo con ordine:
1. Titolo dinamico
Nel Header della View ho aggiunto il seguente codice (in "exposed_input['tax']" "tax" è il nome del filtro):
<?php
$view = views_get_current_view();
$count = count($view->result);
if ($count>0) {
$text = $view->exposed_input['tax'];
$text = strip_tags($text);
$text = ucwords(strtolower($text));
$title = 'Cerca aziende nella tua città/provincia/regione: '.$text;
drupal_set_title($title);
}
else {
$title = 'Cerca aziende nella tua città/provincia/regione';
drupal_set_title($title);
}
?>
In questo modo, se la view produce almeno un risultato, il titolo cambia dinamicamente.
Ho inoltre spuntato "Display even if view has no result".
Una domanda: ho filtrato bene l'input? E' giusto usare "strip_tags"
2. Non mostrare i risultati della view prima della ricerca.
- Ho creato un nuovo argomento di tipo Global: Null
- Action to take if argument is not present - Provide default argument - Fixed entry (lasciare il campo vuoto)
- Validator - PHP Code - PHP validate code:
if ($view->exposed_input['tax']) {
return TRUE;
}
Action to take if argument does not validate - Display empty text
3. Empty text
Nel Empty text della View ho inserito il seguente codice:
<?php
$view = views_get_current_view();
if (!$view->exposed_input['tax']['value'] == "") {
return "Sorry, no results were found. Please adjust your search criteria and try again.";
}
?>
Qui ho una domanda più tecnica. L'if presente nel codice dovrebbe essere chiuso da un endif?
4. Visualizzare il contenuto di Empty text invece del messaggio di errore "Unable to find term..."
Qui c'è stato il bisogno di utilizzare una patch trovata su drupal.org. Eccola.
No, perché usa la notazione con le parentesi graffe.
Ah, non lo sapevo. Quindi in generale è sempre così con il php? Cioè se uso un "if" (e non ho un "else") e metto l'istruzione tra graffe non ho bisogno di un "endif"?
Inoltre, è giusto "sanitizzare" l'input in quel modo?
Sì, è così per le graffe.
Per la "sanitizzazione", Drupal ha delle funzioni apposite, per esempio check_plain(), check_markup(), oppure cerca xss nella API.
Quindi con una cosa del genere potrei ritenermi sicuro?
<?php
$view = views_get_current_view();
$count = count($view->result);
if ($count>0) {
$text = $view->exposed_input['tax'];
$text = ucwords(strtolower($text));
$title = 'Cerca aziende nella tua città/provincia/regione: '.$text;
drupal_set_title(check_plain($title));
}
else {
$title = 'Cerca aziende nella tua città/provincia/regione';
drupal_set_title(check_plain($title));
}
?>
Inserendo questa stringa (
<script src='http://www.esempio.it/xss.js'></script>[/codefilter_code]), il testo nell'input rimane esattamente come scritto, non mi trova nulla ovviamente, il titolo della pagina è "Cerca aziende nella tua città/provincia/regione" (perché la view non ha nessun risultato) e l'URL è:
www.esempio.com/cerca2?tax=<script+src%3D'http%3A%2F%2Fwww.esempio.it%2F...
(questo penso sia merito di drupal e views)
Va tutto bene?
Sinceramente non ricordo cosa faccia $view->exposed_input, comunque con check_plain dovresti ottenere il codice HTML "escapizzato". Con check_markup invece scegli quale filtro applicare e puoi anche togliere tutti i tag, lasciando solo la parte di testo.
Ma check_plain lo devo mettere lì oppure quando assegno la variabile?
Cioè:
$text = check_plain($view->exposed_input['tax']);
La filosofia di fondo di Drupal sarebbe che nel DB finisce paro paro quello inserito dall'utente. Solo in visualizzazione si 'sanitizza' l'output.
Diversa la validazione dell'input: se vuoi che un campo contenga solo testo devi rifiutarlo mentre sei ancora in tempo. Il senso è che il dato inserito dall'utente non può essere modificato a sua insaputa, se non è valido gli va risputato in faccia subito.
Angelo Turetta
Quindi seguendo il tuo consiglio (se ho capito bene) dovrei validare l'input per evitare a monte che venga inserito un testo non valido. Ma non è la stessa cosa se "sanitizzo" poi? Alla fine quella è una casella per la ricerca tra le città, e non penso che gli utenti si metteranno a inserire simboli a caso. Almeno non quelli con buone intenzioni. Per tutti gli altri invece è ovvio che mi debba difendere.
Ma al di là di validare prima, è giusto il codice che ho usato?
Sì mi sembra giusto.
essenzialmente, se un campo deve contenere solo numeri o solo lettere, meglio controllare prima.
Se è un campo di testo generico, va bene come hai fatto
Angelo Turetta