Distribuzione dei plugin in GitHub con aggiornamenti automatici

WordPress ha reso conveniente l'installazione di plug-in al pubblico. Inserisci il tuo plug-in nel repository dei plugin di WordPress e può essere facilmente trovato dagli utenti all'interno della loro dashboard.

Probabilmente una delle migliori caratteristiche del repository è che semplifica l'aggiornamento dei plugin dall'interno del dashboard. Le notifiche di aggiornamento vengono visualizzate all'interno della dashboard e l'esecuzione di un aggiornamento è semplice come fare clic sul pulsante Aggiorna ora pulsante.

Ma che dire se volessi ospitare il plugin da solo? La comoda funzione di aggiornamento non sarà disponibile se si ospita il plug-in al di fuori del repository di plug-in di WordPress. Né i tuoi utenti saranno informati di un aggiornamento disponibile.

Questo articolo ti insegnerà che con un po 'di codifica creativa puoi ospitare i tuoi plugin WordPress in GitHub pur mantenendo la funzionalità di aggiornamento automatico.

Perché ospitare il tuo plugin in GitHub?

Potrebbero esserci diversi motivi per cui vorresti ospitare il tuo plugin al di fuori del repository dei plugin di WordPress. Una delle principali restrizioni che il repository offre è che ti viene richiesto di concedere in licenza il tuo plugin come GPLv2. Non mi soffermerò sui dettagli delle licenze, ma in poche parole significa che chiunque può condividere il tuo lavoro. Quindi, se vuoi vendere il tuo plug-in, l'hosting in un repository GitHub privato è ora un'opzione che puoi prendere in considerazione.

Tuttavia, a causa del modo in cui è stato creato WordPress, l'hosting del plugin in GitHub lo farebbe disabilitare gli aggiornamenti automatici per il nostro plugin. Per capire perché questo è il caso, dobbiamo capire come WordPress gestisce gli aggiornamenti dei plugin.

Puoi saperne di più sul repository dei plugin di WordPress leggendo le loro Linee guida dettagliate sui plug-in.

Come WordPress aggiorna i plugin

Innanzitutto, analizziamo come WordPress esegue gli aggiornamenti dei plug-in per comprendere meglio il motivo per cui i plug-in self-hosted non possono avere aggiornamenti automatici

WordPress controlla periodicamente il repository di WordPress per gli aggiornamenti dei plugin installati. Riceve un sacco di informazioni su ciascun plugin come la sua ultima versione e l'URL del pacchetto del plugin. Questo è ciò che solitamente vediamo nella pagina di amministrazione del plugin quando ci viene notificato un aggiornamento:

Quando clicchiamo sul Visualizza i dettagli della versione x.x. link, WordPress esegue un'altra ricerca nel repository plugin. Questa volta ottiene informazioni più dettagliate sul plug-in come la sua descrizione, il log delle modifiche, la versione di WordPress testata e molto altro. Queste informazioni ci vengono mostrate in un lightbox:

Infine, quando il Aggiorna ora si fa clic sul collegamento, il pacchetto di aggiornamento aggiornato viene scaricato e installato.

Quindi, perché gli aggiornamenti automatici non funzionano per i plugin self-hosted? È perché WordPress cerca di trovarlo nel repository dei plugin di WordPress e non riesce a trovarlo lì!

Il piano di gioco

Il nostro piano è di abilitare gli aggiornamenti automatici con il nostro plugin GitHub-hosted.

Ecco un elenco di ciò che dobbiamo fare per farlo funzionare:

  • Abbiamo bisogno di un modo per distribuire gli aggiornamenti dei plugin in GitHub.
  • Dovremmo mostrare le notifiche di aggiornamento della versione del plugin,
  • Sarebbe bello visualizzare i dettagli del plugin quando Visualizza i dettagli della versione x.x. il collegamento è cliccato.
  • Vogliamo anche installare con successo l'aggiornamento del plugin quando il aggiorna ora il collegamento è cliccato,

Come eseguire il piano

Utilizzeremo alcuni filtri WordPress per consentirci di implementare il nostro piano di gioco. Questi sono:

  • pre_set_site_transient_update_plugins. Questo filtro è chiamato quando WordPress cerca di verificare gli aggiornamenti del plugin.
  • plugins_api. Questo viene usato quando WordPress mostra i dettagli di aggiornamento del plugin.
  • upgrader_post_install. Infine, questo è chiamato dopo che un plugin è stato installato con successo.

Inseriremo questi filtri, quindi inseriremo i nostri dati nei risultati per rendere WordPress pensare che il nostro plugin si trova nel repository dei plugin di WordPress. I dati che inseriremo verranno dal nostro repository GitHub e dovrebbero imitare i dati forniti dal repository dei plugin.

Impostazione del progetto GitHub

Prima di procedere con la codifica, parliamo prima di GitHub e di come lo useremo per fornire i dati di cui abbiamo bisogno per alimentare WordPress.

Avrai bisogno di un repository GitHub privato o pubblico. Il tuo repository dovrebbe contenere tutti i tuoi file plugin e non una copia compressa del tuo plugin.

Useremo una caratteristica interessante chiamata GitHub Uscite.

La cosa buona delle versioni è che ottiene l'attuale base di codice nel repository e crea un file zip scaricabile per ogni versione specifica. Possiamo dire a WordPress di scaricare questo file zip quando aggiorniamo il nostro plugin.

Un'altra cosa positiva di Releases è che possiamo inserire i dettagli dell'aggiornamento del plugin nelle note di rilascio. Possiamo quindi analizzarlo e visualizzarlo nella lightbox di WordPress per i dettagli sull'aggiornamento dei plugin. Possiamo andare oltre e persino consentire il markdown di GitHub per il nostro log delle modifiche.

Quando è il momento di distribuire un aggiornamento al nostro plug-in, segui la formattazione nell'immagine sopra quando crei una nuova versione:

  • Nome del tag: Versione plugin (solo il numero)
  • Note di rilascio: La descrizione dell'aggiornamento
Puoi leggere ulteriori informazioni su GitHub Releases nel loro articolo Release Your Software

Creazione della nostra classe di aggiornamento

Ora è il momento di codificare il nostro plugin!

Innanzitutto, creiamo il punto di partenza per la nostra classe:

class BFIGitHubPluginUpdater private $ slug; // plugin slug private $ pluginData; // plugin data private $ username; // Nome utente GitHub private $ repo; // Nome repository GitHub private $ pluginFile; // __FILE__ del nostro plugin privato $ githubAPIResult; // detiene i dati da GitHub private $ accessToken; // Funzione token di repository privato GitHub __construct ($ pluginFile, $ gitHubUsername, $ gitHubProjectName, $ accessToken = ") add_filter (" pre_set_site_transient_update_plugins ", array ($ this," setTransitent ")); add_filter (" plugins_api ", array ($ this, "setPluginInfo"), 10, 3); add_filter ("upgrader_post_install", array ($ this, "postInstall"), 10, 3); $ this-> pluginFile = $ pluginFile; $ this-> username = $ gitHubUsername ; $ this-> repo = $ gitHubProjectName; $ this-> accessToken = $ accessToken; // Ottieni informazioni sul nostro plug-in dalla funzione privata di WordPress initPluginData () // code here // Ottieni informazioni sul nostro plugin da GitHub private function getRepoReleaseInfo () // code here // Inserisci informazioni sulla versione del plugin per ottenere la funzione pubblica di notifica di aggiornamento setTransitent ($ transient) // codice qui restituisce $ transient; // Inserisci le informazioni sulla versione del plug-in da visualizzare nel dettagli lightbox public function setPluginInfo ($ false, $ action, $ response) // codice eh rispedire $ risposta;  // Esegui ulteriori azioni per installare correttamente la nostra funzione pubblica plugin installInstall ($ true, $ hook_extra, $ result) // codice qui restituisce $ result; 

Questa è la struttura di classe che useremo. Abbiamo definito principalmente tutte le funzioni che utilizzeremo e abbiamo creato i nostri ganci filtro. Questa classe non fa nulla al momento, tranne che per assegnare valori alle proprietà della classe.

Gli argomenti del costruttore

