描述
当插件被激活(启用)时,将调用动作‘activate_PLUGINNAME’钩子。在这个挂钩的名称中,PLUGINNAME被替换为插件的名称,包括可选的子目录。例如,当插件位于wp-content/plugins/sampleplugin/sample.php,则此钩子的名称将变为“activate_sampleplugin/sample.php”。
当插件仅由一个文件组成并且(默认情况下)位于wp-content/plugins/sample.php时,此挂钩的名称将为“activate_sample.php”。
参数
- $file
-
(string)(必填) 插件的文件名,包括路径。
- $callback
-
(callable)(必填) 连接到'activate_PLUGIN'动作的函数。
更多信息
与另一个工作代码示例相关的讨论:https://wordpress.org/support/topic/312342
在‘plugins_loaded’钩子内注册钩子将不起作用。不能在连接到‘plugins_loaded’或‘init’钩子(或任何其他挂钩)的函数内部调用register_activation_hook()。这些钩子在插件加载或激活之前被调用。
当一个插件被激活时,所有启用的插件都被加载,然后该插件被激活。该插件的激活钩子被运行,然后页面立即被重定向。
进程流程
如果您有兴趣在插件激活后立即执行某项操作,请务必注意,钩子进程在启动后会立即执行重定向。因此,在重定向发生之前,不可能使用add_action()或add_filter()类型调用(例如,在插件的激活挂钩之后,仅触发两个挂钩:‘activated_plugin’和‘shutdown’)。这种特殊的快速解决方法是使用add_option(),如下所示:
/* Main Plugin File */ ... function my_plugin_activate() { add_option( 'Activated_Plugin', 'Plugin-Slug' ); /* activation code here */ } register_activation_hook( __FILE__, 'my_plugin_activate' ); function load_plugin() { if ( is_admin() && get_option( 'Activated_Plugin' ) == 'Plugin-Slug' ) { delete_option( 'Activated_Plugin' ); /* do stuff once right after activation */ // example: add_action( 'init', 'my_init_function' ); } } add_action( 'admin_init', 'load_plugin' );
您可以查看完整的文章 @http://stackoverflow.com/questions/7738953/is-there-a-way-to-determine-if-a-wordpress-plugin-is-just-installed/13927297#13927297
但是,可以像这样使用do_action():
function my_plugin_activate() { do_action( 'my_plugin_activate' ); } register_activation_hook( __FILE__, 'my_plugin_activate' );
所包含的插件文件甚至其他插件都可以连接到该动作中。
关于变量范围的一些提示
如果使用全局变量,您可能会发现传递给register_activation_hook()的函数在调用时无法访问全局变量,即使您在函数中声明了全局变量的全局范围,如下所示:
$myvar = 'whatever'; function myplugin_activate() { global $myvar; echo $myvar; // this will NOT be 'whatever'! } register_activation_hook( __FILE__, 'myplugin_activate' );
这是因为在第一个包含中,您的插件不包含在全局范围内。它包含在activate_plugin()函数中,因此它的“主体”不会自动在全局范围内。
这就是为什么你应该始终声明。如果你想让一个变量是全局的,那么你需要声明它,这意味着你可以在任何地方使用它。如果你在插件的主体中使用它,那么你也需要在那里声明它是全局的。
当激活发生时,您的插件将从另一个函数中包含,然后从该函数中(具体地说,在activate_plugin()函数中)在您的插件被激活的点调用您的myplugin_activate()。因此,主体变量在activate_plugin()函数的范围内,并且不是全局变量,除非您显式声明其全局范围:
global $myvar; $myvar = 'whatever'; function myplugin_activate() { global $myvar; echo $myvar; // this will be 'whatever' } register_activation_hook( __FILE__, 'myplugin_activate' );
有关这方面的更多信息,请访问:https://wordpress.org/support/topic/201309
讨论-外部资源
- “kaiser”的基本激活/停用/卸载类的一个好例子可以在WPSE上找到:http://wordpress.stackexchange.com/questions/25910/uninstall-a-plugin-method-typical-features-how-to/25979#25979
源码
更新日志
版本 | 描述 |
---|---|
2.0.0 | 开始引入 |
使用示例
请注意,register_activation_hook不能从另一个钩子(例如‘plugins_loaded’或‘init’)中注册,因为这些钩子都是在加载或激活插件之前调用的。
这将不起作用:
function pluginInit() { require_once dirname(__FILE__) . '/includes/Activator.php'; register_activation_hook( __FILE__, 'Activator', 'activate' ) ); } add_action( 'plugins_loaded', 'pluginInit' );
单例类模式
如果您的插件使用单例类模式,请添加如下激活挂钩:
class MyPlugin { static function install() { // do not generate any output here } } register_activation_hook( __FILE__, array( 'MyPlugin', 'install' ) );
如果保存激活函数/方法的类位于其他文件中,请按如下方式注册激活函数:
include_once dirname( __FILE__ ) . '/your_additional_file.php'; register_activation_hook( __FILE__, array( 'YourAdditionalClass', 'on_activate_function' ) );
或者,因为激活挂钩需要静态函数,如果您在__construct()中:
register_activation_hook( __FILE__, array( 'MyPlugin', 'YOUR_METHOD_NAME' ) );
这里有一条评论可能会因为提供了错误的信息而让人困惑。代码不必在主文件中,除非您正在执行类似于单个文件插件的操作。需要知道的是,第一个参数是启动代码所需的名称,而不是代码所在的文件。例如:
Main plugin file: plugin/myplugin/myplugin.php
include 'some_class.php';
$obj = new other_class();Other plugin file: plugin/myplugin/some_class.php
class some_class {
__constructor() {
register_activation_hook(__DIR__.'/myplugin.php',array($this,'activate');
}
public function activate() { ... }
}
如果在命名空间内调用此函数:
register_activation_hook( __FILE__, __NAMESPACE__ . '\my_activate_callback' );
根据@nacin(WordPress的首席开发人员),您不应该使用激活挂钩(尤其是在多站点上)。您应该这样做:
“最好使用在admin_init上启动的升级程序,并根据存储选项按站点处理。”
资料来源:https://core.trac.wordpress.org/ticket/14170#comment:68
如果插件中有自定义重写规则,则可以刷新固定链接
register_activation_hook( __FILE__, 'wpdocs_myplugin_activate' ); function wpdocs_myplugin_activate() { flush_rewrite_rules(); }
钩子函数有一个布尔参数
$network_wide
,用于指示插件是否已被网络激活。register_activation_hook(__FILE__, 'my_plugin_activate'); function my_plugin_activate($network_wide){ if($network_wide){ //Plugin is network activated $site_ids = get_sites(array('fields' => 'ids')); foreach($site_ids as $site_id){ //Perform something on all sites within the network switch_to_blog($site_id); my_plugin_install_site(); restore_current_blog(); } return; } my_plugin_install_site(); } function my_plugin_install_site(){ //Do something }
使用可调用函数发送参数
假设您的插件具有OOP结构,并且需要在其中遵守SOLID原则。
因此,您需要在register_activation_hook函数中使用可调用函数进行依赖项注入。
示例代码如下所示:注意:我使用了两种方式来显示在激活和停用钩子中带参数和不带参数的可调用函数,以便大胆地使用它们。在register_activation_hook中使用的是带参数的可调用函数。
<?php /** * OOP WordPress Plugin Boilerplate * * Description for OOP Plugin * * @link https://github.com/msn60/oop-wordpress-plugin-boilerplate * @since 1.0.0 * @package Plugin_Name_Name_Space * * @wordpress-plugin * Plugin Name: OOP WordPress Plugin Boilerplate * Plugin URI: https://github.com/msn60/oop-wordpress-pluging-boilerplate-light-version * Description: Description for OOP Plugin * Version: 1.0.2 * Author: Mehdi Soltani <soltani.n.mehdi@gmail.com> * Author URI: https://wpwebmaster.ir * License: GPL-2.0+ * License URI: http://www.gnu.org/licenses/gpl-2.0.txt */ /* * Define your namespaces here by use keyword * */ use Plugin_Name_Name_Space\Includes\Init\{ Constant, Activator }; use Plugin_Name_Name_Space\Includes\Config\Initial_Value; use Plugin_Name_Name_Space\Includes\Uninstall\{ Deactivator, Uninstall }; /** * If this file is called directly, then abort execution. */ if ( ! defined( 'ABSPATH' ) ) { exit; } /** * Class Plugin_Name_Plugin * * This class is primary file of plugin which is used from * singletone design pattern. * * @package Plugin_Name_Name_Space * @author Your_Name <youremail@nomail.com> * @see Plugin_Name_Name_Space\Includes\Init\Core Class * @see Plugin_Name_Name_Space\Includes\Init\Constant Class * @see Plugin_Name_Name_Space\Includes\Init\Activator Class * @see Plugin_Name_Name_Space\Includes\Uninstall\Deactivator Class * @see Plugin_Name_Name_Space\Includes\Uninstall\Uninstall Class */ final class Plugin_Name_Plugin { /** * Instance property of Plugin_Name_Plugin Class. * This is a property in your plugin primary class. You will use to create * one object from Plugin_Name_Plugin class in whole of program execution. * * @access private * @var Plugin_Name_Plugin $instance create only one instance from plugin primary class * @static */ private static $instance; /** * @var Initial_Value $initial_values An object to keep all of initial values for theme */ protected $initial_values; /** * Plugin_Name_Plugin constructor. * It defines related constant, include autoloader class, register activation hook, * deactivation hook and uninstall hook and call Core class to run dependencies for plugin * * @access private */ public function __construct() { /*Define Autoloader class for plugin*/ $autoloader_path = 'includes/class-autoloader.php'; /** * Include autoloader class to load all of classes inside this plugin */ require_once trailingslashit( plugin_dir_path( __FILE__ ) ) . $autoloader_path; /*Define required constant for plugin*/ Constant::define_constant(); /** * Register activation hook. * Register activation hook for this plugin by invoking activate * in Plugin_Name_Plugin class. * * @param string $file path to the plugin file. * @param callback $function The function to be run when the plugin is activated. */ register_activation_hook( __FILE__, function () { $this->activate( new Activator( intval( get_option( 'last_your_plugin_name_dbs_version' ) ) ) ); } ); /** * Register deactivation hook. * Register deactivation hook for this plugin by invoking deactivate * in Plugin_Name_Plugin class. * * @param string $file path to the plugin file. * @param callback $function The function to be run when the plugin is deactivated. */ register_deactivation_hook( __FILE__, array( $this, 'deactivate' ) ); } /** * Call activate method. * This function calls activate method from Activator class. * You can use from this method to run every thing you need when plugin is activated. * * @access public * @since 1.0.0 * @see Plugin_Name_Name_Space\Includes\Init\Activator Class */ public function activate( Activator $activator_object ) { global $wpdb; $activator_object->activate( true, new Table( $wpdb, PLUGIN_NAME_DB_VERSION, get_option( 'has_table_name' ) ) ); } /** * Create an instance from Plugin_Name_Plugin class. * * @access public * @since 1.0.0 * @return Plugin_Name_Plugin */ public static function instance() { if ( is_null( ( self::$instance ) ) ) { self::$instance = new self(); } return self::$instance; } /** * Load Core plugin class. * * @access public * @since 1.0.0 */ public function run_plugin_name_plugin() { // TODO: Do you codes here to run the plugin } /** * Call deactivate method. * This function calls deactivate method from Dectivator class. * You can use from this method to run every thing you need when plugin is deactivated. * * @access public * @since 1.0.0 */ public function deactivate() { Deactivator::deactivate(); } } $plugin_name_plugin_object = Plugin_Name_Plugin::instance(); $plugin_name_plugin_object->run_plugin_name_plugin();
有用的实例,例如,当我们需要为我们的插件功能创建一个DB表:
function create_ourtable(){ global $wpdb; $prefix = $wpdb->prefix; $form_db = $prefix . "ourtable"; //Check if table exists. In case it's false we create it if($wpdb->get_var("SHOW TABLES LIKE '$form_db'") !== $form_db){ $sql = "CREATE TABLE $form_db(id mediumint unsigned not null primary key auto_increment, dates timestamp, names varchar(500), wp_user mediumint unsigned)"; require_once(ABSPATH . 'wp-admin/includes/upgrade.php'); dbDelta($sql); }