173 lines
4.5 KiB
PHP
173 lines
4.5 KiB
PHP
|
<?php
|
||
|
|
||
|
|
||
|
/**
|
||
|
* Class ActionScheduler_Abstract_Schema
|
||
|
*
|
||
|
* @package Action_Scheduler
|
||
|
*
|
||
|
* @codeCoverageIgnore
|
||
|
*
|
||
|
* Utility class for creating/updating custom tables
|
||
|
*/
|
||
|
abstract class ActionScheduler_Abstract_Schema {
|
||
|
|
||
|
/**
|
||
|
* @var int Increment this value in derived class to trigger a schema update.
|
||
|
*/
|
||
|
protected $schema_version = 1;
|
||
|
|
||
|
/**
|
||
|
* @var string Schema version stored in database.
|
||
|
*/
|
||
|
protected $db_version;
|
||
|
|
||
|
/**
|
||
|
* @var array Names of tables that will be registered by this class.
|
||
|
*/
|
||
|
protected $tables = [];
|
||
|
|
||
|
/**
|
||
|
* Can optionally be used by concrete classes to carry out additional initialization work
|
||
|
* as needed.
|
||
|
*/
|
||
|
public function init() {}
|
||
|
|
||
|
/**
|
||
|
* Register tables with WordPress, and create them if needed.
|
||
|
*
|
||
|
* @param bool $force_update Optional. Default false. Use true to always run the schema update.
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
public function register_tables( $force_update = false ) {
|
||
|
global $wpdb;
|
||
|
|
||
|
// make WP aware of our tables
|
||
|
foreach ( $this->tables as $table ) {
|
||
|
$wpdb->tables[] = $table;
|
||
|
$name = $this->get_full_table_name( $table );
|
||
|
$wpdb->$table = $name;
|
||
|
}
|
||
|
|
||
|
// create the tables
|
||
|
if ( $this->schema_update_required() || $force_update ) {
|
||
|
foreach ( $this->tables as $table ) {
|
||
|
/**
|
||
|
* Allow custom processing before updating a table schema.
|
||
|
*
|
||
|
* @param string $table Name of table being updated.
|
||
|
* @param string $db_version Existing version of the table being updated.
|
||
|
*/
|
||
|
do_action( 'action_scheduler_before_schema_update', $table, $this->db_version );
|
||
|
$this->update_table( $table );
|
||
|
}
|
||
|
$this->mark_schema_update_complete();
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $table The name of the table
|
||
|
*
|
||
|
* @return string The CREATE TABLE statement, suitable for passing to dbDelta
|
||
|
*/
|
||
|
abstract protected function get_table_definition( $table );
|
||
|
|
||
|
/**
|
||
|
* Determine if the database schema is out of date
|
||
|
* by comparing the integer found in $this->schema_version
|
||
|
* with the option set in the WordPress options table
|
||
|
*
|
||
|
* @return bool
|
||
|
*/
|
||
|
private function schema_update_required() {
|
||
|
$option_name = 'schema-' . static::class;
|
||
|
$this->db_version = get_option( $option_name, 0 );
|
||
|
|
||
|
// Check for schema option stored by the Action Scheduler Custom Tables plugin in case site has migrated from that plugin with an older schema
|
||
|
if ( 0 === $this->db_version ) {
|
||
|
|
||
|
$plugin_option_name = 'schema-';
|
||
|
|
||
|
switch ( static::class ) {
|
||
|
case 'ActionScheduler_StoreSchema' :
|
||
|
$plugin_option_name .= 'Action_Scheduler\Custom_Tables\DB_Store_Table_Maker';
|
||
|
break;
|
||
|
case 'ActionScheduler_LoggerSchema' :
|
||
|
$plugin_option_name .= 'Action_Scheduler\Custom_Tables\DB_Logger_Table_Maker';
|
||
|
break;
|
||
|
}
|
||
|
|
||
|
$this->db_version = get_option( $plugin_option_name, 0 );
|
||
|
|
||
|
delete_option( $plugin_option_name );
|
||
|
}
|
||
|
|
||
|
return version_compare( $this->db_version, $this->schema_version, '<' );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Update the option in WordPress to indicate that
|
||
|
* our schema is now up to date
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
private function mark_schema_update_complete() {
|
||
|
$option_name = 'schema-' . static::class;
|
||
|
|
||
|
// work around race conditions and ensure that our option updates
|
||
|
$value_to_save = (string) $this->schema_version . '.0.' . time();
|
||
|
|
||
|
update_option( $option_name, $value_to_save );
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Update the schema for the given table
|
||
|
*
|
||
|
* @param string $table The name of the table to update
|
||
|
*
|
||
|
* @return void
|
||
|
*/
|
||
|
private function update_table( $table ) {
|
||
|
require_once( ABSPATH . 'wp-admin/includes/upgrade.php' );
|
||
|
$definition = $this->get_table_definition( $table );
|
||
|
if ( $definition ) {
|
||
|
$updated = dbDelta( $definition );
|
||
|
foreach ( $updated as $updated_table => $update_description ) {
|
||
|
if ( strpos( $update_description, 'Created table' ) === 0 ) {
|
||
|
do_action( 'action_scheduler/created_table', $updated_table, $table );
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* @param string $table
|
||
|
*
|
||
|
* @return string The full name of the table, including the
|
||
|
* table prefix for the current blog
|
||
|
*/
|
||
|
protected function get_full_table_name( $table ) {
|
||
|
return $GLOBALS[ 'wpdb' ]->prefix . $table;
|
||
|
}
|
||
|
|
||
|
/**
|
||
|
* Confirms that all of the tables registered by this schema class have been created.
|
||
|
*
|
||
|
* @return bool
|
||
|
*/
|
||
|
public function tables_exist() {
|
||
|
global $wpdb;
|
||
|
|
||
|
$existing_tables = $wpdb->get_col( 'SHOW TABLES' );
|
||
|
$expected_tables = array_map(
|
||
|
function ( $table_name ) use ( $wpdb ) {
|
||
|
return $wpdb->prefix . $table_name;
|
||
|
},
|
||
|
$this->tables
|
||
|
);
|
||
|
|
||
|
return count( array_intersect( $existing_tables, $expected_tables ) ) === count( $expected_tables );
|
||
|
}
|
||
|
}
|