Actualizar complemento desde API personal

9

Estoy desarrollando un complemento de wordpress en el momento que no quiero en el repositorio de Wordpress. Sin embargo, todavía quiero poder enviar actualizaciones a mis clientes desde mi propio repositorio de API.

He estado leyendo bastante acerca de esto, y una cosa que parece ser algo relacionado con el filtro pre_set_site_transient_update_plugins , sin embargo no puedo encontrar mucha información sobre esto. He probado este tutorial ( enlace ) que no pude ponerme a trabajar. Puedo decir por los comentarios que otros realmente pueden hacer que esto funcione con lo que debe ser casi la versión actual de WP (última respuesta, 22 de abril).

Intenté instalar el complemento desde el sitio y colocar la carpeta API en un segundo dominio, pero la notificación de actualización que generalmente recibo cuando hay una actualización disponible no se mostró en ningún lugar.

¿No estoy seguro de si es realmente posible tener complementos personalizados que ejecuten la actualización automática desde otros repositorios, por lo que me gustaría saber si alguien aquí tiene alguna experiencia con esto? La solución en el tutorial parecía ser una solución fácil. Me pregunto si de alguna manera es posible hacerlo de una manera más avanzada.

¡Cualquier ayuda para que esta actualización automática de mi propio repositorio funcione sería muy apreciada!

(PS: Estoy ejecutando WP versión 3.1.3)

    
pregunta Simon 29.05.2011 - 22:41

5 respuestas

7

Para el beneficio de otros que encuentran esta página, sugiero que aquellos que deseen proporcionar sus propias actualizaciones fuera del repositorio oficial de WP, verifiquen este proyecto en GitHub, que demuestra la funcionalidad:

enlace

    
respondido por el k3davis 17.08.2012 - 16:44
2

Sí, esto es posible. Hay un capítulo completo en Desarrollo profesional de complementos de WordPress dedicado a esto. Si aún no lo has hecho, recoge una copia. Definitivamente ayudará.

    
respondido por el EAMann 29.05.2011 - 22:54
1

Existe este administrador comercial de API de actualización de temas y complementos para WooCommerce que funciona específicamente si el complemento o tema no está alojado en wordpress.org. Está diseñado para proporcionar actualizaciones para complementos y temas alojados automáticamente. El complemento es para aquellos que no quieren escribirlo usted mismo y necesitan muchas funciones, además de ejemplos prácticos de complementos y temas que se venden.

enlace

    
respondido por el Todd Lahman 15.07.2013 - 10:25
1

También hay un servicio excelente en enlace : obtienes un tema o complemento gratis. Para tu información, este no es mi sitio, pero lo probé hace un tiempo y me pareció bastante bueno.

    
respondido por el cwd 24.09.2013 - 05:53
1

Para una instalación de un solo sitio (no lo he probado en un sitio múltiple), solo hay dos enlaces que necesita actualizar desde un servicio externo como github o gitlab. En el código a continuación, uso gitlab ya que eso es lo que uso para alojar mi código ahora. Probablemente debería abstraer las partes de gitlab ...

El primer enlace que necesitarás usar es pre_set_site_transient_update_themes . Este es el filtro que WordPress utiliza para configurar el site_transient para mostrar si hay actualizaciones disponibles. Use este gancho para conectarse a su versión remota y ver si hay actualizaciones disponibles. Si los hay, modifique el transitorio para que WordPress sepa que hay actualizaciones y pueda mostrar el aviso al usuario.

El otro enganche que necesitarás usar es upgrader_source_selection . Este filtro es necesario, para gitlab de todos modos, porque el nombre de la carpeta descargada no es el mismo que el tema, por lo que usamos este gancho para cambiar el nombre al nombre correcto. Si su repositorio remoto proporciona un zip con el nombre correcto, entonces ni siquiera necesita este enlace.

El tercer enlace opcional que puede usar es auto_update_theme si desea actualizar automáticamente su tema. En el siguiente ejemplo, uso este gancho para actualizar automáticamente solo este tema específico.

Este código solo se ha probado con WordPress 4.9.x. Requiere PHP > 7.0.

functions.php

//* Load the updater.
require PATH_TO . 'updater.php';
$updater = new updater();
\add_action( 'init', [ $updater, 'init' ] );

updater.php

/**
 * @package StackExchange\WordPress
 */
declare( strict_types = 1 );
namespace StackExchange\WordPress;

/**
 * Class for updating the theme.
 */
class updater {

  /**
   * @var Theme slug.
   */
  protected $theme = 'theme';

  /**
   * @var Theme repository name.
   */
  protected $repository = 'project/theme';

  /**
   * @var Repository domain.
   */
  protected $domain = 'https://gitlab.com/';

  /**
   * @var CSS endpoint for repository.
   */
  protected $css_endpoint = '/raw/master/style.css';

  /**
   * @var ZIP endpoint for repository.
   */
  protected $zip_endpoint = '/repository/archive.zip';

  /**
   * @var Remote CSS URI.
   */
  protected $remote_css_uri;

  /**
   * @var Remote ZIP URI.
   */
  protected $remote_zip_uri;

  /**
   * @var Remote version.
   */
  protected $remote_version;

  /**
   * @var Local version.
   */
  protected $local_version;

  /**
   * Method called from the init hook to initiate the updater
   */
  public function init() {
    \add_filter( 'auto_update_theme', [ $this, 'auto_update_theme' ], 20, 2 );
    \add_filter( 'upgrader_source_selection', [ $this, 'upgrader_source_selection' ], 10, 4 );
    \add_filter( 'pre_set_site_transient_update_themes', [ $this, 'pre_set_site_transient_update_themes' ] );
  }

  /**
   * Method called from the auto_update_theme hook.
   * Only auto update this theme.
   * This hook and method are only needed if you want to auto update the theme.
   *
   * @return bool Whether to update the theme.
   */
  public function auto_update_theme( bool $update, \stdClass $item ) : bool {
    return $this->theme === $item->theme;
  }

  /**
   * Rename the unzipped folder to be the same as the existing folder
   *
   * @param string       $source        File source location
   * @param string       $remote_source Remote file source location
   * @param \WP_Upgrader $upgrader      \WP_Upgrader instance
   * @param array        $hook_extra    Extra arguments passed to hooked filters
   *
   * @return string | \WP_Error The updated source location or a \WP_Error object on failure
   */
  public function upgrader_source_selection( string $source, string $remote_source, \WP_Upgrader $upgrader, array $hook_extra ) {
    global $wp_filesystem;

    $update = [ 'update-selected', 'update-selected-themes', 'upgrade-theme' ];

    if( ! isset( $_GET[ 'action' ] ) || ! in_array( $_GET[ 'action' ], $update, true ) ) {
      return $source;
    }

    if( ! isset( $source, $remote_source ) ) {
      return $source;
    }

    if( false === stristr( basename( $source ), $this->theme ) ) {
      return $source;
    }

    $basename = basename( $source );
    $upgrader->skin->feedback( esc_html_e( 'Renaming theme directory.', 'bootstrap' ) );
    $corrected_source = str_replace( $basename, $this->theme, $source );

    if( $wp_filesystem->move( $source, $corrected_source, true ) ) {
      $upgrader->skin->feedback( esc_html_e( 'Rename successful.', 'bootstrap' ) );
      return $corrected_source;
    }

    return new \WP_Error();
  }

  /**
   * Add respoinse to update transient if theme has an update.
   *
   * @param $transient
   *
   * @return
   */
  public function pre_set_site_transient_update_themes( $transient ) {
    require_once ABSPATH . 'wp-admin/includes/class-wp-upgrader.php';
    $this->local_version = ( \wp_get_theme( $this->theme ) )->get( 'Version' );

    if( $this->hasUpdate() ) {
      $response = [
        'theme'       => $this->theme,
        'new_version' => $this->remote_version,
        'url'         => $this->construct_repository_uri(),
        'package'     => $this->construct_remote_zip_uri(),
        'branch'      => 'master',
      ];
      $transient->response[ $this->theme ] = $response;
    }

    return $transient;
  }

  /**
   * Construct and return the URI to the remote stylesheet
   *
   * @return string The remote stylesheet URI
   */
  protected function construct_remote_stylesheet_uri() : string {
    return $this->remote_css_uri = $this->domain . $this->repository . $this->css_endpoint;
  }

  /**
   * Construct and return the URI to the remote ZIP file
   *
   * @return string The remote ZIP URI
   */
  protected function construct_remote_zip_uri() : string {
    return $this->remote_zip_uri = $this->domain . $this->repository . $this->zip_endpoint;
  }

  /**
   * Construct and return the URI to remote repository
   *
   * @access protected
   * @since  1.0
   *
   * @return string The remote repository URI
   */
  protected function construct_repository_uri() : string {
    return $this->repository_uri = $this->domain . \trailingslashit( $this->repository );
  }

  /**
   * Get and return the remote version
   *
   * @return string The remote version
   */
  protected function get_remote_version() : string {
    $this->remote_stylesheet_uri = $this->construct_remote_stylesheet_uri();
    $response = $this->remote_get( $this->remote_stylesheet_uri );
    $response = str_replace( "\r", "\n", \wp_remote_retrieve_body( $response ) );
    $headers = [ 'Version' => 'Version' ];

    foreach( $headers as $field => $regex ) {
      if( preg_match( '/^[ \t\/*#@]*' . preg_quote( $regex, '/' ) . ':(.*)$/mi', $response, $match ) && $match[1] ) {
        $headers[ $field ] = _cleanup_header_comment( $match[1] );
      }
      else {
        $headers[ $field ] = '';
      }
    }

    return $this->remote_version = ( '' === $headers[ 'Version' ] ) ? '' : $headers[ 'Version' ];
  }

  /**
   * Return whether the theme has an update
   *
   * @return bool Whether the theme has an update
   */
  protected function hasUpdate() : bool {
    if( ! $this->remote_version ) $this->remote_version = $this->get_remote_version();
    return version_compare( $this->remote_version, $this->local_version, '>' );
  }

  /**
   * Wrapper for \wp_remote_get()
   *
   * @param string $url  The URL to get
   * @param array  $args Array or arguments to pass through to \wp_remote_get()
   *
   * @return array|WP_Error Return the request or an error object
   */
  protected function remote_get( string $url, array $args = [] ) {
    return \wp_remote_get( $url, $args );
  }
}
    
respondido por el Nathan Johnson 03.03.2018 - 19:37

Lea otras preguntas en las etiquetas