Hook procedurali e servizi disaccoppiati
Con i plugin è possibile modificare i componenti ed estenderne le funzionalità. Fondamentalmente esistono due meccanismi distinti utilizzati dai plugin:
- Hook procedurali: chiamata di una “procedura” remota che restituisce un valore di ritorno utilizzato attivamente dal codice chiamante. Ad esempio, i plugin di contenuto che ricevono il testo di un articolo, possono trasformarlo e restituire il testo modificato. Oppure un componente di pagamento che utilizza i plugin per definire diversi metodi di pagamento. Si ottiene un sistema estensibile in cui è possibile aggiungere plugin personalizzati. È un modo semplice ma potente per aggiungere funzionalità extra.
- Azioni di follow-up: in questo caso un plugin ascolta un evento principalmente per innescare un effetto collaterale. Si tratta più di un plugin di tipo “fire-and-forget”. È possibile utilizzarlo, ad esempio, per inviare una notifica su un articolo appena salvato o per registrare le azioni del proprio componente. I plugin personalizzati possono reagire a tale evento e aggiungere azioni completamente nuove. Ciò offre possibilità per un’architettura event-driven.
Questi hook procedurali sono la forma più antica di plugin. Sono un tipo semplice di middleware. Uno svantaggio è che sono strettamente accoppiati: nel punto in cui vengono attivati quegli eventi, è necessario sapere con quali parametri vengono chiamate quelle procedure e quali valori restituiscono. Joomla mitiga tale accoppiamento utilizzando eventi invece di callback diretti. Questi callback richiedevano un ordine fisso dei parametri; gli eventi lo evitano. Tali eventi contengono le variabili di input in modo standardizzato. In linea di principio i plugin non hanno più un valore di ritorno, ma è possibile modificare i parametri di input o aggiungere loro un array di risultati. Quindi, è ancora possibile utilizzare gli “hook” in Joomla, ma questi utilizzano gli eventi per ridurre l’accoppiamento.
Tutorial sui plugin nel manuale per sviluppatori
Nel manuale per sviluppatori troverete un tutorial su come creare un plugin. Lì viene utilizzato come esempio un plugin di contenuti di base. Nel manuale puoi anche trovare alcune informazioni generali su funzionamento dei plugin e sui metodi e gli eventi dei plugin. Nelle sezioni seguenti di questo articolo aggiungerò alcune informazioni di base sull'interfaccia Subscriber e sull'iniezione di dipendenze.
Interfaccia Subscriber
In passato aggiungevamo direttamente a un plugin un metodo con lo stesso nome dell'evento e con un ordine fisso di parametri per quell'evento specifico. Tali metodi venivano rilevati tramite riflessione, il che risultava lento con molti plugin. Utilizzando l'interfaccia SubscriberInterface, definiamo quali eventi il plugin gestirà e quali metodi lo faranno. Questi metodi di gestione ora hanno l'oggetto evento come parametro. L'interfaccia SubscriberInterface non definisce alcun valore di ritorno, ma è possibile aggiungere un array di risultati. È anche possibile assegnare priorità a questi gestori, in modo da non dipendere più completamente dall'ordine di caricamento dei plugin.
Iniezione di dipendenze
Come tutte le estensioni di Joomla, i plugin utilizzano l'iniezione di dipendenze. Ecco perché abbiamo il file del fornitore di servizi. Leggi l'articolo sull'iniezione di dipendenze per capire meglio come funziona. Nel fornitore di servizi il plugin stesso viene istanziato e tutte le dipendenze vengono iniettate al suo interno, in genere tramite setter. Ad esempio, se il tuo plugin necessita di un oggetto application, del database e delle informazioni utente, avrai bisogno di qualcosa di simile nel tuo service provider:
$plugin->setApplication(Factory::getApplication());
$plugin->setDatabase($container->get(DatabaseInterface::class));
$plugin->setUserFactory($container->get(UserFactoryInterface::class));
Nel plugin stesso puoi usare i getter per ottenere quegli oggetti iniettati: $this->getApplication(), $this->getDatabase(), ecc.
Il getter e il setter per l'oggetto Application sono già implementati nel genitore Joomla\CMS\Plugin\CMSPlugin. Se si desidera fornire altri oggetti, sarà necessario implementare autonomamente i metodi setter e getter. Per molti oggetti di base sono disponibili dei trait per implementare tali getter e setter. Ad esempio, per fornire un database, usa il Joomla\Database\DatabaseAwareTrait, e per fornire un oggetto utente usa il Joomla\CMS\User\UserFactoryAwareTrait. La pratica consigliata è quella di specificare quale interfaccia viene implementata quando si utilizza un trait di questo tipo; in questo caso, rispettivamente Joomla\Database\DatabaseAwareInterface e Joomla\CMS\User\UserFactoryAwareInterface.
Diversi tipi di plugin in questa serie
Nei prossimi episodi abbiamo in programma di mostrare plugin personalizzati dei seguenti tipi:
- Plugin Task: pianifica le attività che il tuo sito web deve svolgere, ad esempio il check-in di contenuti ancora in check-out da una sessione scaduta, o la notifica di nuovi contenuti. I plugin Task sono ottimi esempi di azioni di follow-up disaccoppiate.
- Plugin Workflow: è possibile personalizzare l'attuale flusso di lavoro di pubblicazione, ad esempio notificando all'autore di un articolo che lo stato è cambiato. Oppure è possibile definire flussi di lavoro completamente personalizzati, ad esempio per l'e-commerce con stati come ordinato, pagato, spedito, ecc.
- Plugin Finder: quando si dispone di un componente personalizzato, si vorrebbe utilizzarlo in Finder (“ricerca intelligente”). Scrivere un plugin Finder personalizzato per questo.
- Plugin Content: questo è il tipo di plugin più conosciuto. Mostreremo alcune interessanti possibilità con i plugin di contenuto personalizzati.
- Plugin di sistema: non legato a un componente specifico e caricato prima di altre parti del CMS. Mostreremo alcune possibilità, ad esempio come viene utilizzato nel plugin di sistema Obix Class Extender per modificare le classi principali.
- Plugin per servizi web: se il tuo componente dispone di un'API per servizi web, avrai bisogno di un plugin personalizzato per gestirla.
- Plugin Quickicon: crea i tuoi pulsanti per il modulo Quickicons.
- Plugin Filesystem: puoi collocare immagini e file da qualche parte nel cloud. Come creare un plugin per una posizione file personalizzata.
- Plugin Media-action: crea il tuo gestore di immagini.
- Plugin Utente: estenderemo gli utenti e i gruppi di utenti con alcuni plugin personalizzati.
- Plugin Campi: se hai definito i tuoi campi, specifici per il tuo componente, puoi anche consentire ai tuoi clienti di usarli come campi aggiuntivi. In questo episodio ti mostreremo come.
- Plugin Editors e Editors-extended: aggiungi i tuoi pulsanti all'editor.
- Plugin Schemaorg : creeremo alcuni schemi personalizzati per i dati strutturati.
- Plugin Authentication : come implementare un plugin di autenticazione personalizzato, ad esempio per effettuare il login con Github. Esamineremo anche l'autenticazione a più fattori e l'autenticazione API.
- Plugin Behaviour : un interessante gruppo di plugin, meglio conosciuto per il plugin di retrocompatibilità. Quali sono le possibilità di personalizzazione?