register_activation_hook( string $file, callable $callback )

Set the activation hook for a plugin.

Description

When a plugin is activated, the action ‘activate_PLUGINNAME’ hook is called. In the name of this hook, PLUGINNAME is replaced with the name of the plugin, including the optional subdirectory. For example, when the plugin is located in wp-content/plugins/sampleplugin/sample.php, then the name of this hook will become ‘activate_sampleplugin/sample.php’.

When the plugin consists of only one file and is (as by default) located at wp-content/plugins/sample.php the name of this hook will be ‘activate_sample.php’.

Parameters

$filestringrequired
The filename of the plugin including the path.
$callbackcallablerequired
The function hooked to the 'activate_PLUGIN' action.

More Information

Related discussion with another sample of working code: https://wordpress.org/support/topic/312342

Registering the hook inside the ‘plugins_loaded’ hook will not work. You can’t call register_activation_hook() inside a function hooked to the 'plugins_loaded' or 'init' hooks (or any other hook). These hooks are called before the plugin is loaded or activated.

When a plugin is activated, all active plugins are loaded, then the plugin is activated. The plugin’s activation hook is run and then the page is immediately redirected

Process Flow

If you are interested in doing something just after a plugin has been activated it is important to note that the hook process performs an instant redirect after it fires. So it is impossible to use add_action() or add_filter() type calls until the redirect has occurred (e.g., only two hooks are fired after the plugin’s activation hook: 'activated_plugin' and 'shutdown'). A quick workaround to this quirk is to use add_option() like so:

/* 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' );

You can check out the full post @ http://stackoverflow.com/questions/7738953/is-there-a-way-to-determine-if-a-wordpress-plugin-is-just-installed/13927297#13927297.

However, it is possible to use do_action(), like this:

function my_plugin_activate() {

     do_action( 'my_plugin_activate' );
}
register_activation_hook( __FILE__, 'my_plugin_activate' );

Included plugin files and even other plugins will be able to hook into this action.

A Note on Variable Scope

If you’re using global variables, you may find that the function you pass to register_activation_hook() does not have access to global variables at the point when it is called, even though you state their global scope within the function like this:

$myvar = 'whatever';

function myplugin_activate() {

  global $myvar;
  echo $myvar; // this will NOT be 'whatever'!
}

register_activation_hook( __FILE__, 'myplugin_activate' );

This is because on that very first include, your plugin is NOT included within the global scope. It’s included in the activate_plugin() function, and so its “main body” is not automatically in the global scope.

This is why you should always be explicit. If you want a variable to be global, then you need to declare it as such, and that means anywhere and everywhere you use it. If you use it in the main body of the plugin, then you need to declare it global there too.

When activation occurs, your plugin is included from another function and then your myplugin_activate() is called from within that function (specifically, within the activate_plugin() function) at the point where your plugin is activated. The main body variables are therefore in the scope of the activate_plugin() function and are not global, unless you explicitly declare their global scope:

global $myvar;
$myvar = 'whatever';

function myplugin_activate() {

   global $myvar;
   echo $myvar; // this will be 'whatever'
}
register_activation_hook( __FILE__, 'myplugin_activate' );

More information on this is available here: https://wordpress.org/support/topic/201309

Discussions – External Resources

Source

function register_activation_hook( $file, $callback ) {
	$file = plugin_basename( $file );
	add_action( 'activate_' . $file, $callback );
}

Changelog

VersionDescription
2.0.0Introduced.

User Contributed Notes

  1. Skip to note 14 content

    Note that register_activation_hook must not be registered from within another hook for example ‘plugins_loaded’ or ‘init’ as these will have all been called before the plugin is loaded or activated.

    This will NOT work:

    function pluginInit() {
        require_once dirname(__FILE__) . '/includes/Activator.php';
        register_activation_hook( __FILE__, 'Activator', 'activate' ) );
    }
    add_action( 'plugins_loaded', 'pluginInit' );
  2. Skip to note 15 content

    Singleton class pattern

    If your plugin uses the singleton class pattern, add the activation hook like so:

    class MyPlugin {
         static function install() {
                // do not generate any output here
         }
    }
    register_activation_hook( __FILE__, array( 'MyPlugin', 'install' ) );

    If the class that holds your activation function/method is in some additional file, register your activation function like this:

    include_once dirname( __FILE__ ) . '/your_additional_file.php';
    register_activation_hook( __FILE__, array( 'YourAdditionalClass', 'on_activate_function' ) );

    Or, because the activation hook requires a static function, if you’re inside of a __construct():

    register_activation_hook( __FILE__, array( 'MyPlugin', 'YOUR_METHOD_NAME' ) );
  3. Skip to note 16 content

    There’s a comment here that could make this confusing by giving incorrect information. The code does NOT have to be in the main file, unless you’re doing something like a single file plugin. The thing to know is that the first argument is the name required to get your code to fire, not what file the code is in. Example:

    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() { ... }
    }

  4. Skip to note 18 content

    According to @nacin (a lead developer for WordPress), you shouldn’t use activation hooks (especially on multisite). You should do this instead:

    “It’s far better to use an upgrade routine fired on admin_init, and handle that per-site, basing it on a stored option.”

    Source: https://core.trac.wordpress.org/ticket/14170#comment:68

  5. Skip to note 19 content

    The hooked function has one boolean argument, $network_wide which indicates if the plugin is network activated.

    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
    }
  6. Skip to note 20 content


    Sending arguments with callable function

    Imagine that you have OOP structure for your plugin and need to observe SOLID principle inside it.
    For this reason, you need to Dependency Injection with callable function inside your register_activation_hook function.
    Sample code is like in the following:

      Note: I used both way to show calling callable function with argument and without it in activation and deactivation hooks to bold using each of them. Usage of callable function with argument is in 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();
  7. Skip to note 22 content

    Really useful when, for example, when we need to create a DB table for our plugin functionalities:

    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);
    }

  8. Skip to note 25 content

    Please note that register_activation_hook() must be called from the main plugin file – the one that has “Plugin Name: …” directive.
    This code added in the main plugin file will work:

    require_once ( dirname( __FILE__ ) . '/includes/class-my-class.php' );
    
    register_activation_hook( __FILE__, array ( $my_class, 'function_to_call') );

    However, if you try to add register_activation_hook() in the constructor of the class it won’t work because it’s not in the main plugin file.

  9. Skip to note 26 content

    If you have a function called myplugin_activate() in the main plugin file at either

    wp-content/plugins/myplugin.php or
    wp-content/plugins/myplugin/myplugin.php

    use this code:

    register_activation_hook( __FILE__, 'myplugin_deactivate' );

    This will call the myplugin_activate() function on activation of the plugin.

You must log in before being able to contribute a note or feedback.