Una narrazione sull'utilizzo di Composer in un plug-in di WordPress

Pubblicato: 2015-07-06

petersuhm Questo pezzo è stato contribuito dall'autore ospite Peter Suhm. Peter è uno sviluppatore web della Terra dei Danesi. È il creatore di WP Pusher e un grande appassionato di viaggi, portando il suo lavoro con sé mentre va.


L'altro giorno ho pubblicato un avviso sull'utilizzo di Composer nei plugin di WordPress sul blog WP Pusher. Questo post ha ricevuto molta attenzione e sento il bisogno di chiarire alcuni punti che non erano del tutto chiari a tutti. L'articolo era anche un po' pesante per quanto riguarda le questioni tecniche, quindi in questo post cercherò di rendere più chiaro il mio punto principale usando una semplice narrazione per illustrarlo.

Una narrativa

credito fotografico: Doors Open Toronto 2008 - Toronto Archives - (licenza)
credito fotografico: Doors Open Toronto 2008 – Toronto Archives – (licenza)

Immaginiamo per un po' che tu ed io siamo entrambi autori di plugin. Entrambi abbiamo un'ottima idea per un plugin che desideriamo distribuire tramite WordPress.org. Vogliamo includere alcune funzionalità premium nei nostri plugin che gli utenti della versione gratuita possono sbloccare inserendo una chiave di licenza.

Abbiamo bisogno di un codice in grado di gestire questo processo. Entrambi ci rendiamo conto che questo problema probabilmente è già stato risolto da qualcun altro. Nessuno di noi è fan di reinventare la ruota, quindi andiamo su Packagist e digitiamo "gestore delle licenze". Sembra che la nostra ipotesi fosse giustificata. Yoast ha già un pacchetto in grado di gestirlo. Entrambi decidiamo di fare un veloce composer require yoast/license-manager . Vai tranquillo. Ora possiamo passare a lavorare su qualcosa che conta davvero: le funzionalità principali dei nostri rispettivi plugin.

Avanti veloce, pronto per rilasciare il tuo plug-in, ti rendi conto di qualcosa: il tuo utente non ha necessariamente Composer a portata di mano quando installa il tuo plug-in da WordPress.org, quindi come otterranno il codice per il gestore delle licenze? Questa situazione è un po' fastidiosa, perché l'unica soluzione che vedi davvero è semplicemente impegnare l'intera directory del vendor generata da Composer nel tuo plug-in e inviarla a WordPress.org. Sai che non è così che dovrebbe funzionare Composer, ma qualunque cosa. Non hai davvero altre opzioni.

Nel frattempo, sono giunto alla stessa conclusione con il mio plugin. Basta includere il codice del gestore delle licenze e il gioco è fatto.

Avanti veloce ancora una volta, entrambi i nostri plugin ora risiedono nel repository di WordPress.org e di tanto in tanto qualcuno decide di eseguire l'aggiornamento alle nostre versioni premium. Tutto sembra andare bene e siamo entrambi grati di aver potuto semplicemente usare il codice che Yoast aveva generosamente open source e di non dover reinventare la ruota.

Un giorno, ricevi una strana e-mail. Un cliente sta riscontrando un comportamento davvero strano durante il tentativo di sbloccare le funzionalità premium. Non ha senso per te, perché nessun altro ha mai segnalato questo. Dopo ore di debug, chiedi finalmente al tuo cliente di disattivare tutto il resto, tranne il tuo plugin, e poi: Funziona! Hmm. Il tuo plug-in sembra in qualche modo incompatibile con un altro plug-in. Il mio plugin.

Te ne rendi conto dopo aver passato ore a leggere il codice sorgente di tutti gli altri plugin che il cliente aveva installato. Quando ti rendi conto che entrambi usiamo il gestore delle licenze, suona un campanello. Potrebbe essere davvero questo? In tal caso, come mai nessun fatal errors: cannot redeclare class è stata causata da PHP?

Una settimana prima, avevo spostato la versione richiesta del gestore delle licenze nel mio plug-in all'ultima versione, che includeva alcune modifiche sostanziali (fittizie). Dopo ancora più debug e var_dump() 'ing, ti rendi conto che la mia versione del gestore delle licenze è anche la versione caricata da PHP nel tuo plugin. Lo trovi davvero strano perché hai richiesto specificamente un'altra versione del gestore delle licenze con Composer. Non sai davvero cosa fare al riguardo.

Perché non c'è davvero molto che puoi fare al riguardo.

Cos'è successo qua?

Ora che abbiamo visto tutti il ​​problema, prendiamoci un momento per esaminare ciò che è realmente accaduto nella narrazione. Prima di tutto, perché PHP non ha causato un errore fatale quando due classi ovviamente avevano lo stesso nome che entrambi includevamo il gestore delle licenze?

Il motivo è che abbiamo utilizzato un caricatore automatico generato da Composer. Questo caricatore automatico scansiona la struttura delle directory delle nostre dipendenze e aggiunge ogni classe al caricatore automatico. Se una classe è già stata aggiunta, Composer la ignorerà. Silenziosamente. Ho scritto un piccolo esempio di codice se vuoi vederlo di persona. È su GitHub.

Perché la mia versione del gestore delle licenze è stata inclusa prima della tua?

