Distribuyendo tus complementos en GitHub con actualizaciones automáticas

WordPress ha hecho conveniente que los complementos se implementen al público. Simplemente coloque su complemento en el repositorio de complementos de WordPress y podrá encontrarlo fácilmente desde el interior de su panel de control..

Probablemente una de las mejores características del repositorio es que facilita la actualización de complementos desde el interior del panel. Las notificaciones de actualización se muestran dentro del panel de control, y realizar una actualización es tan fácil como hacer clic en Actualizar ahora botón.

¿Pero qué tal si quisieras alojar el plugin por tu cuenta? La conveniente función de actualización no estará disponible si aloja su complemento fuera del repositorio de WordPress. Tampoco se notificará a los usuarios de una actualización disponible..

Este artículo le enseñará que con un poco de codificación creativa, puede alojar sus propios complementos de WordPress en GitHub mientras conserva la función de actualización automática..

¿Por qué alojar su complemento en GitHub?

Puede haber varias razones por las que desearía alojar su complemento fuera del repositorio de complementos de WordPress. Una de las principales restricciones que ofrece el repositorio es que debe obtener una licencia de su complemento como GPLv2. No me detendré en los detalles de la licencia, pero en pocas palabras significa que cualquiera puede compartir su trabajo. Entonces, si desea vender su complemento, el hospedarlo en un repositorio privado de GitHub es ahora una opción que puede considerar.

Sin embargo, debido a la forma en que se construyó WordPress, alojar su complemento en GitHub deshabilitar actualizaciones automáticas para nuestro plugin. Para comprender por qué este es el caso, debemos entender cómo WordPress maneja las actualizaciones de los complementos.

Puede obtener más información sobre el repositorio de complementos de WordPress leyendo sus Pautas detalladas de complementos.

Cómo WordPress actualiza los complementos

Primero, investiguemos cómo WordPress realiza las actualizaciones de los complementos para comprender mejor por qué los complementos auto alojados no pueden tener actualizaciones automáticas.

WordPress comprueba periódicamente el repositorio de WordPress para las actualizaciones de sus complementos instalados. Recibe una gran cantidad de información sobre cada complemento, como su última versión y la URL del paquete del complemento. Esto es lo que generalmente vemos en la página de administración del complemento cuando se nos notifica de una actualización:

Cuando hacemos clic en el Ver detalles de la versión x.x Enlace, WordPress realiza otra búsqueda en el repositorio de complementos. Esta vez obtiene información más detallada sobre el complemento, como su descripción, el registro de cambios, la versión de WordPress en la que se ha probado y mucho más. Esta información se nos muestra en una caja de luz:

Por último, cuando el Actualizar ahora se hace clic en el enlace, se descarga e instala el paquete de complementos actualizado.

Entonces, ¿por qué las actualizaciones automáticas no funcionan para los complementos auto alojados?? Es porque WordPress intenta encontrarlo en el repositorio de complementos de WordPress y no puede encontrarlo allí.!

El plan de juego

Nuestro plan es habilitar las actualizaciones automáticas con nuestro complemento alojado en GitHub.

Aquí hay una lista de lo que debemos hacer para que funcione:

  • Necesitamos una forma de implementar actualizaciones de complementos en GitHub.
  • Deberíamos mostrar notificaciones de actualización de la versión del plugin.,
  • Sería bueno mostrar los detalles del complemento cuando el Ver detalles de la versión x.x se hace clic en el enlace.
  • También queremos instalar con éxito la actualización del complemento cuando el actualizar ahora se hace clic en el enlace,

Cómo ejecutar el plan

Usaremos algunos filtros de WordPress para poder implementar nuestro plan de juego. Estos son:

  • pre_set_site_transient_update_plugins. Este filtro se llama cuando WordPress intenta buscar actualizaciones de complementos.
  • plugins_api. Este se usa cuando WordPress muestra los detalles de actualización del complemento.
  • upgrader_post_install. Por último, esto se llama después de instalar un complemento correctamente.

Vamos a conectarnos a estos filtros, luego empujaremos nuestros datos a los resultados para hacer WordPress pensar que nuestro plugin está en el repositorio de plugins de WordPress. Los datos que ingresaremos provendrán de nuestro repositorio de GitHub, y deben imitar los datos que proporciona el repositorio de complementos..

Configurando el Proyecto GitHub

Antes de continuar con la codificación, primero hablemos de GitHub y cómo la usaremos para proporcionar los datos que necesitamos para alimentar WordPress.

Necesitará un repositorio privado o público de GitHub. Su repositorio debe contener todos sus archivos de complementos, y no una copia comprimida de su complemento..

Estaremos usando una característica genial de GitHub llamada Lanzamientos.

Lo bueno de las versiones es que obtiene la base de código actual en el repositorio y crea un archivo zip descargable para cada versión específica. Podemos decirle a WordPress que descargue este archivo zip al actualizar nuestro complemento.

Otra cosa buena acerca de las versiones es que podemos incluir los detalles de la actualización de nuestro complemento en las notas de la versión. Luego podemos analizar esto y mostrarlo en la caja de luz que muestra WordPress para conocer los detalles de la actualización del complemento. Podemos ir más lejos e incluso permitir que GitHub reduzca los costos para nuestro registro de cambios..

Cuando sea el momento de implementar una actualización de nuestro complemento, siga el formato en la imagen de arriba cuando cree una nueva versión:

  • Nombre de etiqueta: Versión plugin (solo el numero)
  • Notas de lanzamiento: La descripción de la actualización.
Puede leer más sobre los lanzamientos de GitHub en su artículo Libere su software

Creando nuestra clase Updater

Ahora es el momento de codificar nuestro plugin.!

Primero, creamos el punto de partida para nuestra clase:

class BFIGitHubPluginUpdater private $ slug; // plugin slug private $ pluginData; // plugin data private $ username; // nombre de usuario GitHub privado $ repo; // Nombre de repositorio de GitHub private $ pluginFile; // __FILE__ de nuestro plugin privado $ githubAPIResult; // tiene datos de GitHub private $ accessToken; // Función de token de repo privado de GitHub __construct ($ pluginFile, $ gitHubUsername, $ gitHubProjectName, $ accessToken = ") add_filter (" pre_set_site_transient_update_plugins ", array ($ propulsor")); este, "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; // Obtenga información sobre nuestro complemento de la función privada de WordPress initPluginData () // code here // Obtenga información sobre nuestro complemento de GitHub private function getRepoReleaseInfo () // code here // Push en la información de la versión del complemento para obtener la notificación de la actualización public function seteactent ($ transient) // code here return $ transient; // Push en la información de la versión del complemento para mostrar en el detalles lightbox public function setPluginInfo ($ false, $ action, $ response) // code eh volver a $ respuesta;  // Realice acciones adicionales para instalar con éxito nuestro complemento public function postInstall ($ true, $ hook_extra, $ result) // el código devuelve $ result; 

Esta es la estructura de clase que vamos a usar. Simplemente definimos principalmente todas las funciones que vamos a usar y creamos nuestros ganchos de filtro. Esta clase no hace nada a partir del momento, excepto para asignar valores a las propiedades de la clase..

Los argumentos del constructor

Para que nuestra clase se ejecute, necesitaremos algunos argumentos:

  • $ pluginFile: Estaremos llamando a esta clase desde nuestro script de plugin principal, esto debería tener el valor __EXPEDIENTE__. Más adelante veremos detalles sobre nuestro complemento..
  • $ gitHubUsername: Tu nombre de usuario de GitHub
  • $ gitHubProjectName: El nombre de tu repositorio GitHub
  • $ accessToken: Un token de acceso que nos permitirá ver los detalles de un repositorio privado de GitHub. Si su proyecto está alojado en un repositorio público de GitHub, simplemente deje esto en blanco.

Ahora llenemos las funciones de nuestra clase con algún código..

Puede obtener más información sobre la creación de tokens de acceso con la ayuda de GitHub. También puedes leer cómo funciona la API de GitHub.

los initPluginData Función

Esta es la función más simple de nuestra clase. Necesitaremos la información de nuestro plugin y otra información adicional en el resto del script, por lo que estamos poniendo las llamadas necesarias en una función para su comodidad..

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

los getRepoReleaseInfo Función

Esta función tiene que ver con la comunicación con GitHub para obtener nuestra información de lanzamiento. Utilizaremos la API de GitHub para obtener detalles sobre nuestra última versión. Luego guarda todo lo que tengamos en nuestro githubAPIResult propiedad para procesamiento futuro.

los pre_set_site_transient_update_plugins WordPress llama dos veces al filtro, una vez que comprueba si hay actualizaciones de complementos, y luego otra después de obtener resultados. Ya que usaremos esta función en ese filtro, estaremos consultando la API de GitHub dos veces. Solo necesitamos obtener información de GitHub una vez:

// Solo haz esto una vez si (! Empty ($ this-> githubAPIResult)) return; 

A continuación, usaremos la API de GitHub para obtener información sobre nuestros lanzamientos:

