Perbarui plugin dari API pribadi

9

Saya sedang mengembangkan plugin wordpress saat ini yang saya tidak inginkan dalam repositori plugin Wordpress. Namun saya masih ingin dapat mendorong pembaruan kepada pelanggan saya dari repositori API saya sendiri.

Saya sudah membaca sedikit tentang ini, dan satu hal yang sepertinya adalah tentang pre_set_site_transient_update_pluginsfilter, namun saya tidak dapat menemukan banyak info tentang ini. Saya sudah mencoba tutorial ini ( http://konstruktors.com/blog/wordpress/2538-automatic-updates-for-plugins-and-themes-hosted-outside-wordpress-extend/ ) yang saya tidak dapat bekerja. Saya dapat mengatakan dari komentar bahwa orang lain benar-benar bisa mendapatkan ini berfungsi dengan apa yang harus hampir versi WP saat ini (respon terbaru 22 Apr).

Saya mencoba menginstal plugin dari situs dan meletakkan folder API di domain kedua, tetapi pemberitahuan pembaruan yang biasanya saya dapatkan ketika pembaruan tersedia, tidak muncul sama sekali.

Saya tidak yakin apakah benar-benar memungkinkan plugin kustom menjalankan pembaruan otomatis dari repositori lain sehingga saya ingin mendengar jika ada orang di sini yang memiliki pengalaman sama sekali dengan hal ini? Solusi dalam tutorial sepertinya merupakan solusi yang mudah - Saya ingin tahu apakah itu mungkin dilakukan dengan cara yang lebih maju?

Setiap bantuan untuk mendapatkan pembaruan otomatis ini dari repositori saya sendiri akan sangat dihargai!

(PS: Saya menjalankan WP versi 3.1.3)

Simon
sumber
Saya mungkin terlambat ke pesta, tetapi Anda dapat menemukan plugin yang saya buat persis untuk itu: WP Plugin Update Server
froger.me

Jawaban:

2

Ya, ini mungkin. Ada satu bab dalam Pengembangan Plugin WordPress Profesional yang didedikasikan untuk ini. Jika belum, ambil salinannya. Itu pasti akan membantu.

EAMann
sumber
Saya benar-benar menemukan versi PDF online ini, tetapi itu sepertinya tidak berhasil untuk saya juga.
Simon
Ini berfungsi jika Anda melakukannya dengan benar, saya telah melakukannya, lihat HTTP API, codex.wordpress.org/HTTP_API
Wyck
Saya baru mulai lagi. Apa yang saya dapatkan sejauh ini adalah mengaitkan ke cek pembaruan plugin menggunakan add_filter("pre_set_site_transient_update_plugins","dne_altapi_check"); Setelah itu saya memiliki fungsi dne_altapi_check yang berisi print_r("hi");- namun ketika saya menekan tombol "Periksa lagi" di bawah pembaruan, itu tidak mencetak apa-apa sama sekali .. Apakah saya melakukan sesuatu yang salah saat menghubungkan ke pemeriksa pembaruan?
Simon
Saya ingat seseorang menulis kelas untuk staf pembaruan plugin, tetapi dapat menemukan tautan untuk posting itu: /
Mamaduka
1

Ada manajer Plugin dan Pembaruan Tema API komersial untuk WooCommerce yang secara khusus berfungsi jika plugin atau tema tidak dihosting di wordpress.org. Ini dirancang untuk memberikan pembaruan untuk plugin dan tema yang dihosting sendiri. Plugin ini untuk mereka yang tidak ingin menulisnya sendiri, dan membutuhkan banyak fitur, ditambah contoh yang berfungsi untuk plugin dan tema yang sedang dijual.

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

Todd Lahman
sumber
1

Ada juga layanan yang rapi di http://wp-updates.com/ - Anda mendapatkan satu tema atau plugin gratis. FYI - ini bukan situs saya tapi saya sudah mencobanya beberapa waktu lalu dan sepertinya cukup bagus.

cwd
sumber
Tampaknya layanan yang bagus, tetapi saya tidak melihat (hampir dengan rencana gratis) HTTPS di panel kontrol web atau dalam komunikasi: lebih jauh lagi saya tidak menemukan semacam pemeriksaan kepemilikan ketika melakukan pemeriksaan pembaruan (menurut saya sangat sederhana) Permintaan POST), saya merasa barang-barang bisa dicuri, mengetahui nama plugin dan membuat beberapa tebakan. Saya akan senang menggunakannya, jika tampaknya sedikit lebih profesional di sisi keamanan.
reallynice
1

Untuk pemasangan satu situs (saya belum mengujinya di multi-situs), hanya ada dua kait yang perlu Anda perbarui dari layanan eksternal seperti github atau gitlab. Dalam kode di bawah ini, saya menggunakan gitlab karena itulah yang saya gunakan untuk meng-host kode saya sekarang. Saya mungkin harus abstrak bagian gitlab keluar ...

Kait pertama yang harus Anda gunakan adalah pre_set_site_transient_update_themes. Ini adalah filter yang digunakan WordPress untuk mengatur site_transient untuk ditampilkan jika ada pembaruan yang tersedia. Gunakan kait ini untuk menghubungkan ke versi jarak jauh Anda dan melihat apakah ada pembaruan yang tersedia. Jika ada, maka modifikasi transien sehingga WordPress tahu ada pembaruan dan dapat menampilkan pemberitahuan kepada pengguna.

Pengait lain yang perlu Anda gunakan adalah upgrader_source_selection. Filter ini diperlukan, untuk gitlab, karena nama folder yang diunduh tidak sama dengan tema, jadi kami menggunakan kait ini untuk mengubah nama menjadi nama yang benar. Jika repositori jarak jauh Anda menyediakan zip dengan nama yang benar, maka Anda bahkan tidak memerlukan pengait ini.

Kait ketiga, opsional, yang dapat Anda gunakan adalah auto_update_themejika Anda ingin memperbarui tema secara otomatis. Dalam contoh di bawah ini, saya menggunakan pengait ini untuk secara otomatis memperbarui hanya tema khusus ini.

Kode ini hanya diuji dengan WordPress 4.9.x. Ini membutuhkan 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 );
  }
}
Nathan Johnson
sumber