Per la nostra classe da eseguire, avremo bisogno di alcuni argomenti:

  • $ pluginfile: Chiameremo questa classe dal nostro script del plugin principale, questo dovrebbe avere il valore __FILE__. In seguito otterremo dettagli sul nostro plug-in.
  • $ gitHubUsername: Il tuo nome utente GitHub
  • $ gitHubProjectName: Il nome del repository GitHub
  • $ access token: Un token di accesso che ci permetterà di visualizzare i dettagli di un repository privato GitHub. Se il tuo progetto è ospitato in un repository pubblico di GitHub, lascia questo campo vuoto.

Ora riempiamo le funzioni della nostra classe con del codice.

Puoi ottenere ulteriori informazioni sulla creazione di token di accesso dalla guida di GitHub. Puoi anche leggere come funziona l'API GitHub.

Il initPluginData Funzione

Questa è la funzione più semplice della nostra classe. Avremo bisogno dello slug del nostro plugin e di altre informazioni nel resto dello script, quindi stiamo mettendo le chiamate necessarie in una funzione per comodità.

$ this-> slug = plugin_basename ($ this-> pluginFile); $ this-> pluginData = get_plugin_data ($ this-> pluginFile);

Il getRepoReleaseInfo Funzione

Questa funzione si basa sulla comunicazione con GitHub per ottenere le informazioni sulla versione. Useremo l'API GitHub per ottenere dettagli sulla nostra ultima versione. Quindi conserva tutto ciò che otteniamo nel nostro githubAPIResult proprietà per l'elaborazione futura.

Il pre_set_site_transient_update_plugins filtro viene chiamato due volte da WordPress, una volta quando controlla gli aggiornamenti dei plugin, poi un altro dopo che ottiene i risultati. Dato che utilizzeremo questa funzione in quel filtro, interrogheremo l'API GitHub due volte. Abbiamo solo bisogno di ottenere informazioni da GitHub una volta:

// Fallo solo una volta se (! Empty ($ this-> githubAPIResult)) return; 

Successivamente, utilizzeremo l'API GitHub per ottenere informazioni sulle nostre versioni:

// Interroga l'API di GitHub $ url = "https://api.github.com/repos/$this->username/$this->repo/releases"; // Abbiamo bisogno del token di accesso per i repository privati ​​se (! Empty ($ this-> accessToken)) $ url = add_query_arg (array ("access_token" => $ this-> accessToken), $ url);  // Ottieni i risultati $ this-> githubAPIResult = wp_remote_retrieve_body (wp_remote_get ($ url)); if (! empty ($ this-> githubAPIResult)) $ this-> githubAPIResult = @json_decode ($ this-> githubAPIResult); 

Infine, terremo i dati solo per l'ultima versione del plugin:

// Usa solo l'ultima versione se (is_array ($ this-> githubAPIResult)) $ this-> githubAPIResult = $ this-> githubAPIResult [0]; 

Ora possiamo ottenere i dati del nostro plugin da GitHub. Analizzeremo questi dati nelle funzioni successive.

Il setTransitent Funzione

Questa funzione viene chiamata quando WordPress verifica gli aggiornamenti dei plugin. Il nostro compito qui è usare i nostri dati di rilascio di GitHub per fornire informazioni per il nostro aggiornamento del plugin.

La prima cosa che facciamo è controllare se WordPress ha già controllato gli aggiornamenti dei plugin prima. In tal caso, non è necessario eseguire nuovamente il resto della funzione.

// Se prima abbiamo controllato i dati del plugin, non ricontrollare if (vuoto ($ transient-> checked)) return $ transient; 

Successivamente, otterremo le informazioni del plugin che useremo:

// Ottieni plugin e informazioni sulla release di GitHub $ this-> initPluginData (); $ This-> getRepoReleaseInfo ();

Dopo aver chiamato queste due funzioni, possiamo controllare la versione del nostro plug-in locale dalla versione (il nome del tag) trovata in GitHub. Possiamo usare PHP conveniente version_compare funzione per confrontare i due valori:

// Controlla le versioni se dobbiamo fare un aggiornamento $ doUpdate = version_compare ($ this-> githubAPIResult-> tag_name, $ transient-> controllato [$ this-> slug]);

Infine, è disponibile un aggiornamento del plug-in, è necessario chiedere all'amministratore di visualizzare una notifica di aggiornamento. Lo facciamo riempiendo il $ transitoria variabile con le nostre informazioni aggiornate sui plugin.

