อัปเดตปลั๊กอินจาก 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 ออนไลน์ แต่ดูเหมือนจะไม่เหมาะกับฉัน
Simon

มันใช้งานได้ถ้าคุณทำถูกต้องฉันทำเสร็จแล้วลองดูที่ 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");- อย่างไรก็ตามเมื่อฉันกดปุ่ม "ตรวจสอบอีกครั้ง" ภายใต้การอัปเดตจะไม่พิมพ์อะไรเลย .. ทำสิ่งผิดปกติเมื่อเชื่อมต่อตัวตรวจสอบการอัปเดตหรือไม่
Simon

ฉันจำได้ว่ามีคนเขียนคลาสสำหรับเจ้าหน้าที่อัปเดตปลั๊กอิน แต่สามารถค้นหาลิงก์สำหรับโพสต์นั้น: /
Mamaduka

1

มีตัวจัดการปลั๊กอินและชุดอัพเดท API เชิงพาณิชย์สำหรับ WooCommerce ซึ่งทำงานเฉพาะถ้าปลั๊กอินหรือชุดรูปแบบไม่ได้โฮสต์อยู่ใน wordpress.org มันถูกออกแบบมาเพื่อให้การอัปเดตสำหรับปลั๊กอินและธีมที่โฮสต์ด้วยตนเอง ปลั๊กอินสำหรับผู้ที่ไม่ต้องการเขียนเองและต้องการคุณสมบัติมากมายรวมถึงตัวอย่างการทำงานสำหรับปลั๊กอินและธีมที่กำลังขาย

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


1

นอกจากนี้ยังมีบริการที่เรียบร้อยที่http://wp-updates.com/ - คุณจะได้รับหนึ่งธีมหรือปลั๊กอินฟรี FYI - นี่ไม่ใช่เว็บไซต์ของฉัน แต่ฉันได้ลองไปซักพักแล้วและมันก็ค่อนข้างดี


ดูเหมือนจะเป็นบริการที่ดี แต่ฉันไม่ได้สังเกตเห็น (เกือบตามแผนฟรี) HTTPS ในแผงควบคุมของเว็บหรือในการสื่อสาร: นอกจากนี้ฉันไม่พบการตรวจสอบความเป็นเจ้าของใด ๆ เมื่อทำการตรวจสอบการอัปเดต คำขอโพสต์) ฉันรู้สึกว่าสิ่งต่าง ๆ อาจถูกขโมยรู้ชื่อปลั๊กอินและคาดเดาบางอย่าง ฉันชอบที่จะใช้มันถ้ามันดูเป็นมืออาชีพมากขึ้นในด้านความปลอดภัย
จริงๆ

1

สำหรับการติดตั้งไซต์เดียว (ฉันยังไม่ได้ทดสอบบนเว็บไซต์หลายแห่ง) มีเพียงสอง hooks ที่คุณต้องการอัปเดตจากบริการภายนอกเช่น github หรือ gitlab ในรหัสด้านล่างฉันใช้ gitlab เนื่องจากเป็นสิ่งที่ฉันใช้เพื่อโฮสต์รหัสของฉันตอนนี้ ฉันควรสรุปส่วน gitlab ที่เป็นนามธรรมออกมา ...

pre_set_site_transient_update_themesเบ็ดแรกที่คุณจะต้องใช้คือ นี่คือตัวกรองที่ WordPress ใช้เพื่อตั้งค่า site_transient ให้แสดงหากมีการอัปเดตที่พร้อมใช้งาน ใช้เบ็ดนี้เพื่อเชื่อมต่อกับรุ่นระยะไกลของคุณและดูว่ามีการอัพเดตหรือไม่ หากมีอยู่ให้ปรับเปลี่ยน transient เพื่อให้ WordPress ทราบว่ามีการอัปเดตและสามารถแสดงการแจ้งเตือนแก่ผู้ใช้

ตะขออื่น ๆ upgrader_source_selectionที่คุณจะต้องใช้คือ จำเป็นต้องใช้ตัวกรองนี้สำหรับ gitlab อยู่แล้วเนื่องจากชื่อโฟลเดอร์ที่ดาวน์โหลดไม่เหมือนกับชุดรูปแบบดังนั้นเราจึงใช้ตะขอนี้เพื่อเปลี่ยนชื่อเป็นชื่อที่ถูกต้อง หากคุณเป็นที่เก็บข้อมูลระยะไกลให้ซิปที่มีชื่อที่ถูกต้องคุณไม่จำเป็นต้องใช้เบ็ดนี้

เบ็ดสามตัวเลือกที่คุณสามารถใช้ได้คือauto_update_themeถ้าคุณต้องการอัปเดตธีมของคุณโดยอัตโนมัติ ในตัวอย่างด้านล่างฉันใช้ hook นี้เพื่ออัปเดตเฉพาะชุดรูปแบบนี้โดยอัตโนมัติ

รหัสนี้ได้รับการทดสอบด้วย WordPress 4.9.x เท่านั้น มันต้องการ 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 );
  }
}
โดยการใช้ไซต์ของเรา หมายความว่าคุณได้อ่านและทำความเข้าใจนโยบายคุกกี้และนโยบายความเป็นส่วนตัวของเราแล้ว
Licensed under cc by-sa 3.0 with attribution required.