web-dev-qa-db-de.com

Aktualisieren Sie das Plugin von der persönlichen API

Ich entwickle gerade ein WordPress-Plugin, das ich nicht im WordPress-Plugin-Repository haben möchte. Ich möchte jedoch weiterhin in der Lage sein, Updates von meinem eigenen API-Repository an meine Kunden zu senden.

Ich habe ziemlich viel darüber gelesen und eine Sache, über die sich etwas auszutauschen scheint, ist der pre_set_site_transient_update_plugins-Filter, aber ich kann nicht viele Informationen dazu finden. Ich habe dieses Tutorial ausprobiert ( http://konstruktors.com/blog/wordpress/2538-automatic-updates-for-plugins-and-themes-hosted-outside-wordpress-extend/ ), das ich nicht konnte ' Ich werde nicht arbeiten. Aus den Kommentaren kann ich ersehen, dass andere dies tatsächlich mit der aktuellsten Version von WP zum Laufen bringen können (letzte Antwort 22. April).

Ich habe versucht, das Plugin von der Site zu installieren und den API-Ordner in eine zweite Domäne zu verschieben, aber die Update-Benachrichtigung, die ich normalerweise erhalte, wenn ein Update verfügbar ist, wurde überhaupt nicht angezeigt.

Ich bin mir nicht sicher, ob es tatsächlich möglich ist, dass benutzerdefinierte Plug-ins das automatische Update von anderen Repositorys aus ausführen, also würde ich gerne hören, ob jemand hier überhaupt Erfahrung mit diesem Zeug hat. Die Lösung im Tutorial schien eine einfache Lösung zu sein - ich frage mich, ob es irgendwie möglich ist, es auf fortgeschrittenere Weise zu tun?

Jede Hilfe, die dieses automatische Update von meinem eigenen Repository bekommt, wäre sehr dankbar!

(PS: Ich verwende WP Version 3.1.3)

9
Simon

Für andere, die diese Seite finden, empfehle ich diejenigen, die ihre eigenen Updates außerhalb des offiziellen Repositorys WP bereitstellen möchten. Schauen Sie sich dieses Projekt auf GitHub an, das die Funktionalität demonstriert:

https://github.com/jeremyclark13/automatic-theme-plugin-update

7
k3davis

Ja, das ist möglich. Es gibt ein ganzes Kapitel in Professionelle WordPress-Plugin-Entwicklung , das sich diesem Thema widmet. Wenn Sie es noch nicht getan haben, holen Sie sich eine Kopie. Es wird definitiv helfen.

2
EAMann

Es gibt diesen kommerziellen Plugin und Theme Update API Manager für WooCommerce, der speziell funktioniert, wenn das Plugin oder Theme nicht auf wordpress.org gehostet wird. Es wurde entwickelt, um Updates für selbst gehostete Plugins und Themes bereitzustellen. Das Plugin ist für diejenigen gedacht, die es nicht selbst schreiben möchten und viele Funktionen benötigen, sowie Arbeitsbeispiele für Plugins und Themen, die verkauft werden.

http://www.toddlahman.com/shop/wordpress-automatic-update-api-manager/

1
Todd Lahman

Für eine Single-Site-Installation (ich habe sie nicht an mehreren Standorten getestet) müssen Sie nur zwei Hooks von einem externen Dienst wie github oder gitlab aktualisieren. Im folgenden Code verwende ich gitlab, da ich damit meinen Code gerade hoste. Ich sollte wahrscheinlich die Gitlab-Teile herausziehen ...

Der erste Haken, den Sie verwenden müssen, ist pre_set_site_transient_update_themes. Dies ist der Filter, den WordPress verwendet, um den site_transient so einzustellen, dass angezeigt wird, ob Updates verfügbar sind. Verwenden Sie diesen Hook, um eine Verbindung zu Ihrer Remote-Version herzustellen und festzustellen, ob Updates verfügbar sind. Wenn dies der Fall ist, ändern Sie den Transienten so, dass WordPress weiß, dass Aktualisierungen vorliegen, und können Sie dem Benutzer den Hinweis anzeigen.

Der andere Haken, den Sie verwenden müssen, ist upgrader_source_selection. Dieser Filter wird ohnehin für gitlab benötigt, da der Name des heruntergeladenen Ordners nicht mit dem Design übereinstimmt. Daher verwenden wir diesen Hook, um ihn in den richtigen Namen umzubenennen. Wenn Ihr Remote-Repository eine Zip mit dem richtigen Namen bereitstellt, benötigen Sie diesen Hook nicht einmal.

Der dritte optionale Hook, den Sie verwenden können, ist auto_update_theme, wenn Sie Ihr Design automatisch aktualisieren möchten. Im folgenden Beispiel verwende ich diesen Hook, um nur dieses bestimmte Thema automatisch zu aktualisieren.

Dieser Code wurde nur mit WordPress 4.9.x getestet. Es erfordert 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 );
  }
}
1
Nathan Johnson

Es gibt auch einen netten Service unter http://wp-updates.com/ - Sie erhalten ein Theme oder Plugin kostenlos. Zu Ihrer Information - dies ist nicht meine Seite, aber ich habe es vor einiger Zeit versucht und es schien ziemlich gut zu sein.

1
cwd