// Aggiorna il transitorio per includere i dati del plugin aggiornato se ($ doUpdate == 1) $ package = $ this-> githubAPIResult-> zipball_url; // Include il token di accesso per i repository GitHub privati ​​se (! Empty ($ this-> accessToken)) $ package = add_query_arg (array ("access_token" => $ this-> accessToken), $ package);  $ obj = new stdClass (); $ obj-> slug = $ this-> slug; $ obj-> new_version = $ this-> githubAPIResult-> tag_name; $ obj-> url = $ this-> pluginData ["PluginURI"]; $ obj-> package = $ package; $ transient-> response [$ this-> slug] = $ obj;  return $ transient;

Dopo questa funzione elabora le nostre informazioni su GitHub, il nostro amministratore sarebbe in grado di visualizzare le notifiche nella pagina di amministrazione del plugin:

Il setPluginInfo Funzione

Lo scopo di questa funzione è quello di raccogliere dettagli riguardanti il ​​plugin aggiornato dalle note di rilascio. Tutte queste informazioni saranno visualizzate all'interno di un lightbox quando il Visualizza i dettagli della versione x.x. il collegamento è cliccato.

Innanzitutto, prendiamo le informazioni del nostro plug-in:

// Ottieni plugin e informazioni sulla release di GitHub $ this-> initPluginData (); $ This-> getRepoReleaseInfo ();

Quindi controlliamo se è fuori tempo di mostrare qualcosa. Possiamo controllare se stiamo cercando di caricare le informazioni per il nostro plugin corrente controllando il lumaca:

// Se non viene trovato nulla, non fare nulla se (vuoto ($ response-> slug) || $ response-> slug! = $ This-> slug) return false; 

Per visualizzare i dettagli del plug-in, è necessario aggiungere manualmente le informazioni del plug-in a $ risposta variabile, normalmente questa variabile verrà popolata con i risultati del repository plugin di WordPress:

// Aggiungi le informazioni del plugin $ response-> last_updated = $ this-> githubAPIResult-> published_at; $ response-> slug = $ this-> slug; $ response-> plugin_name = $ this-> pluginData ["Name"]; $ response-> version = $ this-> githubAPIResult-> tag_name; $ response-> author = $ this-> pluginData ["AuthorName"]; $ response-> homepage = $ this-> pluginData ["PluginURI"]; // Questa è la nostra versione scarica il file zip $ downloadLink = $ this-> githubAPIResult-> zipball_url; // Include il token di accesso per i repository GitHub privati ​​se (! Empty ($ this-> accessToken)) $ downloadLink = add_query_arg (array ("access_token" => $ this-> accessToken), $ downloadLink);  $ response-> download_link = $ downloadLink;

Finora abbiamo aggiunto i dettagli del plugin, ma non abbiamo ancora analizzato le nostre note di rilascio dalla nostra versione di GitHub. Controlliamo ciò che abbiamo nelle note di rilascio:

Nelle note di rilascio, abbiamo specificato tre dettagli riguardanti la nostra versione: il nostro log delle modifiche, seguito dalla versione WordPress minima richiesta, quindi l'ultima versione di WordPress in cui è stato testato il plug-in. Stiamo analizzando questo testo ed estraiamo questi valori.

Dato che stiamo ospitando il nostro plugin in GitHub, sarebbe bello poter usare il markdown GitHub nelle nostre note di rilascio. Userò una classe PHP chiamata ParseDown per convertire il testo del markdown in HTML:

// Analizzeremo le note di rilascio del markdown di GitHub, includiamo il parser require_once (plugin_dir_path (__FILE__). "Parsedown.php");

Creeremo anche schede nel lightbox per renderlo conforme al modo in cui i plugin ospitati dal repository WordPress mostrano le loro informazioni. Uno sarà per la descrizione del plugin e l'altro sarà per il nostro log delle modifiche:

// Crea schede nella lightbox $ response-> sections = array ('description' => $ this-> pluginData ["Description"], 'changelog' => class_exists ("Parsedown")? Parsedown :: instance () - > parse ($ this-> githubAPIResult-> body): $ this-> githubAPIResult-> body);

Finalmente estrarremo i valori per il richiede e testato:

