activate_plugin()
概述
activate_plugin() 函数用于在“沙盒”环境中尝试激活插件,并在成功时重定向。它通过设置错误重定向、捕获输出错误来确保安全激活,避免重复激活已激活的插件。
关键要点
- 函数在沙盒中激活插件,通过重定向机制处理错误,防止激活钩子在不成功时被调用。
- 参数包括插件路径、重定向URL、网络范围激活选项和静默模式控制。
- 返回 null 表示成功,WP_Error 表示文件无效或激活失败。
- 激活失败可能由插件头信息无效、插件缓存问题或权限错误引起。
- 支持多站点环境,可处理网络范围激活。
代码示例
$result = activate_plugin( 'plugin-dir/plugin-file.php' );
if ( is_wp_error( $result ) ) {
// 处理错误
}注意事项
- 该函数不会阻止插件文件内部的错误,仅通过重定向机制管理激活流程。
- 不应在其他地方复制此沙盒逻辑,因为它依赖于特定的重定向实现。
- 在批量激活插件时,重定向可能不适用,需通过钩子如 activated_plugin 进行条件处理。
Attempts activation of plugin in a “sandbox” and redirects on success.
Description
A plugin that is already activated will not attempt to be activated again.
The way it works is by setting the redirection to the error before trying to include the plugin file. If the plugin fails, then the redirection will not be overwritten with the success message. Also, the options will not be updated and the activation hook will not be called on plugin error.
It should be noted that in no way the below code will actually prevent errors within the file. The code should not be used elsewhere to replicate the “sandbox”, which uses redirection to work.
{@source 13 1}
If any errors are found or text is outputted, then it will be captured to ensure that the success redirection will update the error redirection.
Parameters
$pluginstringrequired-
Path to the plugin file relative to the plugins directory.
$redirectstringoptional-
URL to redirect to.
$network_widebooloptional-
Whether to enable the plugin for all sites in the network or just the current site. Multisite only.
Default:
false $silentbooloptional-
Whether to prevent calling activation hooks.
Default:
false
Source
function activate_plugin( $plugin, $redirect = '', $network_wide = false, $silent = false ) {
$plugin = plugin_basename( trim( $plugin ) );
if ( is_multisite() && ( $network_wide || is_network_only_plugin( $plugin ) ) ) {
$network_wide = true;
$current = get_site_option( 'active_sitewide_plugins', array() );
$_GET['networkwide'] = 1; // Back compat for plugins looking for this value.
} else {
$current = get_option( 'active_plugins', array() );
}
$valid = validate_plugin( $plugin );
if ( is_wp_error( $valid ) ) {
return $valid;
}
$requirements = validate_plugin_requirements( $plugin );
if ( is_wp_error( $requirements ) ) {
return $requirements;
}
if ( $network_wide && ! isset( $current[ $plugin ] )
|| ! $network_wide && ! in_array( $plugin, $current, true )
) {
if ( ! empty( $redirect ) ) {
// We'll override this later if the plugin can be included without fatal error.
wp_redirect( add_query_arg( '_error_nonce', wp_create_nonce( 'plugin-activation-error_' . $plugin ), $redirect ) );
}
ob_start();
// Load the plugin to test whether it throws any errors.
plugin_sandbox_scrape( $plugin );
if ( ! $silent ) {
/**
* Fires before a plugin is activated.
*
* If a plugin is silently activated (such as during an update),
* this hook does not fire.
*
* @since 2.9.0
*
* @param string $plugin Path to the plugin file relative to the plugins directory.
* @param bool $network_wide Whether to enable the plugin for all sites in the network
* or just the current site. Multisite only. Default false.
*/
do_action( 'activate_plugin', $plugin, $network_wide );
/**
* Fires as a specific plugin is being activated.
*
* This hook is the "activation" hook used internally by register_activation_hook().
* The dynamic portion of the hook name, `$plugin`, refers to the plugin basename.
*
* If a plugin is silently activated (such as during an update), this hook does not fire.
*
* @since 2.0.0
*
* @param bool $network_wide Whether to enable the plugin for all sites in the network
* or just the current site. Multisite only. Default false.
*/
do_action( "activate_{$plugin}", $network_wide );
}
if ( $network_wide ) {
$current = get_site_option( 'active_sitewide_plugins', array() );
$current[ $plugin ] = time();
update_site_option( 'active_sitewide_plugins', $current );
} else {
$current = get_option( 'active_plugins', array() );
$current[] = $plugin;
sort( $current );
update_option( 'active_plugins', $current );
}
if ( ! $silent ) {
/**
* Fires after a plugin has been activated.
*
* If a plugin is silently activated (such as during an update),
* this hook does not fire.
*
* @since 2.9.0
*
* @param string $plugin Path to the plugin file relative to the plugins directory.
* @param bool $network_wide Whether to enable the plugin for all sites in the network
* or just the current site. Multisite only. Default false.
*/
do_action( 'activated_plugin', $plugin, $network_wide );
}
if ( ob_get_length() > 0 ) {
$output = ob_get_clean();
return new WP_Error( 'unexpected_output', __( 'The plugin generated unexpected output.' ), $output );
}
ob_end_clean();
}
return null;
}
Hooks
- do_action( ‘activated_plugin’, string $plugin, bool $network_wide )
-
Fires after a plugin has been activated.
- do_action( “activate_{$plugin}”, bool $network_wide )
-
Fires as a specific plugin is being activated.
Skip to note 3 content
Codex
Basic Example
Attempts to activate the plugin, and returns WP_Error on failure
$result = activate_plugin( 'plugin-dir/plugin-file.php' ); if ( is_wp_error( $result ) ) { // Process Error }Skip to note 4 content
ttodua
People, if you want to use redirection (upon plugin activation) you should only do that if your plugin is not “activated” through “BULK ACTIVATION”!
add_action( 'activated_plugin', 'wpdocs_my_redirection' ); function wpdocs_my_redirection( $plugin ) { $table = new WP_Plugins_List_Table; if ( plugin_basename( __FILE__ ) === $plugin && 'activated-selected' !== $table->current_action() ) { wp_redirect( ... ); exit(); } }