// Consulte la API de GitHub $ url = "https://api.github.com/repos/$this-> nombredeusuario/$this->repo/releases"; // Necesitamos el token de acceso para los repositorios privados si (! Vacío ($ this-> accessToken)) $ url = add_query_arg (array ("access_token" => $ this-> accessToken), $ url);  // Obtenga los resultados $ this-> githubAPIResult = wp_remote_retrieve_body (wp_remote_get ($ url)); if (! empty ($ this-> githubAPIResult)) $ this-> githubAPIResult = @json_decode ($ this-> githubAPIResult); 

Por último, solo conservaremos los datos de la última versión del complemento:

// Use solo la última versión if (is_array ($ this-> githubAPIResult)) $ this-> githubAPIResult = $ this-> githubAPIResult [0]; 

Ahora podemos obtener nuestros datos de complementos de GitHub. Estaremos analizando estos datos en las siguientes funciones..

los establecer transit Función

Esta función se llama cuando WordPress comprueba si hay actualizaciones de complementos. Nuestro trabajo aquí es utilizar los datos de la versión de GitHub para proporcionar información para nuestra actualización del complemento.

Lo primero que hacemos es verificar si WordPress ya ha comprobado las actualizaciones de complementos antes. Si es así, entonces no tenemos que ejecutar el resto de la función de nuevo..

// Si hemos revisado los datos del complemento anteriormente, no vuelva a verificar si (vacío ($ transient-> marcado)) return $ transient; 

A continuación, obtendremos la información del complemento que vamos a utilizar:

// Obtener información de la versión del plugin y GitHub $ this-> initPluginData (); $ this-> getRepoReleaseInfo ();

Después de llamar a estas dos funciones, podemos verificar la versión de nuestro complemento local desde la versión (el nombre de la etiqueta) que se encuentra en GitHub. Podemos usar el conveniente de PHP version_compare Función para comparar los dos valores:

// Verifique las versiones si necesitamos hacer una actualización $ doUpdate = version_compare ($ this-> githubAPIResult-> tag_name, $ transient-> checked [$ this-> slug]);

Por último, hay una actualización de complemento disponible, debemos solicitarle al administrador que muestre una notificación de actualización. Hacemos esto llenando el $ transitoria variable con nuestra información actualizada del plugin.

// Actualizar el transitorio para incluir nuestros datos de complemento actualizados si ($ doUpdate == 1) $ package = $ this-> githubAPIResult-> zipball_url; // Incluir el token de acceso para los repositorios privados de GitHub si (! Vacío ($ 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;

Después de que esta función procese nuestra información de GitHub, nuestro administrador podrá mostrar las notificaciones en la página de administración del complemento:

los setPluginInfo Función

El propósito de esta función es recopilar detalles sobre el complemento actualizado de las notas de la versión. Toda esta información se mostrará dentro de una caja de luz cuando el Ver detalles de la versión x.x se hace clic en el enlace.

Primero, obtengamos la información de nuestro plugin:

// Obtener información de la versión del plugin y GitHub $ this-> initPluginData (); $ this-> getRepoReleaseInfo ();

A continuación, verificamos si es hora de mostrar algo o no. Podemos verificar si estamos intentando cargar información para nuestro complemento actual al verificar babosa:

// Si no se encuentra nada, no haga nada si (vacío ($ response-> slug) || $ response-> slug! = $ This-> slug) return false; 

Para mostrar los detalles de nuestro complemento, debemos agregar nuestra información de complemento manualmente a la $ respuesta variable, normalmente esta variable se completaría con los resultados del repositorio de complementos de WordPress:

// Agregar nuestra información del complemento $ response-> last_updated = $ this-> githubAPIResult-> publish_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"]; // Este es nuestro archivo zip de descarga de la versión $ downloadLink = $ this-> githubAPIResult-> zipball_url; // Incluir el token de acceso para los repositorios privados de GitHub si (! Vacío ($ this-> accessToken)) $ downloadLink = add_query_arg (array ("access_token" => $ this-> accessToken), $ downloadLink);  $ response-> download_link = $ downloadLink;

Hasta ahora hemos agregado los detalles de nuestros complementos, pero aún no hemos analizado nuestras notas de lanzamiento de nuestro lanzamiento de GitHub. Vamos a revisar lo que tenemos en nuestras notas de lanzamiento:

En las notas de la versión, hemos especificado tres detalles sobre nuestra versión: nuestro registro de cambios, seguido de la versión mínima requerida de WordPress, luego la última versión de WordPress en la que se probó el complemento. Vamos a analizar este texto y extraer estos valores..

Ya que estamos alojando nuestro plugin en GitHub, sería bueno si pudiéramos tener la capacidad de usar GitHub markdown en nuestras notas de lanzamiento. Voy a usar una clase de PHP llamada ParseDown para convertir el texto de rebaja a HTML:

// Vamos a analizar las notas de la versión del markdown de GitHub, incluido el analizador require_once (plugin_dir_path (__FILE__). "Parsedown.php");

También vamos a crear pestañas en el lightbox para que se ajuste a la forma en que los complementos alojados en el repositorio de WordPress muestran su información. Uno será para la descripción del complemento y el otro será para nuestro registro de cambios:

// Crear pestañas en el lightbox $ response-> section = array ('description' => $ this-> pluginData ["Description"], 'changelog' => class_exists ("Parsedown")? Parsedown :: instance () - > analizar ($ this-> githubAPIResult-> body): $ this-> githubAPIResult-> body);

Finalmente vamos a extraer los valores para el requiere y probado:

// Obtiene la versión requerida de WP si está disponible $ matches = null; preg_match ("/requires:\s([\d\.◆++)/i", $ this-> githubAPIResult-> body, $ matches); if (! empty ($ coincidencias)) if (is_array ($ coincidencias)) if (contar ($ coincidencias)> 1) $ respuesta-> requiere = $ coincidencias [1];  // Obtiene la versión probada de WP si está disponible $ matches = null; preg_match ("/tested:\s([\d\.◆++)/i", $ this-> githubAPIResult-> body, $ matches); if (! empty ($ coincidencias)) if (is_array ($ coincidencias)) if (contar ($ coincidencias)> 1) $ respuesta-> probado = $ coincidencias [1];  devolver $ respuesta;

los postInstalar Función

Esta última función nos ocupará de realizar los procesos adicionales que necesitamos para instalar completamente nuestro complemento después de descargarlo.

Al crear una versión para nuestro repositorio de GitHub, crea automáticamente un archivo zip para esa versión específica. El nombre de archivo para el archivo zip es generado por GitHub con el formato reponame-tagname.zip. Esto también contiene un directorio donde se encuentran nuestros archivos de complemento. Del mismo modo, el nombre del directorio para este también sigue el formato reponame-tagname.

Normalmente, cuando WordPress descarga y descomprime un archivo de complementos, el nombre del directorio de complementos no cambia. Si el directorio de tu plugin es mi-impresionante-plugin, después de eliminar los antiguos archivos de complementos y descomprimir el actualizado, su directorio aún se llamará mi-impresionante-plugin. Pero como GitHub cambia el nombre del directorio de nuestro complemento cada vez que implementamos una versión, WordPress no podrá encontrar nuestro complemento. Todavía podría instalarlo, pero no podrá reactivarlo. Podemos solucionar este problema cambiando el nombre del nuevo directorio para que coincida con el anterior.

Lo primero es lo primero:

// Obtener información del complemento $ this-> initPluginData ();

A continuación, tenemos que verificar si nuestro complemento está actualmente activado, por lo que podemos reactivarlo después:

// Recuerda si nuestro complemento fue previamente activado $ wasActivated = is_plugin_active ($ this-> slug);

Ahora cambiamos el nombre de nuestro directorio de complementos actualizado para que coincida con el anterior. Estamos usando la funcion movimiento aquí, pero como estamos especificando el mismo directorio, sería como cambiarle el nombre:

// Dado que estamos alojados en GitHub, nuestra carpeta de complementos tendría un nombre de direccionamiento de // reponame-tagname y lo cambiaría a nuestro original: global $ wp_filesystem; $ pluginFolder = WP_PLUGIN_DIR. DIRECTORIO_SEPARADOR. dirname ($ this-> slug); $ wp_filesystem-> move ($ result ['destination'], $ pluginFolder); $ resultado ['destino'] = $ pluginFolder;

El último paso sería volver a activar el complemento:

// Reactivar el complemento si es necesario si ($ wasActivated) $ctiv =ctiv_plugin ($ this-> slug);  devolver $ resultado;

Llamando a nuestra clase de actualizador de GitHub

Ahora que la clase ha terminado, todo lo que queda por hacer es llamarlo en nuestro archivo principal de complementos:

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

Probandolo

¡Eso es! Simplemente incluya esta clase y llámela a su complemento, y debería comenzar a buscar actualizaciones automáticamente.

Para probar si funciona, cree una nueva versión para su repositorio de GitHub y siga las pautas indicadas anteriormente:

Una vez que haya creado su versión, puede forzar a WordPress a buscar actualizaciones haciendo clic en el botón de actualización que se encuentra en la barra de administración.

Conclusión

Espero que haya aprendido una o dos cosas sobre cómo funciona WordPress y cómo se realiza todo el proceso de actualización de complementos. Puede descargar el script completo de los enlaces de descarga en la parte superior de este artículo.

Espero que hayan disfrutado este artículo. Aprecio mucho cualquier comentario, comentarios y sugerencias. Comparte tus pensamientos a continuación!