Personal tools
You are here: Home Aiuti ed Info Manuale di Plone 2 8. Gestire il controllo di flusso (workflow)
To change the maximal image width select one of the following:

8. Gestire il controllo di flusso (workflow)

Document Actions

Capitolo 8: Gestire il controllo di flusso (workflow)

Uno dei punti di forza di Plone è lo strumento per il controllo di flusso. Il controllo di flusso ci porta in uno dei temi centrali della gestione di contenuti che è la separazione di logica, contenuto e presentazione. Questo capitolo tratta nel dettaglio il controllo di flusso.

Il capitolo inizia trattando alcune definizioni chiave correlate al controllo di flusso e agli strumenti coinvolti in modo da poter iniziare a concettualizzare il controllo di flusso. Una volta chiariti i concetti discutiamo di come aggiungere e modificare il proprio controllo di flusso.

In questo capitolo presentiamo alcune semplici modifiche che è possibile fare al controllo di flusso predefinito di Plone. Una serie di esempi aiuta a realizzare obiettivi come la creazione di notifiche, lo spostamento di contenuti e così via. Infine mostriamo le più avanzate funzionalità di sviluppo del controllo di flusso e i più importanti strumenti disponibili.

Cos'è il controllo di flusso?

Il Controllo di flusso è una catena di azioni che avvengono su qualcosa per raggiungere uno scopo. Il controllo di flusso esprime spesso delle regole di lavoro esistenti. Ogni attività ha sue differenti regole e sistemi di amministrazione che devono essere svolti da un'azienda. Alcuni esempi possono essere:

  • Prima che l'orario di un dipendente sia approvato deve essere visto e controllato da un supervisore.
  • In una fabbrica di apparecchi per ogni oggetto costruito, agli utenti deve essere comunicata ogni variazione dell'ordine e dell'oggetto appena ciò sia stabilito in fabbrica.
  • Prima di pubblicare una pagina di un sito web questa dev'essere approvata dal responsabile del marketing, approvata dal responsabile del sito e tradotta da un traduttore.

Il controllo di flusso separa la logica di queste regole di affari e uniforma il modo di concepire questi cambiamenti. Separando la logica, è poi facile per gli affaristi cambiare l'applicazione per centrare i loro obiettivi e le loro regole di affari. Spesso le applicazioni provano a forzare un controllo di flusso su un lavoro perché tale controllo è codificato dentro l'applicazione stessa.

Capire il controllo di flusso in Plone

