Make WordPress Core

Opened 8 years ago

Last modified 5 years ago

#37678 new defect (bug)

Add an action hook for plugins to do database upgrades on

Reported by: johnjamesjacoby's profile johnjamesjacoby Owned by:
Milestone: Awaiting Review Priority: normal
Severity: normal Version:
Component: Database Keywords: 2nd-opinion
Focuses: Cc:

Description

Currently, plugins that have custom database tables usually hook into admin_init and pray for rain when comes to their database alterations. This pollutes the admin_init hook namespace quite a bit, particularly with database actions that are almost always necessary in order for plugins to actually work correctly.

It would be nice if WordPress core had a dedicated action hook meant for executing database alterations & upgrades, no different than there being one for plugins_loaded, template_redirect, et all...

I'm conflicted on where exactly this hook should be. I'm 95% sure it belongs somewhere after admin_init so that admin area plugins have a chance to hook everything in. I'm also 95% certain I don't want this as part of the plugin activation sequence, because it's becoming more common to deploy plugins via WP CLI, version control, or some other deployment process, and activation hooks aren't usually ran that way.

Change History (1)

#1 @flixos90
8 years ago

Alternatively we could handle storing the database version of the plugins, and the plugins could register their update function.

function update_database() {
    global $db_plugins;

    $versions = get_option( 'plugin_db_versions', array() );

    foreach ( $db_plugins as $plugin => $data ) {
        if ( empty( $versions[ $plugin ] ) || version_compare( $data['version'], $versions[ $plugin ], '<' ) ) {
            call_user_func( $data['callback'], $versions[ $plugin ] );

            $versions[ $plugin ] = $data['version'];
        }
    }

    update_option( 'plugin_db_versions', $versions );
}
add_action( 'admin_init', 'update_database' );

function register_db_update_hook( $plugin, $version, $callback ) {
    global $db_plugins;

    $db_plugins[ $plugin ] = array( 'version' => $version, 'callback' => $callback );
}

Something like this code could be used (I don't want to introduce a global, but for the sake of simplicity I do it above) - of course it would need to be refined. Also, not sure if that function should be hooked into admin_init for the reasons @johnjamesjacoby stated. It could just be called afterwards.

Note: See TracTickets for help on using tickets.