插件开发文档

防止 WordPress 更新您的外部插件

💡 云策文档标注

概述

本文档旨在指导开发者如何防止非 WordPress.org 托管的插件被 WordPress 自动更新,确保插件安全性和独立性。适用于外部托管插件,禁止用于 WordPress.org 目录中的插件。

关键要点

  • 仅适用于非 WordPress.org 托管的插件,目录插件禁止使用此方法,否则可能导致插件被关闭。
  • 最佳实践是使用独特的文件夹名称,如公司名-功能-plugin,以避免命名冲突和更新覆盖。
  • WordPress 5.8 及以上版本支持通过 Update URI 插件头来阻止更新,设置非 WordPress.org URI 或 false 值即可。
  • 旧版本 WordPress 可使用过滤更新请求的方法,通过 http_request_args 钩子移除插件更新检查。

代码示例

function example_hidden_plugin_12345( $r, $url ) {
    if ( 0 !== strpos( $url, 'https://api.wordpress.org/plugins/update-check' ) )
        return $r; // Not a plugin update request. Bail immediately.
  
    $plugins = unserialize( $r['body']['plugins'] );
    unset( $plugins->plugins[ plugin_basename( __FILE__ ) ] );
    unset( $plugins->active[ array_search( plugin_basename( __FILE__ ), $plugins->active ) ] );
    $r['body']['plugins'] = serialize( $plugins );
    return $r;
}
 
add_filter( 'http_request_args', 'example_hidden_plugin_12345', 5, 2 );

📄 原文内容
The information on this page is meant for use only on plugins not hosted on WordPress.org. Do not attempt to use this on your code hosted in the directory.

If you host your plugin on WordPress.org, we handle all updates for you. As such, the steps in this document are prohibited in all plugins submitted to the directory. Any plugin hosted here that is found to include this plugin will be closed and the developer required to remove it in order for their plugin to be restored.

We have chosen to document it here for the education of developers, as well as to ensure the global WordPress community can be safer.

Always Use Good Folder Names

Before we get into the code, we must stress the absolute best way to ensure your plugin won’t get overwritten by an update from WordPress.org is to use a good name. If you’re making a plugin for your company, give it a folder name like companyname-function-plugin — for example, if you work for FaceRange and you’re making a status plugin, you could name it facerange-status-plugin

Not only would we not accept it for using the prohibited term ‘plugin’, the plugin team would validate that the plugin owner legally represents FaceRange.

Update URI

As of WordPress 5.8, we have added in a feature to how the WordPress.org API checks for updates, and allowed it to be blocked by the use of a new header: Update URI.

Let’s say you have a plugin you made for your own site, and you gave it the folder name of my-plugin. That is a generic folder name, and has a high probability that someone else may use it. It’s also not a name we would allow you to block in our system, due to it’s generic nature.

The Update URI header can be added to the plugin headers. Look in your main plugin file for this section:

/**
 * Plugin Name: My Cool Plugin
 * Plugin URI: https://example.com/my-plugin/
 * Description: My Plugin does cool things.
 * Version: 1.0
 * Author: the team
 * Author URI: https://example.com/
 * Text Domain: my-plugin
 * License: GPLv2
 * License URI: https://opensource.org/licenses/gpl-2.0.php
 */

To apply it, add a new header for Update URI and put a non WordPress.org URI in the value:

 * Update URI: https://example.com/my-updater/

You can also set it to Update URI: false if you want. As long as it does not include wordpress.org/plugins or w.org/plugins it will be protected.

Filtering Updates

Another method, which is supported on older versions of WordPress, is to filter external API requests and discard any for your plugin.

This code, which was written by Mark Jaquith, can be added to your own plugin:

function example_hidden_plugin_12345( $r, $url ) {
    if ( 0 !== strpos( $url, 'https://api.wordpress.org/plugins/update-check' ) )
        return $r; // Not a plugin update request. Bail immediately.
  
    $plugins = unserialize( $r['body']['plugins'] );
    unset( $plugins->plugins[ plugin_basename( __FILE__ ) ] );
    unset( $plugins->active[ array_search( plugin_basename( __FILE__ ), $plugins->active ) ] );
    $r['body']['plugins'] = serialize( $plugins );
    return $r;
}
 
add_filter( 'http_request_args', 'example_hidden_plugin_12345', 5, 2 );

What that does is check if the update request is from the WordPress.org api, and if it matches the plugin folder and file name of this plugin. If it does, the plugin is removed from the list of plugins to check for updates.