// Ottiene la versione richiesta di WP se disponibile $ matches = null; preg_match ("/requires:\s([\d\.]+)/i", $ this-> githubAPIResult-> body, $ matches); if (! empty ($ matches)) if (is_array ($ matches)) if (count ($ matches)> 1) $ response-> requires = $ matches [1];  // Ottiene la versione testata di WP se disponibile $ matches = null; preg_match ("/tested:\s([\d\.]+)/i", $ this-> githubAPIResult-> body, $ matches); if (! empty ($ matches)) if (is_array ($ matches)) if (count ($ matches)> 1) $ response-> tested = $ matches [1];  restituisce $ response;

Il postinstall Funzione

Quest'ultima funzione ci occuperemo dell'esecuzione di ulteriori processi che abbiamo bisogno di installare completamente il nostro plugin dopo che è stato scaricato.

Quando crei una versione per il nostro repository GitHub, crea automaticamente un file zip per quella versione specifica. Il nome file per il file zip è generato da GitHub con il formato reponame-tagname.zip. Questo contiene anche una directory in cui si trovano i nostri file di plugin. Allo stesso modo, il nome della directory per questo segue anche il formato reponame-tagname.

Normalmente, quando WordPress scarica e decomprime un archivio plugin, il nome della directory del plugin non cambia. Se sei la directory dei plugin è my-impressionante-plugin, dopo aver cancellato i vecchi file plugin e decompresso quello aggiornato, la directory verrebbe comunque chiamata my-impressionante-plugin. Ma poiché GitHub cambia il nome della directory del nostro plugin ogni volta che distribuiamo un rilascio, WordPress non sarà in grado di trovare il nostro plugin. Sarebbe ancora in grado di installarlo, ma non sarà in grado di riattivarlo. Possiamo risolvere questo problema rinominando la nuova directory in modo che corrisponda a quella precedente.

Cominciando dall'inizio:

// Ottieni informazioni sul plugin $ this-> initPluginData ();

Successivamente dobbiamo verificare se il nostro plugin è attualmente attivato, quindi possiamo riattivarlo in seguito:

// Ricorda se il nostro plugin è stato precedentemente attivato $ wasActivated = is_plugin_active ($ this-> slug);

Ora rinominiamo la nostra directory di plugin aggiornata in modo che corrisponda a quella precedente. Stiamo usando la funzione mossa qui, ma dal momento che stiamo specificando la stessa directory, sarebbe come rinominarlo:

// Poiché siamo ospitati in GitHub, la nostra cartella di plugin dovrebbe avere una dirname di // reponame-tagname cambiarla in quella originale: global $ wp_filesystem; $ pluginFolder = WP_PLUGIN_DIR. DIRECTORY_SEPARATOR. dirname ($ this-> slug); $ wp_filesystem-> move ($ result ['destination'], $ pluginFolder); $ result ['destination'] = $ pluginFolder;

L'ultimo passo sarebbe riattivare il plugin:

// Riattiva il plugin se necessario se ($ wasActivated) $ activate = activate_plugin ($ this-> slug);  return $ result;

Chiamando la nostra classe di aggiornamento GitHub

Ora che la lezione è terminata, tutto ciò che resta da fare è chiamarlo nel nostro file plugin principale:

require_once ('BFIGitHubPluginUploader.php'); if (is_admin ()) new BFIGitHubPluginUpdater (__FILE__, 'myGitHubUsername', "Repo-Name"); 

Cercandolo

Questo è tutto! Basta includere questa classe e chiamarla nel tuo plugin, e dovrebbe iniziare a verificare automaticamente gli aggiornamenti.

Per verificare se funziona, creare una nuova versione per il repository GitHub e seguire le linee guida indicate in precedenza:

Una volta creato il tuo rilascio, puoi forzare WordPress a verificare la presenza di aggiornamenti facendo clic sul pulsante Aggiorna presente nella barra di amministrazione.

Conclusione

Spero che tu abbia imparato qualcosa su come funziona WordPress e come viene eseguito l'intero processo di aggiornamento dei plugin. Puoi scaricare lo script completo dai link di download nella parte superiore di questo articolo.

Spero che questo articolo ti sia piaciuto. Apprezzo molto qualsiasi commento, commento e suggerimento. Condividi i tuoi pensieri qui sotto!