让代码更简单

WordPress插件配置自定义更新

重要:本文最后更新于2022-11-03 16:28:22,某些文章具有时效性,若有错误或已失效,请在下方留言或联系代码狗

在国外大佬博客看到这篇WordPress插件配置自定义更新教程,于是翻译并实践后发布。

仅需使用wordpress核心中的两个过滤器挂钩plugins_apisite_transient_update_plugins,仅此而已。

WordPress插件配置自定义更新
WordPress插件配置自定义更新

1. 准备自定义更新服务器及文件 

一台可以访问的服务器,以及一些配置文件和插件文件。

misha-update-checker.zip 是插件的新版本,info.json 包含所有更新信息,以及在查看插件信息时将在 WordPress 管理员页面上显示的两个图像。

现在开始配置info.json文件,需要注意的是slug必须与插件文件夹一致,否则无法更新。

复制
{
	"name" : "Misha Update Checker",
	"slug" : "misha-update-checker",
	"author" : "<a href='https://rudrastyh.com'>Misha Rudrastyh</a>",
	"author_profile" : "http://profiles.wordpress.org/rudrastyh",
	"version" : "2.0",
	"download_url" : "https://rudrastyh.com/wp-content/uploads/updater/misha-update-checker.zip",
	"requires" : "3.0",
	"tested" : "5.8",
	"requires_php" : "5.3",
	"last_updated" : "2021-01-30 02:10:00",
	"sections" : {
		"description" : "This simple plugin does nothing, only gets updates from a custom server",
		"installation" : "Click the activate button and that's it.",
		"changelog" : "<h4>1.0 –  1 august 2021</h4><ul><li>Bug fixes.</li><li>Initital release.</li></ul>"
	},
	"banners" : {
		"low" : "https://rudrastyh.com/wp-content/uploads/updater/banner-772x250.jpg",
		"high" : "https://rudrastyh.com/wp-content/uploads/updater/banner-1544x500.jpg"
	}
}

另一种方法是info.json通过 PHP 生成。

复制
$update = array(
	'name' => 'Misha Update Checker',
	'slug' => 'misha-update-checker',
	
	...
	
);

header( 'Content-Type: application/json' );
echo json_encode( $update );

如果有多个插件,使用PHP动态生成更新信息更好。

请注意,这个 json 文件里面的参数名称是自定义的,只要与后面的插件解析此json文件统一即可。

还有一个关于 zip 存档中的文件和文件夹结构的重要说明。

错误正确
misha-update-checker.zip
––misha-update-checker.php
––readme.txt
misha-update-checker.zip
––misha-update-checker/
––––misha-update-checker.php
––––readme.txt

如果不按照此结构存放插件文件,会发生以下情况:单击“更新”按钮后,旧版本插件将被删除,但新版本不会替换它,而是会在随机生成的文件夹中创建,结果会提示:“由于错误,插件已停用:插件文件不存在。”

2. 插件信息页 

通常,当单击“查看详细信息”时,WordPress 会从其自己的 wordpress.org 更新服务器向你显示相应的插件信息。这些信息可以在 WordPress 连接到 wordpress.org 服务器之前被钩住。 

这就是我所说的:

下面是获取插件更新信息,就是上面的info.json的代码,如果你发现后台响应变慢了,那么开发者应该对此请求进行缓存,不必每次都请求服务器。

复制
add_filter( 'plugins_api', 'misha_plugin_info', 20, 3);
/*
 * $res empty at this step
 * $action 'plugin_information'
 * $args stdClass Object ( [slug] => woocommerce [is_ssl] => [fields] => Array ( [banners] => 1 [reviews] => 1 [downloaded] => [active_installs] => 1 ) [per_page] => 24 [locale] => en_US )
 */
function misha_plugin_info( $res, $action, $args ){

	// do nothing if this is not about getting plugin information
	if( 'plugin_information' !== $action ) {
		return $res;
	}

	// do nothing if it is not our plugin
	if( plugin_basename( __DIR__ ) !== $args->slug ) {
		return $res;
	}

	// info.json is the file with the actual plugin information on your server
	$remote = wp_remote_get( 
		'https://rudrastyh.com/wp-content/uploads/updater/info.json', 
		array(
			'timeout' => 10,
			'headers' => array(
				'Accept' => 'application/json'
			) 
		)
	);

	// do nothing if we don't get the correct response from the server
	if( 
		is_wp_error( $remote )
		|| 200 !== wp_remote_retrieve_response_code( $remote )
		|| empty( wp_remote_retrieve_body( $remote ) )
	) {
		return $res;	
	}

	$remote = json_decode( wp_remote_retrieve_body( $remote ) );
	
	$res = new stdClass();
	$res->name = $remote->name;
	$res->slug = $remote->slug;
	$res->author = $remote->author;
	$res->author_profile = $remote->author_profile;
	$res->version = $remote->version;
	$res->tested = $remote->tested;
	$res->requires = $remote->requires;
	$res->requires_php = $remote->requires_php;
	$res->download_link = $remote->download_url;
	$res->trunk = $remote->download_url;
	$res->last_updated = $remote->last_updated;
	$res->sections = array(
		'description' => $remote->sections->description,
		'installation' => $remote->sections->installation,
		'changelog' => $remote->sections->changelog
		// you can add your custom sections (tabs) here
	);
	// in case you want the screenshots tab, use the following HTML format for its content:
	// <ol><li><a href="IMG_URL" target="_blank"><img src="IMG_URL" alt="CAPTION" /></a><p>CAPTION</p></li></ol>
	if( ! empty( $remote->sections->screenshots ) ) {
		$res->sections[ 'screenshots' ] = $remote->sections->screenshots;
	}

	$res->banners = array(
		'low' => $remote->banners->low,
		'high' => $remote->banners->high
	);
	
	return $res;

}

将更新信息推送到 WP Transients 

最后一步,同样获取info.json文件,并将更新信息推送给WP Transients,同样,如果你发现后台响应变慢了,那么开发者应该对此请求进行缓存,不必每次都请求服务器。

复制
add_filter( 'site_transient_update_plugins', 'misha_push_update' );
 
function misha_push_update( $transient ){
 
	if ( empty( $transient->checked ) ) {
		return $transient;
	}

	$remote = wp_remote_get( 
		'https://rudrastyh.com/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 $transient;	
	}
	
	$remote = json_decode( wp_remote_retrieve_body( $remote ) );
 
		// your installed plugin version should be on the line below! You can obtain it dynamically of course 
	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 = $remote->slug;
		$res->plugin = plugin_basename( __FILE__ ); // it could be just YOUR_PLUGIN_SLUG.php if your plugin doesn't have its own directory
		$res->new_version = $remote->version;
		$res->tested = $remote->tested;
		$res->package = $remote->download_url;
		$transient->response[ $res->plugin ] = $res;
		
		//$transient->checked[$res->plugin] = $remote->version;
	}
 
	return $transient;

}

如果要测试上面的代码,你的插件文件夹应该使用misha-update-checker命名,否则sulg对比不通过,将不会有反应。

感觉很棒!可以赞赏支持我哟~

0 打赏

评论 (1)

登录后评论
不错不错,到时候给我用上!
QQ咨询 邮件咨询 狗哥推荐