12

I'm trying to develop my first Wordpress plugin and I got staled in the very first stage. I'm trying to setup some options and database tables when the plugin is activated, but no luck. No matter what I do, the plugin activates, but the database is untouched and the options are not stored in DB. I tried echoing inside the constructor, but it seems that it never reaches it. I have debug activated in WP, but no error is being reported. The function is not being hooked. Does someone can spot what's wrong with my code?

Thanks for any help in advance.

class Myplugin {

    private static $instance;

    public static function get_instance() {
        if ( ! self::$instance ) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    private function __construct() {
        register_activation_hook( __FILE__, array( &$this, 'plugin_activate' ) );
    }

    public function plugin_activate() {
        if ( version_compare( get_bloginfo( 'version' ), '3.8.2', ' < ' ) ) {
            deactivate_plugins( basename( __FILE__ ) );
        } else {
            $rlm_rsvplus_options = array(
                'db_version'          => '1.0',
                'event_name'          => '',
                'end_date'            => '',
            );

        update_option( 'rlm_myplugin_options', $rlm_myplugin_options );

        require_once( "includes/rlm_myplugin_db_setup.php" );//It never reaches this file.


    }
    }
}

$myplugin = Myplugin::get_instance();

3 Answers 3

23

Back to the WordPress documentation.

<?php register_activation_hook( $file, $function ); ?>

Parameters

$file

(string) (required) Path to the main plugin file inside the wp-content/plugins directory. A full path will work. Default: None

$function

(callback) (required) The function to be run when the plugin is activated. Any of PHP's callback pseudo-types will work. Default: None

Possible issue

If calling a function from a file that is outside of main plugin file, then the hook will not work as it is not pointing to the right file. FILE will point to the file where the code is written. So if you happen to include this part of code from elsewhere (another file - not the main plugin file) it's not supposed to work unless you point the right path.

Solution

A solution could be declaring a constant in the main plugin file.

your_main_plugin_file.php

define("PLUGIN_FILE_URL", __FILE__);

and then use it in your included file like so.

includes/some_file.php

<?php register_activation_hook( PLUGIN_FILE_URL, ['your_class_name_here', 'your_class_method_name_here']); ?>

or if you use functions instead of classes then do

<?php register_activation_hook( PLUGIN_FILE_URL, 'your_function_name_here'); ?>
Sign up to request clarification or add additional context in comments.

2 Comments

awesome answer @DevWL it was my issue
+1 for PLUGIN_FILE_URL constant. However, it should be enclosed in single quotes. Also, the constant name must be YOUR_PLUGIN_NAME_PLUGIN_FILE_URL to avoid conflicts with other plugins.
9

The register_activation_hook call needs to be outside of the class itself.

Something like:

class Myplugin {

    private static $instance;

    public static function get_instance() {
        if ( ! self::$instance ) {
            self::$instance = new self();
        }
        return self::$instance;
    }

    private function __construct() {
        // do other stuff here
    }

    public function plugin_activate() {
        if ( version_compare( get_bloginfo( 'version' ), '3.8.2', ' < ' ) ) {
            deactivate_plugins( basename( __FILE__ ) );
        } else {
            $rlm_rsvplus_options = array(
                'db_version'          => '1.0',
                'event_name'          => '',
                'end_date'            => '',
            );

        update_option( 'rlm_myplugin_options', $rlm_myplugin_options );

        require_once( "includes/rlm_myplugin_db_setup.php" );
    }
}

register_activation_hook( __FILE__, array( 'Myplugin', 'plugin_activate' ) );

You can read more on the following tutorial by Francis Yaconiello about How to write WordPress plugin.

4 Comments

alternatively, you could leave the hook registration inside the constructor and instantiate your class outside of the class's code
I instantiate my class outside. I've updated the question to reflect this fact. It's really weird, the execution gets into the constructor, but it just ignores the hook part.
Much Thanks, the linked resource saved me another 12 hours debugging this shit of WordPress.
Important note: the function in the class needs to be public. private or protected functions can not be triggered with an action or filter.
0

In order to work register_activation_hook OR register_deactivation_hook the functions should be in index file OR we need to specify the full path to the file argument.

Replace this:

register_activation_hook( FILE, array( &$this, 'plugin_activate' ) );

With:

register_activation_hook( FILE . 'plugin-main-file.php', array( &$this, 'plugin_activate' ) );

Here the point is register_activation_hook( $file, $function );

Here $file means Path to the main plugin file

Reference: https://codex.wordpress.org/Function_Reference/register_activation_hook

Thanks, - Adi

2 Comments

do you mean FILE? You are using FILE and $file in your examples/explanation.
I mean to say $file variable while calling hook register_activation_hook( $file, $function )

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.