Drupal: utilizzare il modulo Rules per generare automaticamente un contenuto

Drupal: utilizzare il modulo Rules per generare automaticamente un contenuto

Utilizzando il modulo Rules è possibile automatizzare alcune delle operazioni da eseguire sul nostro sito Drupal. Ad esempio, un recente progetto prevedeva la necessità di creare ogni giorno un determinato contenuto, e di impostare un campo CCK di tipo data ad un valore predefinito, campo che viene utilizzato per la generazione automatica del titolo del contenuto (tramite il modulo Automatic Nodetitles).

La procedura non è così complessa come forse potrebbe sembrare; vediamo come fare. Quello che vogliamo è che il sistema generi questo contenuto tutte le mattine alle ore 7; una simile operazione può essere effettuata utilizzando una chiamata cron, sarà quindi necessario che cron sia configurato per essere eseguito sul nostro sito quantomeno attorno alle ore 7 di mattina. Nel nostro sito cron è stato configurato per essere eseguito ogni 15 minuti, in particolare ogni 10°, 25°, 40° e 55° minuto di ciascuna ora del giorno.

Il contenuto che dobbiamo creare è la rassegna stampa del giorno, un contenitore vuoto per la precisione, a cui i redattori nell'arco della giornata andranno ad aggiungere i singoli articoli. Quello che imposteremo è l'ora e la data di creazione della rassegna, un campo cck di tipo data che coinciderà con la data del giorno ed il titolo che sarà generato in modo automatico utilizzando la data del giorno ed un prefisso invariante; il percorso URL della nostra rassegna sarà inoltre qualcosa del tipo http://www.esempio.it/rassegna/aaaa/mm/gg e dovrà essere chiaramente univoco.

Andiamo ad abilitare il modulo Rules ed altri moduli utili (tra queste il modulo Token):

Attivare il modulo Rules e Rules UI

Il tipo di regola da aggiungere è di tipo azione / reazione, dove la nostra azione è l'esecuzione di un processo cron:

Admin menu - Aggiungere una regola

Nella scheda che compare, andiamo ad aggiungere la nuova regola "Creazione automatica contenuto" basata sull'evento "Cron maintenance tasks are performed":

Creare la regola

Salviamo quindi il tutto.

Regola salvata

A questo punto così come sta la nostra regola non fa ancora nulla. Come prima cosa aggiungo alcune condizioni di controllo che solo se sono soddisfatte consentono di passare all'azione. Se sul nostro sito il processo cron viene richiamato ogni 15 minut, è chiaro che tale regola potenzialmente potrebbe essere eseguita ogni 15 minuti, ma non posso certo pensare di creare un nuovo contenuto ad ogni esecuzione di cron, in quanto tale contenuto dovrà essere creato uno solo una volta al giorno precisamente attorno alle ore 7 di mattina.

Clicchiamo su "Add a condition" e selezioniamo "Execute custom PHP code":

Aggiungiamo una prima condizione, del codice PHP

Diamo un nome sensato alla nostra condizione ed incolliamo il seguente codice PHP all'interno del campo "PHP Code:"

// Esegue l'azione solo se siamo tra le 7 e le 7:30 di mattina
// H: 24-hour format of an hour with leading zeros (00 through 23)
// i: Minutes with leading zeros (00 to 59)
$ora = date('H');
$minuti = date('i');
if( $ora == 07 && $minuti >= 00 && $minuti <= 30 ) {
  return TRUE;
} else {
  return FALSE;
}

Inseriamo il codice PHP

Il codice è piuttosto semplice, in pratica restituisce vero solo se l'ora di sistema è compresa tra le 7.00 e le 7.30 di mattina.

Salviamo quindi la nostra condizione. Da sola questa condizione però non è sufficiente. In effetti tra le 7 e le 7.30 la procedura cron viene eseguita due volte (una alle 7.10 ed una alle 7.25). Potremmo restringere il range orario nella nostra condizione di controllo, ma preferisco andare sul sicuro ed avere almeno due chiamate cron (sia mai che per qualche motivo la prima chiamata non venga eseguita). Tra l'altro cosa accadrebbe per esempio se già qualcuno avesse già creato manualmente per qualche motivo il contenuto? Andremmo a generare un duplicato, cosa che invece non è possibile per il nostro contenuto (una delle condizioni iniziali è che vi può essere una sola rassegna stampa per ciascun giorno). Per verificare che il contenuto non sia stato già creato, potremmo ad esempio controllare che l'alias URL non esista già. Aggiungiamo quindi un'altra condizione ("Add a condition") e selezioniamo come condizione URL alias exists:

Aggiungiamo una seconda condizione, non deve esistere il percorso url

Dato che conosciamo già come dovrebbe essere il percorso corretto, ovvero il percorso di base www.esempio.it/rassegna/ seguito dalla data del giorno nel formato aaaa/mm/gg, ad esempio:

www.esempio.it/rassegna/2010/01/27

con un po' di codice PHP possiamo assicurarci che non vengano generati duplicati:

Controllo che non esista il percorso URL

Si noti che no negato la condizione, in quanto quello che effettivamente voglio è che l'URL alias non esista già. Ho cerchiato l'opzione "Lingua" in quanto se il percorso fosse stato dipendente dalla lingua selezionata, se ad esempio avessimo avuto il nome del mese al posto del numero, avrei dovuto impostare l'opzione relativa per la lingua (perché altrimenti il mese nell'indirizzo sarebbe stato sostituito con il corrispettivo termine inglese; in quest'ultimo caso la stringa sarebbe stata qualcosa del tipo "<?php echo data('Y/F/d') ?>").

Fin'ora abbiamo impostato solo le condizioni che devono essere soddisfatte affinchè la nostra regola venga eseguita, ma questa regola non fa ancora nulla. Passiamo quindi alle azioni, sezione "DO" ed aggiungiamo una azione. Dovremmo impostare come prima cosa l'utente che desideriamo "compia" l'azione; niente di più semplice, aggiungiamo la prima azione cliccando su "Add an action" e selezioniamo "Load a user account":

Prima operazione da eseguire, caricare l'utente che creerà il contenuto

L'utente che vogliamo crei il contenuto è l'utente "Redazione" che ha un uid = 3. Impostiamo quindi uid = 3:

Impostare i campi per l'utente da selezionare

Questa sarà la nostra prima regola, quindi diamole un peso basso (-5) onde possa restare in cima ed il suo output sia visibile alla regola seguente: la creazione del nuovo contenuto con le credenziali dell'utente appena selezionato. Aggiungiamo quindi una nuova azione di tipo "Add new content", e selezioniamo l'utente appena caricato come utente autore della rassegna:

Seconda azione da eseguire, creare il nuovo contenuto

Nel mio caso il titolo del contenuto non è importante in quanto verrà auto generato (modulo Automatic Nodetitle) al momento del salvataggio del contenuto utilizzando un campo CCK di tipo data (field_data) che andremo a popolare con una azione successiva. Ora che abbiamo creato la nuova rassegna, dovremmo andare a modificare il campo field_data impostandolo pari al valore della data odierna. Nel caso specifico inoltre dovevano essere impostati dei campi numerici che venivano utilizzati per indicare lo stato di lavoro sulla rassegna stampa. Si possono seguire diverse modalità per eseguire queste azioni, ovvero intervenire singolarmente sui singoli campi CCK utilizzando le relative azioni messe a disposizione da Rules, oppure è possibile eseguire del codice PHP che faccia tutto il lavoro. Il bello di Rules in effetti è anche questo, ovvero non vi è un solo modo (cosa che vale del resto anche per Drupal) per eseguire una stessa operazione. Io ho optato per eseguire del codice PHP.

Aggiungo quindi una azione che esegua del codice PHP personalizzato.

Terza azione da eseguire, eseguire del codice php personalizzato

Ecco il codice che andrò ad inserire:

// Imposto la data di creazione (nessuna timezone impostata)
$node_added->field_data[0]['value'] = date('Y-m-d H:i:s');
// Imposto lo stato di bozza
$node_added->field_rassegna_stato[0]['value'] = 0;
// Imposto lo stato di invio della newsletter
$node_added->field_rassegna_newsletter[0]['value'] = 0;
// salvo le modifiche al nodo
node_save($node_added);

e questa la scheda configurata:

Impostazione del codice PHP personalizzato

Per finire ho aggiunto un'ultima azione che salva un messaggio nel log di sistema. Ecco quindi una veduta d'insieme della regola appena creata:

Una vista d'insieme alla regola che abbiamo creato

Con la procedura che abbiamo appena configurato, ogni mattina tra le 7 e le 7.30, all'esecuzione del processo cron, verrà generato il contenuto che conterrà la rassegna della giornata.