Ciò è accaduto perché il mio plugin aveva un nome che ne causava il caricamento prima del tuo. Forse, in futuro, chiameremo tutti i nostri plugin “Aaaaaa My Plugin” per essere caricati per primi!

Quindi, per riassumere, il problema principale qui è che non sapremo quale versione delle nostre dipendenze è disponibile per noi in quale momento. Dipende semplicemente da fattori che non possiamo controllare completamente come sviluppatori di plugin.

È un problema specifico del compositore?

No. Non lo è davvero. WordPress non ha un modo per gestire il codice di terze parti in plugin o temi. Qui sta il problema. Il motivo per cui sto parlando di Composer è che sta guadagnando molta popolarità in questi giorni. Se gli sviluppatori di WordPress vogliono utilizzare Composer nei plugin rilasciati tramite WordPress.org, questo deve essere risolto in qualche modo. Altrimenti, vedremo il vero caos quando tutti i plugin inizieranno a essere incompatibili tra loro perché utilizzano versioni diverse. Benvenuto nell'inferno del debug.

Cosa possiamo fare al riguardo?

Qualcuno che è stato davvero preoccupato per questo e ha lavorato duramente per trovare una potenziale soluzione è Coen Jacobs. Ho deciso di contattare Coen e chiedergli se pensa che ci sia qualcosa che possiamo fare al riguardo.

Molti sviluppatori stanno già includendo codice di terze parti nei loro plugin. E 'veramente un problema?

Sì, questo è già un problema nell'ecosistema dei plugin. Diventerà ancora peggio quando più persone capiranno che è una buona idea mettere le funzionalità comuni in pacchetti separati. Questi pacchetti possono quindi essere raggruppati con più plug-in e il problema apparirà sempre di più. Ho parlato con un paio di sviluppatori che hanno già attraversato l'inferno del debug cercando di scoprire cosa sta causando questo problema.

Andando avanti, suggeriresti agli sviluppatori di smettere di includere codice di terze parti nei loro plugin?

Sono un po' combattuto su questo argomento. Non ha senso dal punto di vista degli sviluppatori dire alle persone di smettere di raggruppare i pacchetti condivisi nei loro plugin. D'altra parte, tutti vogliono la migliore esperienza utente possibile per i propri utenti. È una decisione difficile da prendere di sicuro.

A questo punto, voglio portare avanti lo sviluppo relativo a WordPress. Voglio condividere le librerie e utilizzare le librerie condivise da altri. Nessuno dovrebbe reinventare la ruota più e più volte. Quindi correrei il rischio di incappare in problemi come questo, risolvendo i problemi man mano che si presentano.

Ciò significa anche che farò del mio meglio per trovare una soluzione a lungo termine per questo problema. Più persone inizieranno a utilizzare Composer, più persone collegheranno le librerie con i loro plugin. Questo problema si presenterà più spesso, quindi è il momento di risolverlo.

Cosa possono fare gli sviluppatori di plugin per prevenire questo problema?

C'è una soluzione alternativa che ho già visto utilizzare da alcune persone. Fondamentalmente si riduce a spostare la tua dipendenza nello spazio dei nomi del tuo plug-in. Danny van Kooten lo ha fatto per uno dei suoi plugin. Tuttavia, questo non è l'ideale. Ogni volta che aggiorna le sue dipendenze, deve esaminare tutti i file e modificare nuovamente gli spazi dei nomi. Ora questo non è un compito così grande per una biblioteca relativamente piccola come Pimple, ma un'impresa enorme per le biblioteche più grandi.

Questo può essere fatto solo con gli spazi dei nomi, quindi dovrai fare in modo che il tuo plugin richieda anche PHP 5.3+. Non mentirò, penso che ogni plugin dovrebbe iniziare a farlo prima o poi, ma è sicuramente qualcosa che devi considerare quando decidi di farlo.

Quale sarebbe la soluzione ideale, se esiste?

La situazione ideale sarebbe usare una sorta di gestore delle dipendenze. C'è ovviamente Composer, il gestore delle dipendenze più utilizzato. Il compositore è molto difficile, se non impossibile, da utilizzare per la stragrande maggioranza degli utenti di WordPress. Dopotutto è uno strumento per sviluppatori.

WordPress dovrebbe rendere tutto più semplice per i suoi utenti finali, consentendo comunque agli sviluppatori di utilizzare praticamente qualsiasi pacchetto desiderino. Su questo pensiero, ho iniziato a mettere insieme il plugin WordPress Composer Installer, che fa tutto il duro lavoro di Composer mentre le persone installano i plugin come hanno sempre fatto. Non appena sarò in grado di completarlo, lo integrerò correttamente nell'intero flusso di installazione del plug-in.

Ora forse un giorno, questo può essere integrato nel core di WordPress. C'è ancora molta strada da fare, ma il proof of concept funziona già.

Conclusione

Se hai letto fino a qui, prima di tutto: grazie. In secondo luogo, spero che ora tu veda come questo è qualcosa che alla fine diventerà un problema. La nostra situazione attuale è molto frustrante, perché semplicemente non abbiamo gli strumenti di cui abbiamo bisogno. Tuttavia, penso che sia importante continuare a parlarne e assicurarci che tutti noi, come sviluppatori di WordPress, comprendiamo i potenziali problemi causati dalle dipendenze in conflitto di terze parti nel nostro codice.

Infine, voglio menzionare ancora una volta che questo non è un problema di Composer. È un problema di WordPress.