182 lines
4.4 KiB
PHP
182 lines
4.4 KiB
PHP
<?php
|
|
namespace ElementorPro\Core\Database;
|
|
|
|
use Elementor\Core\Utils\Collection;
|
|
|
|
if ( ! defined( 'ABSPATH' ) ) {
|
|
exit; // Exit if accessed directly.
|
|
}
|
|
|
|
abstract class Base_Migration {
|
|
/*
|
|
* @see https://github.com/WordPress/WordPress/blob/d2694aa46647af48d1bcaff48a4f6cac7f5cf470/wp-admin/includes/schema.php#L49
|
|
*/
|
|
const MAX_INDEX_LENGTH = 191;
|
|
|
|
/**
|
|
* @var \wpdb
|
|
*/
|
|
protected $wpdb;
|
|
|
|
/**
|
|
* @param \wpdb|null $wpdb_instance
|
|
*/
|
|
public function __construct( \wpdb $wpdb_instance = null ) {
|
|
if ( ! $wpdb_instance ) {
|
|
global $wpdb;
|
|
|
|
$this->wpdb = $wpdb;
|
|
} else {
|
|
$this->wpdb = $wpdb_instance;
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Runs when upgrading the database
|
|
*
|
|
* @return void
|
|
*/
|
|
abstract public function up();
|
|
|
|
/**
|
|
* Runs when downgrading the database.
|
|
*
|
|
* @return void
|
|
*/
|
|
abstract public function down();
|
|
|
|
/**
|
|
* A util to run SQL for creating tables.
|
|
*
|
|
* @param $table_name
|
|
* @param array $columns
|
|
*/
|
|
protected function create_table( $table_name, array $columns ) {
|
|
$table_name = "{$this->wpdb->prefix}{$table_name}";
|
|
|
|
$columns_sql = ( new Collection( $columns ) )
|
|
->map( function( $definition, $col_name ) {
|
|
return "`{$col_name}` {$definition}";
|
|
} )
|
|
->implode( ', ' );
|
|
|
|
$query = "CREATE TABLE `{$table_name}` ({$columns_sql}) {$this->wpdb->get_charset_collate()};";
|
|
|
|
$this->run_db_delta( $query );
|
|
}
|
|
|
|
/**
|
|
* Add columns.
|
|
*
|
|
* @param $table_name
|
|
* @param array $columns
|
|
*/
|
|
protected function add_columns( $table_name, array $columns ) {
|
|
$table_name = "{$this->wpdb->prefix}{$table_name}";
|
|
|
|
$add_columns_sql = ( new Collection( $columns ) )
|
|
->map( function ( $definition, $column_name ) {
|
|
return "ADD COLUMN `{$column_name}` {$definition}";
|
|
} )
|
|
->implode( ', ' );
|
|
|
|
$this->wpdb->query( "ALTER TABLE `{$table_name}` {$add_columns_sql};" ); // phpcs:ignore
|
|
}
|
|
|
|
/**
|
|
* Drop columns
|
|
*
|
|
* @param $table_name
|
|
* @param array $columns
|
|
*/
|
|
protected function drop_columns( $table_name, array $columns ) {
|
|
$table_name = "{$this->wpdb->prefix}{$table_name}";
|
|
|
|
$drop_columns_sql = ( new Collection( $columns ) )
|
|
->map( function ( $column_name ) {
|
|
return "DROP COLUMN `{$column_name}`";
|
|
} )
|
|
->implode( ', ' );
|
|
|
|
$this->wpdb->query( "ALTER TABLE `{$table_name}` {$drop_columns_sql};" ); // phpcs:ignore
|
|
}
|
|
|
|
/**
|
|
* A util to run SQL for dropping tables.
|
|
*
|
|
* @param $table_name
|
|
*/
|
|
protected function drop_table( $table_name ) {
|
|
$table_name = "{$this->wpdb->prefix}{$table_name}";
|
|
|
|
$query = "DROP TABLE IF EXISTS `{$table_name}`;";
|
|
|
|
// Safe query that shouldn't be escaped.
|
|
$this->wpdb->query( $query ); // phpcs:ignore
|
|
}
|
|
|
|
/**
|
|
* A util to run SQL for creating indexes.
|
|
*
|
|
* @param $table_name
|
|
* @param array $column_names
|
|
*/
|
|
protected function create_indexes( $table_name, array $column_names ) {
|
|
$max_index_length = static::MAX_INDEX_LENGTH;
|
|
$table_name = "{$this->wpdb->prefix}{$table_name}";
|
|
|
|
// Safe query that shouldn't be escaped.
|
|
$column_definition = $this->get_column_definition( $table_name );
|
|
|
|
if ( ! $column_definition ) {
|
|
return;
|
|
}
|
|
|
|
$should_set_max_length_index = ( new Collection( $column_definition ) )
|
|
->filter( function ( $value ) {
|
|
preg_match( '/\((\d+)\)/', $value['Type'], $match );
|
|
|
|
return ( isset( $match[1] ) && intval( $match[1] ) > Base_Migration::MAX_INDEX_LENGTH )
|
|
|| in_array( strtolower( $value['Type'] ), [ 'text', 'longtext' ], true );
|
|
} )
|
|
->pluck( 'Field' )
|
|
->values();
|
|
|
|
$indexes_sql = ( new Collection( $column_names ) )
|
|
->map( function( $col_name ) use ( $should_set_max_length_index, $max_index_length ) {
|
|
$max_index_length_sql = '';
|
|
|
|
if ( in_array( $col_name, $should_set_max_length_index, true ) ) {
|
|
$max_index_length_sql = " ({$max_index_length})";
|
|
}
|
|
|
|
return "ADD INDEX `{$col_name}_index` (`{$col_name}`{$max_index_length_sql})";
|
|
} )
|
|
->implode( ', ' );
|
|
|
|
// Safe query that shouldn't be escaped.
|
|
$this->wpdb->query( "ALTER TABLE `{$table_name}` {$indexes_sql};" ); // phpcs:ignore
|
|
}
|
|
|
|
/**
|
|
* @param $table_name
|
|
*
|
|
* @return array
|
|
*/
|
|
protected function get_column_definition( $table_name ) {
|
|
return $this->wpdb->get_results( "SHOW COLUMNS FROM `{$table_name}`;", ARRAY_A ); // phpcs:ignore
|
|
}
|
|
|
|
/**
|
|
* Runs global dbDelta function (wrapped into method to allowing mock for testing).
|
|
*
|
|
* @param $query
|
|
*
|
|
* @return array
|
|
*/
|
|
protected function run_db_delta( $query ) {
|
|
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
|
|
|
return dbDelta( $query );
|
|
}
|
|
}
|