Lo strumento del controllo di flusso di Plone fornisce alcune funzionalità e limitazioni che sono decisive per capire il controllo di flusso di Plone stesso. Il prodotto per il controllo del flusso usato da Plone è il DCWorkflow che un prodotto a sorgente aperto rilasciato dalla Zope Corporation. Sono disponibili altri strumenti per il controllo di flusso ed alcuni stanno per essere incorporati in Plone, come OpenFlow (http://www.openflow.it - prodotto da italiani! n.d.t.). Comunque, per il momento, DCWorkflow è sufficentemente semplice e potente e fornisce tutte le funzionalità di cui hanno bisogno la maggior parte degli utenti.

Il DCWorkflow assume che vi sia un oggetto nel sistema che sia sottoposto al controllo di flusso - per esempio un pezzo di contenuto o un elemento. Assume poi che oggetti dello stesso tipo siano sottoposti al medesimo controllo di flusso. Riproponendo un tipo di contenuto (vedere il Capitolo 11 per ulteriori informazioni su questo argomento) si possono avere contenuti simili sottoposti a controlli di flusso differenti.

Il sistema DCWorkflow è incluso in Plone e quindi non vi è nulla di extra da installare. Nella ZMI (l'Interfaccia di Gestione Zope Management Interface) è rappresentato dall'oggetto portal_workflow.

Concettualizzare un Controllo di Flusso

Prima di spiegare un controllo di flusso spieghiamo alcuni semplici elementi della terminologia: stati e transizioni.

Uno stato è una informazione su un elemento di contenuto in un particolare istante. Esempi di stato sono privato, pubblicato, in revisione e bozza. Tutti i controlli di flusso hanno come minimo uno stato di partenza con cui parte ogni contenuto. Il controllo di flusso passa poi il contenuto attraverso una serie di stati sia per l'intervento dell'utente che per qualche processo automatico. Quando in contenuto raggiunge uno stato finale, rimane in quello stato per un lungo periodo (normalmente per sempre). Il contenuto può arrivare ad uno o più differenti stati finali nel processo di un controllo di flusso.

Per spostare da uno stato ad un altro un certo pezzo di contenuto è necessaria una transizione. Una transizione congiunge uno stato iniziale con uno stato finale. Una transizione può avere molte funzionalità associate, come vedremo più avanti, ma, per il momento, ci basta sapere che una transizione sposta un contenuto da due stati. Una transizione viene normalmente impostata da qualche forza esterna come il click di un utente su un pulsante di una pagina web o uno script che interagisce con una pagina.

Visualizzare un controllo di flusso, specie quando si parla di qualcosa di nebuloso come contenuto, può confondere un po'. Può aiutare il pensare ad una scadenza giornaliera. Un caso così, l'esempio seguente mostra il controllo di flusso di un conto di una carta di credito, si è fortunati se lo si riceve ogni mese:

  1. La compagnia emittente prepara un conto e ce lo invia tramite e-mail.
  2. Riceviamo il conto e lo mettiamo sulla scrivania. Talvolta il conto sta li sulla scrivania per qualche tempo in attesa della fine del mese. Occasionalmente è necessario chiedere spiegazioni a qualcuno a proposito di certe spese del tipo "Cos'erano quei vestiti che hai comperato?".
  3. Per qualsiasi domanda o problema importante si torna alla compagnia emittente causando talvolta l'emissione di un nuovo conto (sebbene questo avvenga molto raramente).
  4. Normalmente, alla fine del mese, quando si fanno tutti gli addebiti, poi si paga il conto.

Da questo quindi si possono ricavare alcuni stati. Guardando i passi precedenti vediamo che non è proprio necessario creare altri stati per ricevere il conto, inclusi l'aprirlo e metterlo sulla scrivania. Ugualmente non dobbiamo preoccuparci per ogni movimento che arriva. Anche se questi sono tutti passi validi che realmente avvengono, provare a fare un controllo di flusso per tutti gli stati può essere macchinoso. É possibile, piuttosto, riassumere il controllo di flusso nei seguenti stati:

Emissione
Il conto della carta di credito viene preparato per esserci spadito.
Revisione
Riceviamo il conto della carta di credito e lo mettiamo sulla nostra scrivania per controllarlo
Pagamento
Il conto della carta di credito viene pagato, messo in archivio e dimenticato per sempre.

Ora che abbiamo estratto gli stati possiamo pensare ai cambiamenti che avvengono. Per ugnuno di questi stati dev'esserci almeno una transizione che possa cambiare da uno stato ad un altro il conto:

Invio
La banca spedisce il conto della carta di credito
Pagamento
Paghiamo il conto della carta di credito.
Rigetto
C'è qualcosa di sbagliato nel conto e non viene approvato.

La Figura 8-1 mostra questo insieme di transizioni e di stati. Nella figura i riquadri rappresentano gli stati con il loro nome scritto dentro. Le frecce rappresentano le transizioni da uno stato al prossimo con il nome della transizione in corsivo.

../pb2_en/img/3294f0801scrap.png

Figura 8-1. Una semplice macchina degli stati per il pagamento dei conti delle carte di credito.

Abbiamo quindi estratto questi processi di lavoro per pagare il conto di una carta di credito con un controllo di flusso. Il prossimo passo è pensare ai ruoli ed alla sicurezza relative al conto della nostra carta di credito. Questo controllo di flusso ora contiene la logica del lavoro per una applicazione che debba processare le carte di credito.

Capire Ruoli e Sicurezza nel Controllo di Flusso

In qualsiasi sistema complesso si hanno utenti di tutti i ruoli e gruppi. I ruoli in Plone danno una grande flessibilità sulla sicurezza ma possono anche renderla più complicata. Il Capitolo 9 tratta della sicurezza, dei ruoli locali, dei gruppi ma in questa sezione trattiamo alcuni punti chiave sul come questi argomenti sono correlati al controllo di flusso.

Quando un pezzo di contenuto passa da uno stato ad un altro del controllo di flusso, il processo di controllo può cambiare le impostazioni di sicurezza di quel contenuto. Le impostazioni di sicurezza determinano quale utente può effettuare quella azione su quel pezzo di contenuto. Manipolando le impostazioni di sicurezza del controllo di flusso, è possibile causare la modifica della sicurezza di un pezzo di contenuto durante il suo ciclo vitale. Gli utenti provenienti da sistemi statici o da Zope spesso sono confisi in quanto, in Zope, tutti i pezzi di contenuto hanno le medesime impostazioni di sicurezza durante l'intera loro vita.

Ritornando all'esempio, noi possiamo interferire con le impostazioni di sicurezza del conto della carta di credito. Un modo per rappresentarlo è quello di produrre una tabella che espanda in termini generici la sicurezza delle transizioni che possono avvenire in ciascuno dei vari stati, come mostrato in Tabella 8-1.

Tabella 8-1. Le Transizioni e le Entità che possono farle

Stato Noi Banca
Emissione   Invia
Revisione Paghiamo Rigetta
Pagamento    

A questo punto nella Tabella 8-1 vediamo le transizioni e chi può farle. Non abbiamo ancora pensato all'accesso che deve effettuare ciascun utente per realizzare una azione su un oggetto in ogni punto. Per esempio in quale punto è possibile che qualcuno modifichi il conto, e quando può essere visto questo? Queste sono dette azioni nella terminologia Plone, come viene mostrato nella Figura 8-2. Speriamo di avere solo noi l'accesso agli ordinativi della nostra carta di credito! Ugualmente in ogni passaggio la banca è in grado di vedere il conto della carta di credito e di rispondere a domande su di essp.

Tabella 8-2. Le Azioni e le Entità che possono farle

Stato Noi Banca
Emissione   Vede, Modifica
Revisione Vediamo Vede
Pagamento Vediamo Vede

In realtà, quando viene emesso, non ci è possibile modificare il conto della nostra carta di credito, solo la banca lo può fare. Possiamo mandare di ritorno il nostro conto respingendolo ma la banca non è detto che voglia le nostre modifiche. In una situazione come questa assumiamo che la banca sia proprietaria del conto della carta di credito. Ciò dimostra il concetto detto possesso. Possiamo ricevere conti di carte di credito diverse da banche diverse ed in ciascun caso possiamo pensare alla banca come alla proprietaria del conto. Ciascuna banca possiede il proprio conto di carta di credito ma la banca A non possiede il conto della banca B. La Tabella 8-3 combina le transizioni con le azioni cambiando rispettivamente i termini Noi e Banca con Pagante e Possessore

Tabella 8-3. Le Transizioni e le Azioni Combinate, più i Ruoli della gente

Stato Pagante Possessore
Emissione   Invia, Vede, Modifica
Revisione Paga, Rigetta, Vede Vede
Pagamento Vede Vede

Ovviamente questo è un esempio alquanto limitato, ma illustra com'è possibile applicare un controllo di flusso a degli stati base. Qui potrebbero avvenire altri tipi di transizione, per esempio, saremmo più che felici se qualcun altro pagasse il conto della carta di credito per noi, ma ciò è talmente improbabile che non lo aggiungeremo al controllo di flusso o alla sicurezza.

Prima di mostrare come creare e modificare il controllo di flusso vediamo il controllo di flusso predefinito di Plone.

Introduzione al controllo di flusso di Plone

Plone è fornito di un insieme di controlli di flusso predefiniti per il nostro sito. Questi controlli di flusso prevedono una percorso logico nello spostamento dei contenuti dentro un sito Plone. Un sito Plone standard ha due controlli di flusso: il controllo di flusso normale e il controllo di flusso delle cartelle. Le seguenti sezioni trattano a turno ciascuno di questi.

Controllo di flusso predefinito (Default Workflow)

Nel Capitolo 3 abbiamo trattato il controllo di flusso e le impostazioni della pubblicazione dei contenuti predefiniti. Abbiamo discusso di ciascuno stato del controllo di flusso. Comunque una immagine è meglio di migliaia di parole così la Figura 8-2 mostra gli stati del controllo di flusso predefinito fornito con Plone.

../pb2_en/img/3294f0802scrap.png

Figura 8-2. Il Controllo di Flusso predefinito fornito con Plone

La Figura 8-2 mostra i principali stati e transizioni. Questa immagine ha una linea grigia punteggiata che rappresenta una sorta di divisione della sicurezza. A sinistra della linea è la parte dove normalmente i possessori del contenuto interagiscono con il contenuto stesso. A destra di quella linea c'è la parte dove sono i revisori che interagiscono con i contenuti.

Nota

Il possessore di un contenuto è la persona che ha creato in origine il contenuto. Un possessore è un particolare collaboratore di un siti Plone. Sebbene esisteno molti membri in un sito solo una persona può essere il possessore di un pezzo di contenuto di un sito Plone. Siccome il ruolo di possessore viene determinato quando un oggetto viene creato, il ruolo di possessore è un ruolo speciale.

Come nell'esempio della carta di credito, esiste un insieme di impostazioni di permessi per il controllo di flusso predefinito. La Tabella 8-4 mostra tutti i permessi e gli stati.

Tabella 8-4. I Permessi predefiniti del Controllo di Flusso

Stato Anonimo Autenticato Possessore Manager Revisore
Proposto View View View Edit Edit
Privato     Edit Edit View
Pubblicato View View View Edit View
Visibile View View Edit Edit View

View fa riferimento ai seguenti permessi: Access Contents Information e View

Edit fa riferimento al seguente permesso: Modify Portal Content

Come si può vedere nella Tabella 8-4, l'impostazione predefinita è che solo quando un contenuto è nello stato privato è certamente nascosto a qualsiasi altra persona. Quando un contenuto è nello stato Pubblicato solo un manager può modificarlo. In una prossima sezione, Modificare i permessi, vedremo come cambiare facilmente questi permessi via web.

Controllo di Flusso delle Cartelle

Abbiamo trattato anche il controllo di flusso delle cartelle nel Capitolo 3 quando abbiamo parlato la pubblicazione dei contenuti. Comunque, come abbiamo notato in quel capitolo, non esiste lo stato Proposto (Pending) per le cartelle. Abbiamo invece un controllo di flusso più semplice, come mostra la Figura 8-3.

../pb2_en/img/3294f0803scrap.png

Figura 8-3. Il Controllo di Flusso predefinito per le cartelle fornito con Plone

Altri Controlli di Flusso

In un sito Plone sono disponibili numerosi controlli di flusso, inclusi controlli privati, controlli per comunità, controlli per la pubblicazione diretta (one-step workflow n.d.t.) e così via. ZopeZen ha un suo controllo di flusso come pure PloneCollectorNG. DCWorkflow ha ben quattro controlli di flusso.

Attualmente vi sono due controlli di flusso nel prodotto PloneWorkflows del progetto collettivo in SourceForge (http://sf.net/projects/collective): il controllo di flusso per comunità e quello per la pubblicazione diretta. Il primo è molto simile al controllo di flusso predefinito di Plone con poche variazioni. Il controllo di flusso per la pubblicazione diretta ha solo due stati: Privato e Pubblicato.

Al momento non è semplice installare e disinstallare i controlli di flusso, e non c'è un modo semplice per far transitare i contenuti da uno stato ad un altro. Per esempio se si installa il controllo di flusso per la pubblicazione diretta su uno stato già esistente, sarà necessario aggiustare gli stati di tutti gli oggetti per metterli in uno degli stati nuovi. Questa è probabilmente una situazione semplice, ogni cosa nello stato Pubblicato può rimanere com'è, mentre tutto il resto deve passare allo stato Privato.

Aggiungere e modificare il Controllo di Flusso

Ora che abbiamo parlato del controllo di flusso predefinito arriviamo al punto chiave che con ogni probabilità abbiamo già in mente: Come possiamo cambiare le impostazioni predefinite? Ebbene, come con quasi tutto in Plone, è possibile aggiungere, modificare e cancellare tutto di un controllo di flusso tramite la ZMI. Lo strumento che gestisce i controlli di flusso è il portal_workflow. Nelle sezioni che seguono vedremo come vengono assegnati i controlli di flusso e poi entreremo nei dettagli di tutte le sue impostazioni.

Impostare il Controllo di Flusso per un Tipo di Contenuto

Dopo aver cliccato su portal_workflow possiamo vedere un elenco di assegnamenti dei controlli di flusso. Una caratteristica del DCWorkflow è che ogni tipo di contenuto ha uno ed un solo controllo di flusso a lui assegnato; la Figura 8-4 mostra questi assegnamenti.

../pb2_en/img/3294f0804.png

Figura 8-4. L'elenco dei controlli di flusso per tipo

In questa pagina vediamo un elenco con ogni tipo di contenuto ed il controllo di flusso che vi è applicato. Se non è specificato alcun controllo di flusso (in altre parole, se il valore è a blank), allora non viene applicato alcun controllo. Come esempio, l'impostazione predefinita per il tipo Portal Site è a blank. Sicuramente non si desidera provare a far transitare ad altro stato il sito Plone medesimo ma solo gli oggetti contenuti. Se il valore è Default, a questo tipo di contenuto verrà applicato il controllo di flusso predefinito in cima alla pagina. Nella Figura 8-4 viene applicato il controllo di flusso folder_workflow ai tipi tema e folder, mentre per tutti gli altri tipi viene applicato il controllo plone_workflow. I nomi dei controlli di flusso riferiscono al nome degli oggetti di controllo importati o creati con lo strumento di controllo del flusso. Per ulteriori informazioni sui controlli di flusso disponibili, selezionare la scheda Contents. Questa apre l'elenco dei controlli di flusso che vengono letti nel sistema, come mostra la Figura 8-5.

../pb2_en/img/3294f0805.png

Figure 8-5. I Controlli di Flusso disponibili

È possibile aggiungere controlli di flusso cliccando sul pulsante Add Workflow. Questo apre l'elenco dei controlli disponibili, per crearne uno selezionare un tipo di controllo di flusso ed inserire un nome per esso. Per creare un controllo di flusso che sia vuoto ma che sia configurabile via web, selezionare dc_workflow e dargli un nome appropriato; per esempio inserire mio_workflow.

Modificare un Controllo di Flusso

Nella scheda Contents è possibile cliccare su un controllo di flusso per accedere alla schermata della gestione di quel workflow: a tutti gli stati, transizioni e funzionalità associate. La serie di schede in cima alla pagina mostrano molto bene le funzionalità del controllo di flusso: Stati, Transizioni, Elenco lavori, Script e Permessi. Giriamo ora in tutte queste schede ed in alcune altre opzioni che sono disponibili. Se non altrimenti specificato tutte le prossime schede sono accessibili da questa pagina principale del controllo di flusso.

La creazione o la modifica di un controllo di flusso può richiedere molti click e può fare un po' di confusione. Se siamo sviluppatori ci terremo all'uso del file system e volendo, fare tutto con Python, parleremo di questo più avanti in questo capitolo nella sezione Scrivere un Controllo di Flusso in Python.

Impostare lo Stato Iniziale

Per impostare lo stato iniziale andiamo nella scheda States dove vediamo gli stati disponibili e dove possiamo notare che, vicino ad uno, c'è un asterisco, come mostra la Figura 8-6.

../pb2_en/img/3294f0806.png

Figura 8-6. Impostare lo stato iniziale per questo controllo di flusso

Impostiamo lo stato iniziale per il nostro controllo di flusso spuntando il box accanto allo stato e cliccando poi Set Initial State. Qualsiasi contenuto generato con questo controllo di flusso avrà quello stato iniziale. Qualsiasi contenuto già esistente rimane nello stato in cui si trovava; cambiare lo stato iniziale successivamente non modifica lo stato. Per ciascun controllo di flusso è possibile impostare solo lo stato iniziale.

Come impostare lo stato iniziale a privato

In molti siti può avere senso che un contenuto non venga mostrato o che non sia accessibile agli utenti, se non ai soli amministratori o ai possessori, se non dopo che sia stato completato. La maniera migliore per ottenere questo è quello di impostare lo stato iniziale degli oggetti a qualche valore che garantisca questo grado di sicurezza: per esempio, privato. Nello stato privato solo i revisori, i manager e i possessori possono vedere l'elemento.

Per impostare lo stato predefinito a privato dalla ZMI, cliccare su portal_workflow e selezionare la scheda Contents. Poi cliccare plone_workflow, selezionare la scheda States e poi scegliere lo stato predefinito spuntando il box accanto a private. Cliccare infine il pulsante Save Changes. Ora i nuovi contenuti nascono nello stato private e non sono più accessibili da tutti.

Attenzione!

nell'originale c'è un errore? dice di spuntare accanto a visible - lallo

Modificare gli Stati

La scheda States elenca gli stati che sono definiti in questo controllo di flusso. All'inizio del capitolo abbiamo detto che uno stato rappresenta un oggetto in un determinato istante. Ogni stato ha un ID unico che usualmente è un semplice verbo come in revisione o pubblicato (pending, published). Per aggiungere uno stato inserire un ID e cliccare Add in fondo alla pagina.

Sono visibili anche le seguenti opzioni:

Title
Il titolo dello stato viene mostrato nel sito Plone e dev'essere quindi user-friendly.
Description
La descrizione può essere una lunga descrizione dello stato. Non viene attualmente mostrata agli utenti ma potrebbe esserlo in futuro.
Possible transitions
Questa elenca tutte le possibili transizioni che possono intervenire sullo stato. Quest'elenco contiene elementi solo se realmente esiste almeno una transizione nel sistema. Selezionare semplicemente le transizioni di cui abbiamo bisogno per questo stato. Selezionando una transizione per questo stato stiamo scegliendo che il punto iniziale per questa transizione sia questo stato.

Per modificare uno stato, inserire le modifiche e premere Save per confermare. La scheda Permission si aprirà con i permessi che verranno applicati ad un oggetto quando si troverà in questo stato. Ciò può significare il cambiamento dei permessi su un oggetto quando arriva (transiziona) a questo stato. Il modulo è sufficentemente auto esplicativo; per abilitare l'utente anonimo a vedere l'oggetto, spuntare il box che corrisponde a View ed ad Anonimous e cliccare Save, come mostra la Figura 8-7.

../pb2_en/img/3294f0807.png

Figura 8-7. Pagina dei permessi degli stati

Se si cambiano i permessi per un certo stato del controllo di flusso nasce un problema che è necessario risolvere. Ogni contenuto esistente in quello stato non ha impostati i nuovi permessi. Quel contenuto ha i permessi del vecchio controllo di flusso ed è necessario aggiornarli. Quando abbiamo finito di fare tutte le modifiche andiamo alla pagina principale del controllo di flusso e clicchiamo su Update Security Settings, come mostra la Figura 8-4. Questo aggiornamento può prendere un bel po' di tempo in quanto dipende dal numero di oggetti su cui si interviene.

La scheda Variables consente di assegnare un valore ad una variabile quando l'oggetto è in questo stato. Il controllo di flusso determina l'elenco delle variabili disponibili per ciascun stato. Per maggiori informazioni vedere la sezione Modificare le variabili

Modificare le transazioni

La scheda Transitions elenca le transizioni che esistenti in questo controllo di flusso. All'inizio del capitolo abbiamo detto che una transizione rappresenta i possibili cambiamenti dello stato di un oggetto. Ciascuna transizione ha lcune variabili che sono mostrate nella pagina di sommario. Per aggiungere una transizione inserire un ID e cliccare Add in fondo alla pagina, come mostra la Figura 8-8.

../pb2_en/img/3294f0808.png

Figura 8-8. Pagina di dettaglio della transizione

Se ora clicchiamo su una transizione apriamo i seguenti dettagli per questa transizione:

Title
È il titolo di questa transizione.
Description
La descrizione dettagliata per questa transizione.
Destination state
È lo stato che sarà raggiunto dopo questa transizione. Lo stato sorgente iniziale è definito assegnando la transizione allo stato.
Trigger type
Indica come verrà svolta questa transizione. Automatic significa che avviene appena un oggetto arriva a questo stato. Initiated by user action è la scelta più comune ed è che un utente debba attivare la transizione cliccando un collegamento.
Script (before)
Esegue questo script prima che avvenga la transizione.
Script (after)
Esegue questo script dopo che la transizione è avvenuta.
Guard
È il grado di sicurezza per questo stato (spiegata brevemente).
Display in actions box
Indica come viene mostrata questa transizione in Plone. Inserendo un valore assicura che la transizione sia inserita come azione. Si potrà quindi ottenere la transizione come azione chiamando le azioni.

Tra questi valori il Destination state è davvero interessante. Anche se abbiamo sostenuto in precedenza che le transizioni normalmente cambiano uno stato, ciò non è richiesto. Siccome ogni transizione è in grado di lanciare script e scrivere qualcosa nella history, a volte è utile non cambiare stato. Per un esempio di questo modo d'uso, vedere la sezione Uso del controllo di flusso per tracciare le modifiche, più avanti in questo capitolo. Se vogliamo che la transizione cambi lo stato, selezioniamo il nuovo stato come stato di destinazione.

Una transizione può avere più punti di partenza ma solo una destinazione; se abbiamo bisogno di avere destinazioni multiple sono necessarie altrettante transizioni. Possiamo specificare script da eseguire prima o dopo la transizione. Due semplici esempi sono muovere un oggetto in un controllo di flusso e inviare una notifica e-mail. La sezione Problemi comuni ed esempi tratta entrambi i casi.

Prima che qualsiasi transizione possa essere eseguita, una sentinella di guardia controlla l'intera transizione assicurando che l'utente che ha lanciato la transizione abbia i diritti per farlo. La sentinella è composta dai seguenti tre componenti:

Permission(s)
Sono i permessi richiesti. Permessi multipli devono essere separati da punti e virgola (;).
Role(s)
Sono i ruoli richiesti. Ruoli multipli devono essere separati da punti e virgola (;).
Expression
È una espressione del controllo di flusso. Per ulteriori informazioni vedere la sezione Modificare le espressioni del controllo di flusso più avanti in questo capitolo. Per ciascun valore specificato la sentinella deve valutarla a true prima di poter continuare. Se la prova con uno di questi valore fallisce, la transizione non viene eseguita. Si noterà che solitamente le sentinelle hanno specificati solo uno o due valori.
Modificare le variabili

La scheda Variables elenca le variabili che sono state create e modificate nel controllo di flusso. Non ne abbiamo parlato molto finora perché ci siamo concentrati sugli stati e sulle transizioni. Questa sezione tratta delle variabili.

Non sempre è possibile, e non si consiglia di provarlo, incapsulare tutte le informazioni necessarie in un controllo di flusso, semplicemente usando gli stati e le transizioni. Ma è possibile usare le variabili per contenere alcune informazioni correlate al controllo di flusso. Come, nel precedente esempio della carta di credito, il conto può essere pagato in svariati modi (Servizio di Internet banking, assegno e così via). È possibile conservare l'ammontare del metodo (100 Euro, per esempio) in una variabile. Ad un rigetto o modifica del conto questo ammontare dovrà essere aggiornato. Lo scopo di una variabile è di avere qualcosa che cambia al cambiare di ogni stato e transizione.

Ritornando alla pagina principale del controllo di flusso, clicchiamo la scheda Variables per vedere l'elenco di tutte le variabili. Per aggiungere una variabile, inserire l'ID per la variabile e premere su Add in fondo alla pagina. Per determinare in qualsiasi momento in quale stato si trovi un oggetto, il DCWorkflow contiene lo stato corrente in una variabile dell'oggetto. Il nome predefinito di questa variabile è review_state.

Nota

Se si ha la necessità di cambiarlo perché va in conflitto con qualche altro nome, è possibile farlo in fondo alla pagina. Questo causerà però la perdita dello stato da parte di tutti gli oggetti attuali, quindi porre molta attenzione nel cambiare questo valore.

Ogni variabile del controllo di flusso possiede le seguenti proprietà:

Description
È la descrizione della variabile
Make available to catalog
Queste variabili vengono messe in un'elenco che può essere mostrato al catalogo. Non inserisce indici o metadati nel catalogo, questo dev'essere fatto manualmente.
Store in workflow
Determina se le informazioni debbano essere conservate nel controllo di flusso piuttosto che nell'oggetto.
Variable update mode
Determina quando aggiornare la variabile
Default value
Determina un valore predefinito formato stringa
Default expression
È il valore predefinito tramite una espressione. Se è presente viene usato al posto di Default value (per maggiori informazioni vedere la sezione Modificare le espressioni del controllo di flusso più avanti nel capitolo).
Info. guard
Sono impostazioni di sicurezza per questa variabile. Queste impostazioni di sentinella sono simili a quelle analoghe delle transizioni, comunque qui la sentinella interviene quando si accede alla variabile.
Modificare l'elenco dei lavori

La scheda Worklist consente l'accesso a tutti gli elenchi dei lavori che sono assegnati in questo controllo di flusso. Un elenco lavori (worklist) è un metodo per interrogare il controllo di flusso per informazioni a proposito dei suoi numerosi oggetti. Per esempio, vorremmo chiedere facilmente al controllo di flusso tutti i crediti della nostra carta di credito che non abbiamo ancora pagato .

Per aggiungere un worklist inserire un ID e premere Add. Ciascun elenco lavori ha le seguenti proprietà:

Description
È la descrizione dell'elenco lavori.
Cataloged variable matches
È il valore a cui deve corrispondere la variabile per essere inserita in questo elenco lavori. La variabile corrispondente è la variabile di stato del controllo di flusso contenuta nell'elenco delle variabili (il nome della variabile predefinito per questa variabile è review_state).
Display in actions box
Sono informazioni da mostrare nell'interfaccia utente. l'inserimento di un valore assicura che la transizione sia inserita come azione. Sarà quindi possibile ottenere questa transizione come azione chiamando le azioni.
Guard
È una sentinella all'accesso di quest'elenco lavori.

Ritornando all'esempio della carta di credito, se vogliamo sapere tutti i conti che dobbiamo ancora approvare, potremmo mettere queste informazioni in un worklist. Per prima cosa la variabile review_state dovrà contenere lo stato corrente per ciascun elemento. Tutti i conti della carta di credito che devono essere approvati devono essere nello stato review. Poi aggiungiamo un elenco lavori con il nome di review_queue dove il valore della variabile sia pending. Possiamo quindi chiamare l'elenco di tutti gli elementi in review_queue.

Sebbene l'elenco lavori sia un modo conveniente per conservare informazioni, Plone non lo usa. Plone usa invece ZCatalog per chiamare gli oggetti che sono sottoposti a controllo di flusso. Siccome gli elenchi lavori di DCWorkflow usano lo strumento di catalogazione, il risultato è il medesimo.

Modificare gli Script

La scheda Scripts elenca gli script disponibili in questo controllo di flusso. Questo elenco è una reale cartella standard nella ZMI e vi si può aggiungere quasi ogni cosa. Ma in questa cartella dovremo aggiungere solo script Python e l'unica ragione per farlo dovrebbe essere aggiungere uno script per una gestione avanzate delle transizioni.

Per aggiungere uno script dalla scheda Scripts selezionare Scripts dal menù a cascata e dare un ID allo script. Lo script è passato ad uno ed un solo oggetto, che è l'oggetto base del controllo di flusso delle espressioni; per ulteriori informazioni su questo oggetto vedere la sezione Modificare gli script del Controllo di Flusso più avanti nel capitolo. Per esempio, se vogliamo accedere all'attuale oggetto nel controllo di flusso, possiamo usare uno script Python come il seguente:

##parameters=state_change
obj = state_change.object

Ciò che succede in questo script è cosa da sviluppatori, noi possiamo far girare quasi ogni cosa qui. Possiamo controllare eventi, e accedere ad altri controlli di flusso e transizioni. Per degli esempi di script vedere le sezioni Inviare notifiche via E-Mail e Spostare oggetti più avanti nel capitolo. Quando viene eseguito lo script, viene eseguito con l'utente che avvia la transizione. Se è necessario eseguirlo come qualcun altro, è possibile assegnargli un ruolo proxy. Ritornando alle transizioni, è possibile assegnare questo script ad un numero arbitrario di transizioni nelle opzioni script (after) e script (before). È possibile avviare lo script sia prima che dopo una transizione.

Modificare i Permessi

La scheda Permissions elenca i permessi gestiti da questo controllo di flusso. Abbiamo già visto questi permessi esaminando gli stati. In questa scheda si imposta l'elenco dei permessi gestibili da quegli stati. Per aggiungere un nuovo permesso, selezionare il permesso dall'elenco a cascata e selezionare Add.

É possibile modificare un documento pubblicato?

Ebbene, nel controllo di flusso predefinito, se non si ha il ruolo di manager non è possibile modificare un documento pubblicato. Se si abilita il possessore del documento a modificarlo si dovrà poi sottoporlo nuovamente a revisione. Comunque questa sembra una richiesta comune ed è banale soddisfarla. Nalla ZMI cliccare portal_workflow e selezionare la scheda Contents. Poi cliccare plone_workflow e selezionare la scheda States. Cliccare infine su published e scegliere la scheda Permission. Spuntare il box che corrisponde a concedere all'owner la possibilità di modificare i contenuti del portale.

*Insert 3294s0801.tif*

Cliccare su Save Changes per salvare i nostri permessi. Siccome abbiamo alterato le impostazioni della sicurezza dobbiamo cliccare su portal_workflow, selezionare la scheda Contents e poi cliccare su Update security settings. Questo aggiorna tutti gli oggetti del nostro sito ed assicura che i (nuovi) permessi vengano applicati agli oggetti esistenti. Ora i possessori possono modificare i loro documenti anche quando essi sono nello stato published.

Modificare gli script del Controllo di Flusso

Gli script danno allo sviluppatore l'opportunità di intervenire sulla logica di una transizione. Questa logica può essere quasi ogni cosa si desidera. Potremmo controllare che siano rispettate alcune condizioni (per esempio, è stato fatta la correzione degli errori ortografici del documento?) o se sono state effettuate alcune delle azioni speciali. Quando l'oggetto è sottoposto a transizione viene chiamato lo script.

Quando viene chiamato uno script, gli viene passato un parametro extra. Questo parametro extra fornisce l'accesso a tutti i tipi di elementi e attributi correlati alla transizione. Questo parametro è denominato state_change ed ha i seguenti attributi:

status
è lo stato del controllo di flusso
object
È l'oggetto sottoposto a transizione nel controllo di flusso
workflow
È l'oggetto workflow corrente dell'oggetto sottoposto a transizione
transition
È l'oggetto transizione che viene eseguito
old_state
È lo stato originario dell'oggetto
new_state
È lo stato di destinazione dell'oggetto
kwargs
Sono gli argomenti parole-chiave passate al metodo doActionFor
getHistory
È un metodo che non prende parametri e ritorna una copia della history degli oggetti del controllo di flusso.
getPortal
È un metodo che non prende parametri e ritorna l'oggetto Plone root
ObjectDeleted(folder)
Dice al controllo di flusso che l'oggetto che sta per essere sottoposto a transizione è stato cancellato; prende l'oggetto a cui si desidera ritorni l'utente. Passa all'eccezione la cartella a cui si vuol redirigere l'utente (vedere la sezione Spostare oggetti più avanti nel capitolo)
ObjectMoved(newObject, newObject)
Dice al controllo di flusso che l'oggetto che sta per essere sottoposto a transizione è stato spostato. Passa all'eccezione la cartella a cui si vuol redirigere l'utente (vedere la sezione Spostare oggetti più avanti nel capitolo)
getDateTime
È un metodo che non prende parametri e ritorna l'oggetto DateTime relativo alla transizione

Per esempio, per sapere a quale sia lo stato di destinazione della transazione e in che momento, è necessario un oggetto Script (Python) come il seguente, che ci darà proprio questa informazione. Lo script scrive le informazioni relative alla transizione nel file di log:

##parameters=state_change
st = 'From %s to %s on %s' % (
    state_change.old_state,
    state_change.new_state,
    state_change.getDateTime())
context.plone_log(st)

Consiglio

Mentre si scrive un oggetto Script (Python) è possibile aver bisogno di scrivere in un file di log per facilitare la correzione degli errori (debug). Uno script denominato plone_log fa proprio questo, prende una stringa e la passa alle funzioni di registrazione di Plone. Di conseguenza, chiamando context.plone_log si ha un utile strumento per correggere gli errori.

Quando si assegna uno script ad una transizione si hanno due possibilità: before e after (prima e dopo). Come suggeriscono i nomi, uno script impostato a before viene lanciato prima della transizione. Ciò è sfruttabile per script che devono controllare se qualcosa deve avvenire prima che la transizione sia lanciata, come controllare se un altro oggetto o pagina dipendenti siano stati aggiornati o che non vi siano errori ortografici. Uno script impostato ad after viene lanciato una volta che la transizione è stata completata, anche se, in qualsiasi momento, una eccezione inaspettatamente sollevata dallo script, può far fallire la transizione e far rimanere l'oggetto nel suo stato originale, mentre l'eccezione viene mostrata all'utente.

Modificare le espressioni del controllo di flusso

In questo capitolo abbiamo visto valori che possono essere espressi tramite espressioni del controllo di flusso. Per esempio il valore assegnato ad una variabile che è il risultato di una espressione del controllo di flusso. Questa espressione non ha niente di speciale; è semplicemente una espressione TAL (Template Attribute Language) con alcune differenti variabili disponibili. Abbiamo già studiato le espressioni TAL nel Capitolo 5 e quindi dovremmo avere famigliarità con quelle espressioni e le loro opzioni, come del Python, stringhe e path expression.

A differenza delle espressioni TAL standard, alcuni parametri extra vengono passati allo spazio dei nomi (namespace) relativo ad un determinato controllo di flusso. Lo spazio dei nomi di una espressione del controllo di flusso contengono i seguenti parametri:

here
È l'oggetto sottoposto a transizione nel controllo di flusso
container
È il contenitore dell'oggetto sottoposto a transizione nel controllo di flusso
state_change
È l'oggetto del cambiamento di stato referenziato nella sezione Modificare gli script del Controllo di Flusso
transition
È la transizione che viene eseguita, identico a state_change.transition.
status
È lo stato originario dell'oggetto, identico a state_change.old_state.
workflow
È il controllo di flusso per questo oggetto
scripts
Sono gli script disponibili in questo controllo di flusso
user
È l'utente che esegue la transizione

Problemi comuni ed esempi

Ora presentiamo alcuni comuni problemi che si possono risolvere facilmente usando il controllo di flusso. Quando un'utente provoca una transizione nel controllo di flusso, questa transizione gira usando l'account di quello specifico utente. In quasi tutti i seguenti esempi, un utente normale può non avere i permessi sufficienti per completare l'operazione. Per esempio, gli utenti con il ruolo di member non hanno normalmente il diritto all'accesso all'elenco degli utenti a meno che questo permesso non sia stato dato loro esplicitamente.

Per risolvere questo problema di permessi, come già segnalato, ad alcuni dei seguenti oggetti Script (Python) è stato dato un ruolo leggermente diverso. Per impostare un ruolo proxy su uno script, accedere alla scheda Proxy di un oggetto o poi selezionare l'utente che deve lanciare lo script, come mostra la Figura 8-9.

../pb2_en/img/3294f0809.png

Figura 8-9. Impostare le opzioni proxy su uno script

Ci assicureremo, ovviamente, che i nostri script siano eseguiti con il ruolo minimo necessario, il che dipende direttamente da cosa fa il nostro script.

Introduzione delle espressioni del Controllo di Flusso

Le successive espressioni per il controllo di flusso sono alcuni utili esempi che possono essere usati in varie posizioni

Per ottenere i commenti, o una stringa vuota, da questa transizione usiamo:

python:state_change.kwargs.get('comment', '')

Per ottenere il titolo della cartella che contiene l'oggetto usiamo

container/Title

Per provare se il vecchio stato è review usiamo:

python: state_change.old_state == 'review'

Per avere l'utente che sta eseguendo la transizione usiamo:

user/getId

Così se vogliamo tracciare chi è l'ultimo utente che ha eseguito una transizione sull'oggetto, è possibile aggiungere una variabile last user nel controllo di flusso. Lo si può fare andando nel controllo di flusso e cliccando la scheda Variables. Poi aggiungiamo la variabile last_user. Se si imposta la variabile Default expr a user/getId, ogni volta che l'oggetto cambia, questo valore viene tenuto per noi.

Uso del controllo di flusso per tracciare le modifiche

In una particolare applicazione di un nostro cliente abbiamo dovuto tener traccia del momento in cui un elemento viene modificato e delle ragioni di questa modifica in modo che quando successivamente si guarda l'elemento si possa trovare un commento per ogni cambiamento. Grazie al controllo di flusso questo è facile ottenerlo.

Nel nostro caso il controllo di flusso aveva solo uno stato ma ora questo funziona per quasi tutti i workflow. In quello, abbiamo aggiunto una transizione denominata edit. Quella transizione non modifica realmente lo stato dell'oggetto; lo stato di destinazione per la transizione era (Remain in state), che significa che non deve evvenire alcun cambiamento.

Quando viene modificato un oggetto, viene chiamato un metodo per effettuare la modifica. Per esempio, quando viene modificato un documento, il metodo chiamato è document_edit.cpy. Si può trovare questo script cliccando su portal_skins, poi su plone_form_scripts e quindi su document_edit. Tutto quello che si deve fare è aggiungere a quello script una riga prima dell'ultima:

context.portal_workflow.doActionFor(new_context,
 'edit', comment='')

Il metodo doActionFor di portal_workflow effettua le transizioni date (nel nostro caso edit) per l'oggetto che viene passato (nel nostro caso context). Ogni volta che l'oggetto viene modificato viene eseguita quella transizione edit. Ciò causa l'aggiunta di una riga all'elenco dei commenti che mostra chi ha modificato l'oggetto, quando è stato aggiunto e qualsiasi commento ad esso associato.

Quando un oggetto viene modificato, non vengono inseriti realmente commenti, quindi per essere un po' più avanzati, dobbiamo modificare il modello di modifica dei documenti (edit template) affinché includa un campo commenti. Poi possiamo accedere a questo elenco di commenti andando nella scheda State dove viene mostrato, in fondo, l'elenco delle modifiche.

Spostare oggetti

Una utile possibilità è lo spostamento di un oggetto durante il controllo di flusso. Per esempio potremmo spostare tutti i rilasci stampa in una cartella denominata Press Release ogniqualvolta ne viene pubblicato uno. I contenuti possono essere creati e modificati ovunque e poi spostati con la pubblicazione in questa cartella. Lo script di esempio nel Listato 8-1 sposta l'oggetto che è sottoposto al controllo di flusso nella cartella Members. Per aggiungere questo script andare nello strumento del controllo di flusso nella ZMI e selezionare la scheda Scripts. Poi scegliere Script (Python) dal box con l'elenco a cascata. Dare al nuovo oggetto il nome moveObject quindi inserire il Listato 8-1 in questo script.

Listato 8-1. Spostare un oggetto

##parameters=state_change
# get the object and its ID
obj = state_change.object
id = obj.getId()
 
# get the src folder and the destination folder
dstFldr = context.portal_url.Members
srcFldr = obj.aq_parent
 
# perform the move
objs = srcFldr.manage_cutObjects([id,])
dstFldr.manage_pasteObjects(objs)
 
# get the new object
new_obj = dstFldr[id]
 
# pass new_obj to the error, *twice*
raise state_change.ObjectMoved(new_obj, new_obj)

Dobbiamo fare ancora alcune cose; primo, assegnare questo script ad una transizione. Normalmente si usa uno script simile nella transizione publish. Per far questo andiamo in quella transizione ed assegnamo il valore moveObject al campo script (after).

Secondo, esiste un altro piccolo problema: questo script sposta gli oggetti nella cartella Members. Probabilmente abbiamo in mente una destinazione migliore. Per fare un tale spostamento l'utente deve avere i diritti appropriati per muovere oggetti tra queste cartelle. Normalmente solo un manager può spostare oggetti dentro la cartella Members. Così è necessario dare allo script il ruolo proxy di manager. Si può farlo cliccando su Scripts, poi su moveObject e selezionando la scheda Proxy. Assegnare il ruolo di manager allo script. Nel Capitolo 9 si possono avere ulteriori informazioni sulla sicurezza e sui ruoli locali.

Guardando il codice, prima lo script ottiene l'oggetto e l'ID dell'oggetto dallo spazio dei nomi della transizione. Poi ottiene la cartella sorgente e quella di destinazione. Poi effettua il copia incolla utilizzando l'interfaccia API (Application Programming Interface) di Zope ObjectManager. È possibile ovviamente determinare programmaticamente queste cartelle, magari in base all'utente che realizza la transizione o al tipo di contenuto che viene spostato. Infine si ottiene l'oggetto e lo si passa ad una eccezione ObjectMoved.

L'eccezione ObjectMoved è una speciale eccezione del DCWorkflow. Dandole due volte il nuovo oggetto come parametro, il nuovo oggetto viene passato al front-end Plone. Ciò risulta critico e quindi quando l'utente viene mandato all'oggetto in seguito alla modifica, è alla nuova posizione dell'oggetto, non a quella vecchia. Possiamo ovviamente scrivere una funzione che riporti indietro l'oggetto qualora fosse respinto, magari nella cartella home del collaboratore.

Un altro caso speciale e ancora più insolito e di cancellare un oggetto con il controllo di flusso. Normalmente la cancellazione è una azione del contenitore dell'oggetto quindi è insolito trovarla in un controllo di flusso. Per questo scopo si può sollevare l'eccezione ObjectDeleted. Il Listato 8-2 mostra lo script per effettuare una cancellazione.

Listato 8-2. Cancellare un oggetto

##parameters=state_change
 
# get the object
obj = state_change.object
id = obj.getId()
 
# get the parent folder, delete the object
srcFldr = obj.aq_parent
srcFldr.manage_delObjects([id,])
 
# raise the object deleted method and pass
# the folder you want to return to
raise state_change.ObjectDeleted(srcFldr)

Possiamo chiamare questo script deleteObject e cancellare completamente oggetti tramite il controllo di flusso. Di nuovo, per assicurare che l'errore sia sollevato, Plone vuol sapere cosa fare; in questo caso, egli prende l'utente dalla cartella contenente quell'oggetto.

Inviare notifiche via E-Mail

Se si ha un sito Plone che un utente non visita regolarmente è abbastanza stupido mettere informazioni su cosa deve essere revisionato e quando. Si può trasformare il controllodi flusso in un rudimentale sistema di notifica utilizzandolo per inviare una e-mail agli utenti. I canale di notifica delle e-mail è solo un piccolo esempio, Può diventare un messaggio istantaneo, come un messaggio di testo spedito via telefono e così via. Lasciamo le altre possibilità all'immaginazione.

In questo esempio, inviamo una e-mail tramite l'oggetto MailHost sul server ad ogni utente del sistema che abbia il ruolo di reviewer, dicendo loro che un nuovo oggetto è stato sottoposto a revisione. È uno script realmente più complicato del primo che abbiamo mostrato poco fa, in quanto effettua alcuni passi: definizione delle variabili, ricerca del nome dell'account di ciascun revisore, ricerca dell'indirizzo e-mail, invio di una e-mail. Il Listato 8-3 mostra lo script.

Listato 8-3. Inviare una notifica e-mail

##parameters=state_change
# the objects we need
object = state_change.object
mship = context.portal_membership
mhost = context.MailHost
administratorEmailAddress = context.email_from_address
 
# the message format, %s will be filled in from data
message = """
From: %s
To: %s
Subject: New item submitted for approval - %s
 
%s
 
URL: %s
"""

Questo imposta il messaggio e gli oggetti di cui avevamo bisogno. Oltre all'oggetto soggetto a transizione, abbiamo bisogno anche di un riferimento allo strumento per la gestione degli utenti portal_membership e al server SMTP (Simple Mail Transfer Protocol) via MailHost. Il messaggio è facilmente configurabile per mandare una e-mail in ogni formato si desideri.

Poi usiamo il metodo listMembers dell'oggetto portal_membership per ottenere un elenco dei collaboratori. Per ciascun collaboratore si può vedere in seguito se il ruolo di revisore è nell'elenco dei ruoli per quell'utente chiamando il metodo getRoles:

for user in mship.listMembers():
    if "Reviewer" in mship.getMemberById(user.id).getRoles():

Il lettore astuto noterà che girare su ogni collaboratore in un sito Plone può essere un po' lento se si hanno migliaia di utenti. Nel prossimo capitolo modifichiamo questo script per avere l'elenco degli utenti di un determinato gruppo.

Non è possibile inviare una e-mail se non si un indirizzo dell'utente, quindi controlliamo prima che ci sia un indirizzo valido. Manca solo formattare il messaggio e-mail e spedirlo. Per far questo si può usare la funzionalità di sostituzione di stringhe di Python e passarle i quattro parametri che corrispondono ai %s della variabile message impostata all'inizio dello script. Dopo questa sostituzione la variabile msg contiene la e-mail che vogliamo spedire. Per spedirla chiamiamo semplicemente il metodo send dell'oggetto MailHost e passare la stringa della e-mail:

if user.email:
    msg = message % (
         administratorEmailAddress,
         user.email,
         object.TitleOrId(),
         object.Description(),
         object.absolute_url()
         )
    mhost.send(msg)

Il risultato è la seguente e-mail che verrà spedita:

From: administrator@agmweb.ca
To: andy@agmweb.ca
Subject: New item submitted for approval - Plone's great
 
We all know Plone is a great product, but with the newest release
it's gotten even better...
 
URL: http://agmweb.ca/Members/andym/News_Item_123

L'Appendice B contiene il listato completo di questo script.

Uso del PloneCollectorNG

PloneCollectorNG è un raccoglitore di problemi disponibile in Plone. Ci sono molti tracciatori di problemi in giro ma questo è quello che usiamo e raccomandiamo in Plone. In effetti sembra che scrivere un tracciatore sia alquanto comune tra gli sviluppatori. Una delle cose realmente simpatiche del controllo di flusso è che abitua gli utenti a significativi cambiamenti nell'uso di una applicazione. Come per lo sviluppatore, sviluppare prodotti agganciati ad un DCWorkflow consente all'applicazione di rimanere flessibile. Si può trovare PloneCollectorNG all'indirizzo http://www.zope.org/Members/ajung/PloneCollectorNG.

Il prodotto aggiunge durante l'installazione una serie di tipi di contenuto, uno dei quali è PloneIssueNG, che è un issue (report bug, problema). Piuttosto di mettere nel codice (hard-coding) esattamente come il problema cambia nel database, al problema viene assegnato un controllo di flusso separato. Quel controllo di flusso contiene stati, transizioni, variabili ed elenchi lavori appropriati.

Ad ogni passaggio si può ricavare in quale stato si trova un oggetto chiamando il metodo getInfoFor di portal_workflow. Questo utile metodo accetta un oggetto e la variabile da cercare. Nel controllo di flusso di PloneCollectorNG questa variabile è denominata state, mentre nel controllo di flusso Plone è detta review_state. Per trovare lo stato di un oggetto usiamo per esempio:

portal_workflow.getInfoFor(obj, "review_state")

Possiamo trovare i possibili stati di un oggetto esaminando lo stato dell'oggetto direttamente nel controllo di flusso, in questo modo:

portal_workflow['pcng_workflow'].states._mapping.keys()

Come risultato avremo che se l'utente vuol avere un semplice sistema di tracciatura dei problemi, allora modificare questo controllo di flusso via web diventa banale (se, quando è stata sviluppata l'applicazione, è stato considerato lo strumento di controllo di flusso). Compariamo questo sistema ad un altro popolare bug-tracking, Bugzilla dove, cambiare uno stato o una transizione richiede ore ed ore di programmazione Perl per trovare tutte le referenze ad uno stato di errore (bug's state) nel codice (hard-coded).

Distribuire e scrivere il Controllo di Flusso

Se si ha un controllo di flusso molto esteso per la propria applicazione, ci sono alcuni differenti modi di distribuirlo. Le prossime sezioni chiudono la trattazione del controllo di flusso presentando una coppia di tali opzioni.

Scrivere tramite la ZMI

Probabilmente scrivere il controllo di flusso tramite la ZMI è il modo più semplice anche se più laborioso. Sebbene la ZMI porti spesso la gente a impazzire, essa rimane la via più semplice per impostare le opzioni. Sfortunatamente una volta che si è iniziato a scrivere il controllo di flusso tramite la ZMI siamo bloccati in quel paradigma. In altre parole non vi è un modo semplice per modificare o alterare quel controllo di flusso sul file system. Ovviamente, abbiamo parlato, precedentemente in questo capitolo, della modifica di un controllo di flusso via web.

Per esportare un controllo di flusso dalla ZMI, cliccare su portal_workflow e selezionare la scheda Contents, selezionare i controlli di flusso che si desidera esportare spuntando i box sulla sinistra nella ZMI cliccando poi import/export. Nella parte in cima della pagina di esportazione, selezionare Download to local machine e cliccare export. Viene creato un file con estensione .zexp che può essere salvato e redistribuito. Selezionando XML Format si ottiene un file nel formato XML (Extensible Markup Language) con estensione .xml.

Se si ha un controllo di flusso in formato .zexp o .xml l'importazione in Plone è assolutamente lineare. Mettere quel file nella cartella di importazione di Zope sul file system. Può essere sia la cartella home dell'istanza sia la cartella Zope.

Clicchiamo poi portal_workflow, scegliamo la scheda Contents e clicchiamo su import/export. Nella parte in cima alla pagina si può vedere un semplice modulo che prende il nome di un file da importare. Inseriamo qui il nome del file e lasciamo selezionato Take ownership of imported objects. Clicchiamo il pulsante Import per importare il controllo di flusso. Il controllo di flusso viene importato e gli viene dato il nome specificato nell'esportazione.

Scrivere un Controllo di Flusso in Python

La maniera preferita dai programmatori per scrivere un controllo di flusso è probabilmente usare Python, in quanto può essere fatto tutto con Python e facilmente distribuito. Primo, facciamo un modulo Python nel file system. In cima al file importiamo gli strumenti necessari, come segue:

from Products.CMFCore.WorkflowTool import addWorkflowFactory
from Products.DCWorkflow.DCWorkflow import DCWorkflowDefinition

Secondo, facciamo una funzione che crei il controllo di flusso. L'Appendice A elenca le API per scrivere un controllo di flusso un po' più in dettaglio. Ma possiamo semplicemente barare e guardare ai numerosi esempi disponibili nel progetto PloneWorkflow nel collective (http://sf.net/projects/collective) o anche in quelli contenuti in Plone. Per esempio:

def sample(id):
    """ Sample workflow """
    ob = DCWorkflowDefinition(id)
    ob.states.addState('private')
    ob.states.addState('public')
    # add transitions
    return ob

Finalmente registriemo il controllo di flusso nel sistema così:

addWorkflowFactory(sample,
                   id='sample_workflow',
                   title='Sample workflow')

Questo script deve far parte della installasione di un prodotto. Il Capitolo 12 tratta dello scrivere ed installare prodotti.

Ora, naturalmente, è disponibile una scorciatoia, che si chiama DCWorkflowDump. Questa prende il codice dalla ZMI e lo sbatte (dump) dentro un modulo Python. Il codice sorgente di DCWorkflowDump è disponibile nel collective (http://sf.net/projects/collective) ma anche nel sito web del manuale Plone all'indirizzo http://plone-book.agmweb.ca si può trovare un file .zip con il codice.

Per installare DCWorkflowDump, decomprimere il file e copiare la cartella denominata DCWorkflowDump nella cartella Products della nostra installazione Plone. Come controllo per sapere se siamo nella cartella giusta, verifichiamo che la stessa cartella contenga, tra le altre cose, una cartella per DCWorkflow. Poi riavviamo l'istanza Plone.

Una volta riavviato Plone, rechiamoci nella ZMI in quel particolare controllo di flusso e noteremo una nuova scheda denominate dump. Scegliamo quella pagina per vedere la schermata di dump e clicchiamo su Dump it! per ottenere il controllo di flusso. Questo prende il nostro controllo di flusso e lo formatta in Python. Salviamo questo file nel nostro prodotto e quindi ora abbiamo un file Python da manipolare. Questo prodotto è un valido strumento poiché consente di creare il controllo di flusso con la ZMI e poi distribuirlo e alterarlo tramite Python.


Andy McKay: The Definitive Guide to Plone. Apress 2004
This online version was generated using the 'PloneBook' product from docs.neuroinf.de/products.
It was last updated by
lallo on 2005-04-09 07:08 from the cvs source using
svn export http://docit.bice.dyndns.org/Plone/PloneBook2/it LibroPlone.

Powered by Plone CMS, the Open Source Content Management System

This site conforms to the following standards: