Вопрос

I try to build an plugin with an custom db table. So I include the notifications.php in the plugin index.php file. If I do a die; in the public function init() (in notifications.php), it dies so it's loaded, but the register_activation_hook not triggers on activate te plugin and the my_notifications_install fuction not execute. What's the problem? The activation not respond with an error.

The plugin structure:

/plugins/plugindir/index.php

// Notifications
include_once plugin_dir_path( __FILE__ ) . '/notifications.php';
$my_notifications = new my_notifications( __FILE__ );

/plugins/plugindir/notifications.php

class my_notifications {

    public function __construct( ) {
        $this->init();
    }

    public function init() {
        global $my_notifications_db_version;
        $my_notifications_db_version = '1.0';
        register_activation_hook( __FILE__, array( $this, 'my_notifications_install' ) );
    }

    private function my_notifications_install() {
        global $wpdb;
        global $my_notifications_db_version;

        $table_name = $wpdb->prefix . 'my_notifications';

        $charset_collate = $wpdb->get_charset_collate();

        $sql = "CREATE TABLE $table_name (
            id mediumint(9) NOT NULL AUTO_INCREMENT,
            time datetime DEFAULT '0000-00-00 00:00:00' NOT NULL,
            user_id mediumint(9) NOT NULL,
            post_id mediumint(9) NOT NULL,
            attachment_id mediumint(9) NOT NULL,
            message text NOT NULL,
            PRIMARY KEY  (id)
        ) $charset_collate;";

        require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
        dbDelta( $sql );

        add_option( 'my_notifications_db_version', $my_notifications_db_version );
    }

}

Это было полезно?

Решение

The rule of thumb is to never do anything which is not triggered by action or filter.

In this case you try register a hook before wordpress even finished to "boot". This may work sometimes, but totally not an healthy idea. Use at least the 'init' hook (and even better the 'wp_loaded' if you can), to trigger you initialization, and do not do anything before that unless you have a very good reason.

As for the activation hook, be very careful with trusting it being triggered as it will not be triggered on multisite install, and not when updates are done, so you might as well plan in advance and detect by yourself when DB initialization or updates are required.

Другие советы

register_activation_hook( __FILE__, array( $this, 'my_notifications_install' ) );

This should be in main plugin file. Because it use FILE to create name of hook. So change the reference or move this peace of code to main plugin file.

Check this link for more info about register_activation_hook codex, noone there use $this as reference to object, I saw &$this in some plugins for example wp-discuzz.

Also using db_delta with plugin activation hook is not good idea because when You need to update Your table schema after next release You need manually restart Your plugin because Wordpress doesn't trigger activation_hook while update since version 3.9 and dbdelta check of table exists and does nothing when table already exist if You use it more often than only on activation hook.

Лицензировано под: CC-BY-SA с атрибуция
Не связан с wordpress.stackexchange
scroll top