__NAMESPACE__ with register_activation_hook

Im teaching myself namespaces and OOP in wordpress at the moment so bare with me.

In the base of my plugin I’m loading activation and deactivation hooks. Currently the deactivation hook works but the activation hook doesn’t, it just fails silently (WP_DEBUG is on).

The base file declares a namespace and a constant, and then requires the class files for activation and deactivation and then registers the hooks. Activation and deactivation are functionally identical with each requiring and instantiating a error logging class, and sending a message to a method.

I’ve poured over the documentation for both register_deactivation_hook and for register_activation_hook (especially the contributor notes) and I’ve not been able to resolve this, so any thoughts on why one works and the other does not will be greatly appreciated.

The file structure is as follows:

/plugin/
    plugin.php   
/plugin/includes/
         ActivatorClass.php
         DeactivatorClass.php
         ErrorLogClass.php

/plugin/plugin.php

<?php
namespace company\pluginName;

/**
 * Plugin Name:       Plugin Name
 * Plugin URI:        http://url
 * Description:       A demo plugin 
 * Version:           0.0.1
 * Author:            me
 */


function pluginInit() {

    // Machine file path
    define( 'PLUGIN_PATH', realpath( plugin_dir_path( __FILE__ ) ) . DIRECTORY_SEPARATOR );

    /**
    * Runs during plugin activation.
    * Documented in includes/ActivatorClass.php
    */
    require_once PLUGIN_PATH . 'includes/ActivatorClass.php';
    register_activation_hook( __FILE__, array( __NAMESPACE__ . '\\ActivatorClass', 'activate' ) );

    /**
    * Runs during plugin deactivation.
    * Documented in includes/DeactivatorClass.php
    */
    require_once PLUGIN_PATH  . 'includes/DeactivatorClass.php';
    register_deactivation_hook( __FILE__, array( __NAMESPACE__ . '\\DeactivatorClass', 'deactivate' ) );
}

add_action( 'plugins_loaded', __NAMESPACE__ . '\\pluginInit' );

plugin/includes/ActivatorClass.php

 <?php
 namespace company\pluginName;

 /**
  * Fired during plugin activation
  *
  * This class defines all code necessary to run during the plugin's activation.
  *
  * @since      0.0.1
  * @package    plugin\pluginName\
  * @author     me
  */
  class ActivatorClass {

      /**
       * Fired during plugin activation
       *
       * @since    0.0.1
       */
      public static function activate() {
          require ( PLUGIN_PATH. '/includes/ErrorLogClass.php');
          $activate = new ErrorLog();
          $activate->log('Plugin Activated');
      }
  }

/plugin/includes/ErrorLogClass.php

<?php
namespace company\pluginName;

/**
* Class ErrorLog
*
* @since      0.0.1
* @package    plugin\pluginName\
* @author     me
*/

 class ErrorLog {

    /**
     * The error(s) to be logged
     * @var array | string
     */
    protected $log;

    /**
     * The logging method
     *
     * @param $log
     */
    public static function log( $log ) {
        if ( true === WP_DEBUG ) {
            if ( is_array( $log ) || is_object( $log ) ) {
                error_log( print_r( $log, true ) );
            } else {
                error_log( $log );
            }
        }
    }
 }

1
1

The reason that the plugin activation hook wasn’t working in the code provided in the question is that on plugin activation the plugins_loaded hook is never run. Since the register_activation_hook hook was hooked from plugins_loaded it was never run on activation. And since it’s never fired ever again, this way of hooking results in register_activation_hook never firing.

The solution is to register the activation hook from the main plugin file and not attached to any hooks. In fact, this is the only way that you can run the activation hook. After a plugin is activated there are only two other hooks run: that particular plugin activation hook and shutdown. It’s possible to add hooks to shutdown and they will fire on plugin activation, but it fires after the plugin activation hook.

/**
 * Plugin Name: WordPress Namespace OOP Plugin Example
 */
declare( strict_types = 1 );
namespace StackExchange\WordPress;

//* Start bootstraping the plugin
require( __DIR__ . '/includes/plugin.php' );
$WordPressStackExchangePlugin = new plugin();
\add_action( 'plugins_loaded', [ $WordPressStackExchangePlugin, 'plugins_loaded' ] );

//* Register activation hook
\register_activation_hook( __FILE__, [ __NAMESPACE__ . '\\ActivatorClass', 'activate' ] );

The activation hook would then call the static method activate from the StackExchange\WordPress\ActivatorClass class.

Notes:

  1. Strict typing requires PHP > 7.0.
  2. Array shorthand requires PHP > 5.4
  3. Namespacing and __DIR__ require PHP > 5.3

Leave a Comment