如果您正在开发待售插件,这将很有帮助,如果你不是开发者,那可以划走了。wordpress支持了从自己服务器更新我们自己的插件、主题,而无需将其托管至wordpress。下面,我们就详细介绍其部署方法,帮助像我一样需要的人。
插件
插件主要用到三个过滤钩子:
1、plugins_api (插件信息,这里用来更改插件信息的,对于更新没有任何鸟用)
2、site_transient_update_plugins (临时缓存,这里用来更新插件)
3、upgrader_process_complete (更新完成执行,这里用来清理缓存)
示例插件代码(你可以将其放到你的插件代码中,然后修改info.json的地址即可,我的示例插件目录结构是这样的[kekc_cn_-update-plugin/kekc_cn_-update-plugin.php]):
<?php
/*
* Plugin name: 自定义服务器更新插件示例
* Description: 自定义服务器更新插件示例,实现从插件从自己服务器更新插件
* Version: 1.0
* Author: KEKC
* Author URI: https://www.kekc.cn
* License: GPL
*/
/**/
defined( 'ABSPATH' ) || exit;
if( ! class_exists( 'kekc_cn_UpdateChecker' ) ) {
class kekc_cn_UpdateChecker{
public $plugin_slug;
public $version;
public $cache_key;
public $cache_allowed;
public function __construct() {
$this->plugin_slug = plugin_basename( __DIR__ );
$this->version = '1.0';
$this->cache_key = 'kekc_cn__custom_upd';
$this->cache_allowed = false;
add_filter( 'plugins_api', array( $this, 'info' ), 20, 3 );
add_filter( 'site_transient_update_plugins', array( $this, 'update' ) );
add_action( 'upgrader_process_complete', array( $this, 'purge' ), 10, 2 );
}
public function request(){
$remote = get_transient( $this->cache_key );
if( false === $remote || ! $this->cache_allowed ) {
$remote = wp_remote_get(
'https://www.kekc.cn/wp-content/uploads/updater/info.json',
array(
'timeout' => 10,
'headers' => array(
'Accept' => 'application/json'
)
)
);
if(
is_wp_error( $remote )
|| 200 !== wp_remote_retrieve_response_code( $remote )
|| empty( wp_remote_retrieve_body( $remote ) )
) {
return false;
}
set_transient( $this->cache_key, $remote, DAY_IN_SECONDS );
}
$remote = json_decode( wp_remote_retrieve_body( $remote ) );
return $remote;
}
function info( $res, $action, $args ) {
// print_r( $action );
// print_r( $args );
// 如果你现在没有得到插件信息,就什么都不要做
if( 'plugin_information' !== $action ) {
return $res;
}
// 检查是不是我们要更新的插件
if( $this->plugin_slug !== $args->slug ) {
return $res;
}
// 获取更新信息
$remote = $this->request();
if( ! $remote ) {
return $res;
}
$res = new stdClass();
$res->name = $remote->name;
$res->slug = $remote->slug;
$res->version = $remote->version;
$res->tested = $remote->tested;
$res->requires = $remote->requires;
$res->author = $remote->author;
$res->author_profile = $remote->author_profile;
$res->download_link = $remote->download_url;
$res->trunk = $remote->download_url;
$res->requires_php = $remote->requires_php;
$res->last_updated = $remote->last_updated;
$res->sections = array(
'description' => $remote->sections->description,
'installation' => $remote->sections->installation,
'changelog' => $remote->sections->changelog
);
if( ! empty( $remote->banners ) ) {
$res->banners = array(
'low' => $remote->banners->low,
'high' => $remote->banners->high
);
}
return $res;
}
public function update( $transient ) {
if ( empty($transient->checked ) ) {
return $transient;
}
$remote = $this->request();
if(
$remote
&& version_compare( $this->version, $remote->version, '<' )
&& version_compare( $remote->requires, get_bloginfo( 'version' ), '<' )
&& version_compare( $remote->requires_php, PHP_VERSION, '<' )
) {
$res = new stdClass();
$res->slug = $this->plugin_slug;
$res->plugin = plugin_basename( __FILE__ ); // kekc_cn_-update-plugin/kekc_cn_-update-plugin.php
$res->new_version = $remote->version;
$res->tested = $remote->tested;
$res->package = $remote->download_url;
$transient->response[ $res->plugin ] = $res;
}
return $transient;
}
public function purge(){
if (
$this->cache_allowed
&& 'update' === $options['action']
&& 'plugin' === $options[ 'type' ]
) {
// 只需在安装新的插件版本时清理缓存。
delete_transient( $this->cache_key );
}
}
}
new kekc_cn_UpdateChecker();
}
上面的插件呢,还用到一个info.json文件,是储存在服务器的,主要是用来存放插件信息的,其内容为:
{
"name" : "自定义服务器更新插件示例",
"slug" : "kekc_cn-update-checker",
"author" : "<a href='https://www.kekc.cn'>kekc</a>",
"author_profile" : "http://profiles.wordpress.org/kekc",
"version" : "2.0",
"download_url" : "https://www.kekc.cn/wp-content/uploads/updater/kekc_cn-update-checker.zip",
"requires" : "3.0",
"tested" : "5.8",
"requires_php" : "5.3",
"last_updated" : "2021-01-30 02:10:00",
"sections" : {
"description" : "这个简单的插件什么都不做,只从自定义服务器上获取更新。",
"installation" : "点击激活按钮,就可以了。",
"changelog" : "<h4>版本1.0</h4><ul><li>修复BUG</li><li>首次发布。</li></ul>"
},
"banners" : {
"low" : "https://www.kekc.cn/wp-content/uploads/updater/banner-772x250.jpg",
"high" : "https://www.kekc.cn/wp-content/uploads/updater/banner-1544x500.jpg"
}
}
info.json里面的download_url是更新的插件地址,注意插件的目录结构需要和之前的插件一致,两个banner图自备。
主题
使用到的钩子
1、site_transient_update_themes (其实这个钩子和上面的site_transient_update_plugins是一样的)
不考虑性能,我们的代码可以这样:
<?php
add_filter( 'site_transient_update_themes', 'kekc_cn_update_themes' );
function kekc_cn_update_themes( $transient ) {
// 得到主题文件夹名称,如果你不是在主题中插入我们的代码请更改此项,比如你的主题有子主题,请自己测试一下
$stylesheet = get_template();
// 获得本地主题的版本号
$theme = wp_get_theme();
//$theme = wp_get_theme( $stylesheet );//更新子主题试试这个,但可能会在更新过程中导致主题重复,你们自己测试一下。
$version = $theme->get( 'Version' );
// 获取远程的主题信息
$remote = wp_remote_get(
'https://www.kekc.cn/wp-content/uploads/theme-updater/info.json',
array(
'timeout' => 10,
'headers' => array(
'Accept' => 'application/json'
)
)
);
// 判断有没有正常获取到远程的主题信息
if(
is_wp_error( $remote )
|| 200 !== wp_remote_retrieve_response_code( $remote )
|| empty( wp_remote_retrieve_body( $remote ) )
) {
return $transient;
}
// 对响应body进行json编码
$remote = json_decode( wp_remote_retrieve_body( $remote ) );
if( ! $remote ) {
return $transient; // who knows, maybe JSON is not valid
}
$data = array(
'theme' => $stylesheet,
'url' => $remote->details_url,
'requires' => $remote->requires,
'requires_php' => $remote->requires_php,
'new_version' => $remote->version,
'package' => $remote->download_url,
);
// 检查版本号[插件版本、wordpress版本、PHP版本]
if(
$remote
&& version_compare( $version, $remote->version, '<' )
&& version_compare( $remote->requires, get_bloginfo( 'version' ), '<' )
&& version_compare( $remote->requires_php, PHP_VERSION, '<' )
) {
$transient->response[ $stylesheet ] = $data;
} else {
$transient->no_update[ $stylesheet ] = $data;
}
return $transient;
}
上面的代码,每次访问管理员面板都会重新从我们的更新服务器上获取更新,所有管理页面的加载速度都开始变慢。我们可以缓存一下,使用set_transient,代码为:
<?php
if( false == $remote = get_transient( 'kekc-theme-update'.$version ) ) {
// 获取远程主题信息
$remote = wp_remote_get(
'https://rudrastyh.com/wp-content/uploads/theme-updater/info.json',
array(
'timeout' => 10,
'headers' => array(
'Accept' => 'application/json'
)
)
);
// 获取失败就暂停操作
if(
is_wp_error( $remote )
|| 200 !== wp_remote_retrieve_response_code( $remote )
|| empty( wp_remote_retrieve_body( $remote ) )
) {
return $transient;
}
$remote = json_decode( wp_remote_retrieve_body( $remote ) );
if( ! $remote ) {
return $transient; // 也许JSON是无效的?
}
set_transient( 'kekc-theme-update'.$version, $remote, HOUR_IN_SECONDS ); //HOUR_IN_SECONDS是1小时,还有其他的,比如DAY_IN_SECONDS(相当于86400),这里可以放秒数
}
info.json可以用PHP来返回,毕竟PHP可以返回任何文件类型:
<?php
$update = array(
'version' => '2.0',
'details_url' => 'https://www.kekc.cn/themes/kekc_cn-theme/changelog.html',
'download_url' => ''
);
if( ! empty( $_GET[ 'license_key' ] ) && license_check_logic( $_GET[ 'license_key' ] ) {
$update[ 'download_url' ] = 'https://www.kekc.cn/themes/kekc_cn-theme/2.0.zip';
}
header( 'Content-Type: application/json' );
echo json_encode( $update );
结语
其实吧,都非常简单,我的代码都感觉用多了,你可以参照我写的自己重写一下。或者你觉得都太累,你可以参照GitHub上的一个项目(plugin-update-checker),来从自己服务器上更新插件和主题,请忽略项目名称,他是支持插件和主题的。
学完我上面的代码,你甚至可以试试实现一个wordpress主题、插件商店。
暂无评论内容