Opened 10 years ago
Last modified 8 months ago
#37678 new defect (bug)
Add an action hook for plugins to do database upgrades on
| Reported by: |
|
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.
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_initfor the reasons @johnjamesjacoby stated. It could just be called afterwards.