功能
尝试在“沙箱”中激活插件,并在激活成功后进行重定向。
格式
activate_plugin( string $plugin, string $redirect = '', bool $network_wide = false, bool $silent = false )
描述
当一个函数已经被激活时,该函数不会再次尝试激活该插件。
该函数的工作原理是,在引入插件文件之前就将重定向的结果设置为错误,如果插件启动失败,这个错误的结果就不会被启动成功的信号覆盖。同时,如果插件启动失败,插件的设置不会被更新,也不会调用插件激活钩子。
需要注意的是,该函数不会阻止插件文件产生的错误报告,该函数也不能在任何地方用于复制“沙箱”环境,因为该函数只通过重定向来工作。
该函数会捕捉插件产生的所有错误报告或其他输出信息,以确保在重定向成功执行时更新默认的为“错误”的重定向状态。
参数
$plugin (string) (必须参数) 插件文件所在位置的相对路径。 $redirect (string) (可选参数) 重定向所指向的 URL. 默认值:'' $network_wide (bool) (可选参数) 是否对网络中的所有站点启用插件,或只对当前站点启用插件。该参数只适用于多站点模式下。 默认值:false $silent (bool) (可选参数) 是否阻止唤起激活钩子。 默认值:false
返回值
(null|WP_Error) 若执行成功则返回 `Null`, 若执行的插件文件无效则返回 `WP_Error`.
更多信息
出现下面这段通用响应代码就意味着插件没有被激活,原因可能有多种,例如:文件包含出问题、解析头部信息时出问题、插件缓存出问题(关于 WordPress 对象缓存可参考:https://developer.wordpress.org/reference/classes/wp_object_cache/)或权限错误等。
The plugin does not have a valid header.
插件缓存出问题通常是由插件被完全初始化之后又对插件源文件进行了添加或修改操作导致的,可通过重新加载页面或者将 activate_plugin() 作为一个单独的 AJAX 请求发送这样的方式来解决。在有必要的情况下,也可以通过手动更新缓存来解决此类问题,示例如下:
$cache_plugins = wp_cache_get( 'plugins', 'plugins' );
if ( !empty( $cache_plugins ) ) {
$new_plugin = array(
'Name' => $plugin_name,
'PluginURI' => $plugin_uri,
'Version' => $plugin_version,
'Description' => $plugin_description,
'Author' => $author_name,
'AuthorURI' => $author_uri,
'TextDomain' => '',
'DomainPath' => '',
'Network' => '',
'Title' => $plugin_name,
'AuthorName' => $author_name,
);
$cache_plugins[''][$plugin_path] = $new_plugin;
wp_cache_set( 'plugins', $cache_plugins, 'plugins' );
}
源码
代码所在文件:
wp-admin/includes/plugin.php
相关代码片段:
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;
}
变更日志
- 自 WordPress 2.5.0 开始引入。
- 在 WordPress 5.2.0 中测试了与 WordPress 和 PHP 的兼容性。
参考链接:https://developer.wordpress.org/reference/functions/activate_plugin/