Оновіть плагін з особистого API


9

Я розробляю плагін WordPress в той момент, який я не хочу в сховищі плагінів Wordpress. Однак я все ще хочу мати можливість надсилати оновлення для своїх клієнтів із власного сховища API.

Я читав досить багато про це, і одна річ, яка, здається, є щось про pre_set_site_transient_update_pluginsфільтру, проте я не можу знайти багато інформації про це. Я спробував цей підручник ( http://konstruktors.com/blog/wordpress/2538-automatic-updates-for-plugins-and-themes-hosted-outside-wordpress-extend/ ), над яким я не міг працювати. Я можу сказати з коментарів, що інші насправді можуть налагодити цю роботу з тим, що повинно бути майже поточною версією WP (остання відповідь 22 квітня).

Я спробував встановити плагін із сайту та помістити папку API на другий домен, але повідомлення про оновлення, яке я зазвичай отримую, коли оновлення доступне, взагалі ніде не відображалось.

Я не впевнений, чи дійсно можливо, щоб користувацькі плагіни запускали автоматичне оновлення з інших сховищ, тому я хотів би почути, чи є хтось тут із цим досвідом? Рішення в підручнику здавалося простим рішенням - мені цікаво, чи можна якось це зробити більш досконалим способом?

Будемо дуже вдячні за будь-яку допомогу в отриманні цього автоматичного оновлення з мого власного сховища!

(PS: я запускаю WP версії 3.1.3)


Я можу запізнитися на вечірку, але ви можете знайти плагін, який я створив саме для цього: Сервер оновлення плагінів WP
froger.me

Відповіді:


7

Для користі інших, хто знайде цю сторінку, я пропоную тим, хто бажає надати свої власні оновлення поза офіційним сховищем WP, ознайомитись із цим проектом на GitHub, який демонструє функціональність:

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


2

Так, це можливо. Цьому розділу присвячена розробка професійних плагінів WordPress . Якщо ви ще цього не зробите, підберіть копію. Це обов’язково допоможе.


Я фактично знайшов PDF-версію цього інтернету, але це, здається, не працювало і для мене.
Саймон

Це робить роботу , якщо ви зробите це правильно, я зробив це, подивіться на HTTP API, codex.wordpress.org/HTTP_API
Wyck

Я тільки почав заново. Поки що у мене є підключення до перевірки оновлення плагінів, використовуючи add_filter("pre_set_site_transient_update_plugins","dne_altapi_check"); функцію dne_altapi_check, яка містить print_r("hi");- проте коли я натискаю кнопку "Перевірити ще раз" під час оновлень, вона взагалі нічого не друкує. Чи я робити щось не так під час підключення до перевірки оновлень?
Саймон

Пам’ятаю, хтось написав клас для співробітників оновлення плагінів, але можна знайти посилання на цю посаду: /
Mamaduka

1

Існує цей комерційний менеджер API плагінів та оновлень тем для WooCommerce, який спеціально працює, якщо плагін або тема не розміщується на wordpress.org. Він розроблений для надання оновлень для власних плагінів та тем. Плагін призначений для тих, хто не хоче писати його самостійно і потребує безлічі функцій, а також робочі приклади для плагінів та тем, які продаються.

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


1

Існує також акуратний сервіс на веб- сайті http://wp-updates.com/ - ви отримуєте одну тему або плагін безкоштовно. FYI - це не мій сайт, але я спробував це деякий час тому, і це здалося досить непоганим.


Здається, приємна послуга, але я не помітив (майже у вільному плані) HTTPS у веб-панелі управління, ні в спілкуванні: крім того, я не знайшов жодної перевірки власності під час перевірки оновлення (мені здається, це дуже просто POST-запит), я вважаю, що речі можуть бути вкрадені, знаючи ім'я плагіна та роблячи деякі здогадки. Я хотів би використовувати його, якби це здавалося трохи професійнішим з боку безпеки.
realnice

1

Для встановлення одного сайту (я його не перевіряв на багатьох сайтах), є лише два гачки, які потрібно оновити із зовнішньої служби, наприклад github або gitlab. У наведеному нижче коді я використовую gitlab, оскільки саме зараз я використовую для розміщення свого коду. Я, мабуть, повинен абстрагувати частини gitlab ...

Перший гачок, який вам потрібно буде використовувати, - це pre_set_site_transient_update_themes. Це фільтр, який WordPress використовує для встановлення сайту_transient для показу, чи є оновлення. Використовуйте цей гачок, щоб підключитися до віддаленої версії та побачити, чи є оновлення. Якщо вони є, то змініть перехідний процес, щоб WordPress знав, що є оновлення, і може показувати повідомлення користувачеві.

Інший гачок, який вам потрібно буде використовувати, - це upgrader_source_selection. Цей фільтр потрібен для gitlab у будь-якому випадку, оскільки ім'я завантаженої папки не те саме, що тема, тому ми використовуємо цей гачок, щоб перейменувати його на правильне ім'я. Якщо ви віддаленому сховищу надає поштовий індекс з правильним іменем, вам цей гачок навіть не потрібен.

Третій, необов’язковий, гачок, який ви можете використовувати, - це auto_update_themeякщо ви хочете автоматично оновити свою тему. У наведеному нижче прикладі я використовую цей гачок для автоматичного оновлення лише цієї конкретної теми.

Цей код протестовано лише за допомогою WordPress 4.9.x. Для цього потрібен PHP> 7.0.

function.php

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

updateter.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 );
  }
}
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.