Вопрос или проблема
Я разрабатываю игру и планирую, что у меня будут партнеры, чтобы они могли запускать игру, как моя.
Для этого я разработал плагин с некоторыми классами и функциями для обработки запросов игры.
Поскольку этот плагин совершенно бесполезен для всех пользователей wordpress, я хочу отправить этот плагин своим партнерам по электронной почте в формате zip, но хочу, чтобы они могли обновлять плагин, если потребуется.
Таким образом, возможно ли хранить плагин на собственном сервере и заставить плагин проверять обновления с моего сайта, а не из каталога wp plugins?
Весь кредит за следующий пост принадлежит Абиду Омару. Полный учебник можно найти на Tuts+: Руководство по WordPress HTTP API: Автоматические обновления плагинов
Суть в том, чтобы создать новый класс, который будет отправлять внешний файл (API) и возвращать плагин для загрузки, если он устарел. Ниже предполагается, что вы создаете плагин, используя следующий код (не в functions.php
или каталоге mu-plugins
).
wp_autoupdate.php
будет внешним файлом (в вашем плагине), содержащим класс Auto Update, определенный ниже.update.php
— это внешний “удаленный” файл, используемый для проверки обновлений, создающий API.
Ниже будет наша начальная настройка.
add_action( 'init', 'wptuts_activate_au' );
function wptuts_activate_au()
{
require_once ('wp_autoupdate.php'); // Файл, содержащий класс ниже
$wptuts_plugin_current_version = '1.0';
$wptuts_plugin_remote_path="http://localhost/update.php";
$wptuts_plugin_slug = plugin_basename(__FILE__);
new wp_auto_update( $wptuts_plugin_current_version, $wptuts_plugin_remote_path, $wptuts_plugin_slug );
}
Класс автoобновления – wp_autoupdate.php
class wp_auto_update
{
/**
* Текущая версия плагина
* @var string
*/
public $current_version;
/**
* Удаленный путь обновления плагина
* @var string
*/
public $update_path;
/**
* Плагин Slug (plugin_directory/plugin_file.php)
* @var string
*/
public $plugin_slug;
/**
* Название плагина (plugin_file)
* @var string
*/
public $slug;
/**
* Инициализирует новый экземпляр класса Auto-Update для WordPress
* @param string $current_version
* @param string $update_path
* @param string $plugin_slug
*/
function __construct( $current_version, $update_path, $plugin_slug )
{
// Установить открытые переменные класса
$this->current_version = $current_version;
$this->update_path = $update_path;
$this->plugin_slug = $plugin_slug;
list ($t1, $t2) = explode("https://wordpress.stackexchange.com/", $plugin_slug);
$this->slug = str_replace( '.php', '', $t2 );
// определить альтернативное API для проверки обновлений
add_filter( 'pre_set_site_transient_update_plugins', array( &$this, 'check_update' ) );
// Определить альтернативный ответ для проверки информации
add_filter('plugins_api', array(&$this, 'check_info'), 10, 3);
}
/**
* Добавить наш самохостящийся автoобновляющий плагин в фильтр временных данных
*
* @param $transient
* @return object $ transient
*/
public function check_update( $transient )
{
if( empty( $transient->checked ) ) {
return $transient;
}
// Получить удаленную версию
$remote_version = $this->getRemote_version();
// Если доступна более новая версия, добавить обновление
if ( version_compare( $this->current_version, $remote_version, '<' ) ) {
$obj = new stdClass();
$obj->slug = $this->slug;
$obj->new_version = $remote_version;
$obj->url = $this->update_path;
$obj->package = $this->update_path;
$transient->response[$this->plugin_slug] = $obj;
}
var_dump( $transient );
return $transient;
}
/**
* Добавить наше самохостящее описание в фильтр
*
* @param boolean $false
* @param array $action
* @param object $arg
* @return bool|object
*/
public function check_info( $false, $action, $arg )
{
if( $arg->slug === $this->slug ) {
$information = $this->getRemote_information();
return $information;
}
return false;
}
/**
* Вернуть удаленную версию
* @return string $remote_version
*/
public function getRemote_version()
{
$request = wp_remote_post( $this->update_path, array( 'body' => array( 'action' => 'version' ) ) );
if( ! is_wp_error( $request ) || wp_remote_retrieve_response_code( $request ) === 200 ) {
return $request['body'];
}
return false;
}
/**
* Получить информацию о удаленной версии
* @return bool|object
*/
public function getRemote_information()
{
$request = wp_remote_post( $this->update_path, array( 'body' => array( 'action' => 'info' ) ) );
if( ! is_wp_error( $request ) || wp_remote_retrieve_response_code( $request ) === 200) {
return unserialize( $request['body'] );
}
return false;
}
/**
* Вернуть состояние лицензирования плагина
* @return boolean $remote_license
*/
public function getRemote_license()
{
$request = wp_remote_post( $this->update_path, array( 'body' => array( 'action' => 'license' ) ) );
if( ! is_wp_error( $request ) || wp_remote_retrieve_response_code( $request ) === 200 ) {
return $request['body'];
}
return false;
}
}
Удаленное (внешнее) обновление API – update.php
if( isset( $_POST['action'] ) ) {
switch( $_POST['action'] ) {
case 'version':
echo '1.1';
break;
case 'info':
$obj = new stdClass();
$obj->slug = 'plugin.php';
$obj->plugin_name="plugin.php";
$obj->new_version = '1.1';
$obj->requires="3.0";
$obj->tested = '3.3.1';
$obj->downloaded = 12540;
$obj->last_updated = '2012-01-12';
$obj->sections = array(
'description' => 'Новая версия плагина автoобновления',
'another_section' => 'Это еще один раздел',
'changelog' => 'Некоторые новые функции'
);
$obj->download_link = 'http://localhost/update.php';
echo serialize( $obj );
case 'license':
echo 'false';
break;
}
} else {
header( 'Cache-Control: public' );
header( 'Content-Description: File Transfer' );
header( 'Content-Type: application/zip' );
readfile( 'update.zip' );
}
update.php
будет хранить самую актуальную информацию о вашем плагине. Используя функцию init
, вы можете передать текущую установленную версию, чтобы она могла отправить ее в update.php
и проверить с текущей, которая у нее есть. Есть место для улучшения кода, чтобы он был более оптимизирован, но я использовал это именно (как бы) для того, чтобы сделать то, что вы пытаетесь сделать, поэтому это хороший отправной пункт.
Да, возможно разместить ваш собственный плагин и заставить плагин проверять обновления с вашего сервера. Вам нужно будет добавить пользовательский код в ваш плагин, чтобы сообщить ему о проверке обновлений на вашем сервере. Существуют некоторые фреймворки, которые помогут вам это сделать, попробуйте эти:
Я возвращался к этой “проблеме” несколько раз на протяжении многих лет, и некоторые из проектов на GitHub, которые были поделены в ответах, здесь просто фантастичны, хотя некоторые из них сейчас кажутся мертвыми. Также были некоторые расширения WooCommerce, которые пытались решить эту проблему, одновременно предоставляя решение для выставления счетов, но они были довольно неудобны и трудны для поддержки в моем опыте.
Однако еще одним замечательным решением является Git Updater Энди Фраген. Вместо необходимости размещения ZIP-файлов вашего плагина на вашем (ненадежном) сервере и/или взлома ваших плагинов и тем для добавления дополнительных файлов и зависимостей и т.д., вы просто добавляете простую однострочную “шапку” внутри вашего файла style.css
для тем WordPress или внутри вашего файла plugin.php
для плагинов. Буквально, это все, что требуется.
Вот пример:
https://github.com/littlebizzy/hovercraft/blob/master/style.css
GitHub Theme URI: littlebizzy/hovercraft
Подход Энди — один из самых чистых, которые я видел, и сэкономил мне кучу времени и головной боли в поисках простого решения для обновления моих расширений WordPress.
Он работает из коробки для общественных репозиториев и поддерживает API-ключи для частных репозиториев. Таким образом, вы можете просто иметь, например, подписку PayPal или Patreon, где клиенты платят за доступ к коду, который они хотят, и затем вы предоставляете им API-ключ к этим частным репозиториям на GitHub или GitLab и т.д. Вам не нужно управлять какими-либо ZIP-файлами или выставлением счетов вообще.
А реализация занимает всего около 30 секунд для большинства проектов.
Я разработал другое решение для самохостинга плагинов напрямую из Github и доставки обновлений. Больше деталей вы можете найти в этом посте: https://eduardovillao.me/how-to-self-host-wordpress-plugins-on-github-and-deliver-updates/
Вкратце вам понадобится только:
- Этот Github action: https://github.com/eduardovillao/wp-self-host-updater-generator
- Добавьте этот файл в ваш плагин: https://github.com/eduardovillao/wp-self-host-updater-checker
Удачи с вашими проектами!
Ответ или решение
Хостинг плагина WordPress на собственном сервере и обеспечение обновлений: руководство для разработчиков
В современных условиях разработка собственных решений для распространения и обновления плагинов WordPress становится актуальной задачей для многих IT специалистов. В рассматриваемом случае, целью является обеспечение постоянного доступа партнеров к актуальной версии разработанного плагина для поддержки их игровых проектов.
Основной сценарий
-
Создание плагина: Ваш плагин, разработанный специально для обработки игровых запросов, должен быть упакован в файл ZIP. Этот файл вы можете отправлять своим партнерам для установки.
-
Автоматическое обновление: Чтобы реализовать автоматическое обновление плагина, нужно создать систему, при которой WordPress будет проверять обновления не через стандартный каталог плагинов, а с вашего собственного сервера.
Шаги по реализации автообновлений
1. Настройка основного кода
Создайте файл wp_autoupdate.php
, который будет содержать класс для проверки и установки обновлений:
class wp_auto_update {
public $current_version;
public $update_path;
public $plugin_slug;
public $slug;
function __construct($current_version, $update_path, $plugin_slug) {
$this->current_version = $current_version;
$this->update_path = $update_path;
$this->plugin_slug = $plugin_slug;
list ($t1, $t2) = explode('/', $plugin_slug);
$this->slug = str_replace('.php', '', $t2);
add_filter('pre_set_site_transient_update_plugins', array(&$this, 'check_update'));
add_filter('plugins_api', array(&$this, 'check_info'), 10, 3);
}
public function check_update($transient) {
if (empty($transient->checked)) {
return $transient;
}
$remote_version = $this->getRemote_version();
if (version_compare($this->current_version, $remote_version, '<')) {
$obj = new stdClass();
$obj->slug = $this->slug;
$obj->new_version = $remote_version;
$obj->url = $this->update_path;
$obj->package = $this->update_path;
$transient->response[$this->plugin_slug] = $obj;
}
return $transient;
}
public function check_info($false, $action, $arg) {
if ($arg->slug === $this->slug) {
$information = $this->getRemote_information();
return $information;
}
return false;
}
public function getRemote_version() {
$request = wp_remote_post($this->update_path, array('body' => array('action' => 'version')));
if (!is_wp_error($request) || wp_remote_retrieve_response_code($request) === 200) {
return $request['body'];
}
return false;
}
public function getRemote_information() {
$request = wp_remote_post($this->update_path, array('body' => array('action' => 'info')));
if (!is_wp_error($request) || wp_remote_retrieve_response_code($request) === 200) {
return unserialize($request['body']);
}
return false;
}
}
2. Настройка сервера для обновлений
Создайте файл update.php
на сервере, который будет отвечать на запросы плагина о новых версиях:
if (isset($_POST['action'])) {
switch ($_POST['action']) {
case 'version':
echo '1.1'; // ваша актуальная версия
break;
case 'info':
$obj = new stdClass();
$obj->slug = 'plugin-slug';
$obj->new_version = '1.1';
$obj->requires = '5.0';
$obj->tested = '5.8';
$obj->downloaded = 10;
$obj->last_updated = '2023-08-10';
$obj->sections = array(
'description' => 'Описание нового функционала и исправлений.',
'changelog' => 'Перечень изменений.'
);
$obj->download_link = 'http://ваш-домен.com/update.zip';
echo serialize($obj);
break;
}
}
3. Интеграция и альтернативные решения
Для упрощения и автоматизации этого процесса можно воспользоваться готовыми решениями и фреймворками:
- Plugin Update Checker: Фреймворк для проверки обновлений плагинов.
- Git Updater: Решение для интеграции с Git репозиториями, которое позволяет упростить процесс обновления и управления доступом.
Заключение
Самостоятельная организация сервиса обновлений плагинов требует начальных технических навыков, но дает значительное преимущество в управлении версиями и поддержке партнеров. Использование приведенных методов позволит вам обеспечивать актуальность вашего плагина, предлагать партнерам простой и надежный механизм обновления.