Make the db utils class non-static, change the custom orders tables UI
- Rename DBUtils to DatabaseUtils, and register it in the DI container (instead of having it just contain static methods) - The tool for the custom orders tables has now two shapes: "create tables" and "delete tables" (so no regeneration, migration...) - Not yet used constants and methods from DataSynchronizer removed - Added missing method comments
This commit is contained in:
parent
fc0c45a204
commit
3964a2255a
|
@ -7,6 +7,7 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
use Automattic\Jetpack\Constants;
|
use Automattic\Jetpack\Constants;
|
||||||
|
use Automattic\WooCommerce\Internal\Utilities\DatabaseUtil;
|
||||||
use Automattic\WooCommerce\Internal\WCCom\ConnectionHelper as WCConnectionHelper;
|
use Automattic\WooCommerce\Internal\WCCom\ConnectionHelper as WCConnectionHelper;
|
||||||
use Automattic\WooCommerce\Utilities\DBUtil;
|
use Automattic\WooCommerce\Utilities\DBUtil;
|
||||||
|
|
||||||
|
@ -345,7 +346,9 @@ class WC_Install {
|
||||||
self::create_tables();
|
self::create_tables();
|
||||||
}
|
}
|
||||||
|
|
||||||
$missing_tables = DBUtil::verify_database_tables_exist( self::get_schema() );
|
$missing_tables = wc_get_container()
|
||||||
|
->get( DatabaseUtil::class )
|
||||||
|
->get_missing_tables( self::get_schema() );
|
||||||
|
|
||||||
if ( 0 < count( $missing_tables ) ) {
|
if ( 0 < count( $missing_tables ) ) {
|
||||||
if ( $modify_notice ) {
|
if ( $modify_notice ) {
|
||||||
|
@ -580,22 +583,22 @@ class WC_Install {
|
||||||
$pages = apply_filters(
|
$pages = apply_filters(
|
||||||
'woocommerce_create_pages',
|
'woocommerce_create_pages',
|
||||||
array(
|
array(
|
||||||
'shop' => array(
|
'shop' => array(
|
||||||
'name' => _x( 'shop', 'Page slug', 'woocommerce' ),
|
'name' => _x( 'shop', 'Page slug', 'woocommerce' ),
|
||||||
'title' => _x( 'Shop', 'Page title', 'woocommerce' ),
|
'title' => _x( 'Shop', 'Page title', 'woocommerce' ),
|
||||||
'content' => '',
|
'content' => '',
|
||||||
),
|
),
|
||||||
'cart' => array(
|
'cart' => array(
|
||||||
'name' => _x( 'cart', 'Page slug', 'woocommerce' ),
|
'name' => _x( 'cart', 'Page slug', 'woocommerce' ),
|
||||||
'title' => _x( 'Cart', 'Page title', 'woocommerce' ),
|
'title' => _x( 'Cart', 'Page title', 'woocommerce' ),
|
||||||
'content' => '<!-- wp:shortcode -->[' . apply_filters( 'woocommerce_cart_shortcode_tag', 'woocommerce_cart' ) . ']<!-- /wp:shortcode -->',
|
'content' => '<!-- wp:shortcode -->[' . apply_filters( 'woocommerce_cart_shortcode_tag', 'woocommerce_cart' ) . ']<!-- /wp:shortcode -->',
|
||||||
),
|
),
|
||||||
'checkout' => array(
|
'checkout' => array(
|
||||||
'name' => _x( 'checkout', 'Page slug', 'woocommerce' ),
|
'name' => _x( 'checkout', 'Page slug', 'woocommerce' ),
|
||||||
'title' => _x( 'Checkout', 'Page title', 'woocommerce' ),
|
'title' => _x( 'Checkout', 'Page title', 'woocommerce' ),
|
||||||
'content' => '<!-- wp:shortcode -->[' . apply_filters( 'woocommerce_checkout_shortcode_tag', 'woocommerce_checkout' ) . ']<!-- /wp:shortcode -->',
|
'content' => '<!-- wp:shortcode -->[' . apply_filters( 'woocommerce_checkout_shortcode_tag', 'woocommerce_checkout' ) . ']<!-- /wp:shortcode -->',
|
||||||
),
|
),
|
||||||
'myaccount' => array(
|
'myaccount' => array(
|
||||||
'name' => _x( 'my-account', 'Page slug', 'woocommerce' ),
|
'name' => _x( 'my-account', 'Page slug', 'woocommerce' ),
|
||||||
'title' => _x( 'My account', 'Page title', 'woocommerce' ),
|
'title' => _x( 'My account', 'Page title', 'woocommerce' ),
|
||||||
'content' => '<!-- wp:shortcode -->[' . apply_filters( 'woocommerce_my_account_shortcode_tag', 'woocommerce_my_account' ) . ']<!-- /wp:shortcode -->',
|
'content' => '<!-- wp:shortcode -->[' . apply_filters( 'woocommerce_my_account_shortcode_tag', 'woocommerce_my_account' ) . ']<!-- /wp:shortcode -->',
|
||||||
|
|
|
@ -12,6 +12,7 @@ use Automattic\WooCommerce\Internal\DependencyManagement\ServiceProviders\Orders
|
||||||
use Automattic\WooCommerce\Internal\DependencyManagement\ServiceProviders\ProductAttributesLookupServiceProvider;
|
use Automattic\WooCommerce\Internal\DependencyManagement\ServiceProviders\ProductAttributesLookupServiceProvider;
|
||||||
use Automattic\WooCommerce\Internal\DependencyManagement\ServiceProviders\ProxiesServiceProvider;
|
use Automattic\WooCommerce\Internal\DependencyManagement\ServiceProviders\ProxiesServiceProvider;
|
||||||
use Automattic\WooCommerce\Internal\DependencyManagement\ServiceProviders\RestockRefundedItemsAdjusterServiceProvider;
|
use Automattic\WooCommerce\Internal\DependencyManagement\ServiceProviders\RestockRefundedItemsAdjusterServiceProvider;
|
||||||
|
use Automattic\WooCommerce\Internal\DependencyManagement\ServiceProviders\UtilsClassesServiceProvider;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* PSR11 compliant dependency injection container for WooCommerce.
|
* PSR11 compliant dependency injection container for WooCommerce.
|
||||||
|
@ -43,6 +44,7 @@ final class Container implements \Psr\Container\ContainerInterface {
|
||||||
ProductAttributesLookupServiceProvider::class,
|
ProductAttributesLookupServiceProvider::class,
|
||||||
ProxiesServiceProvider::class,
|
ProxiesServiceProvider::class,
|
||||||
RestockRefundedItemsAdjusterServiceProvider::class,
|
RestockRefundedItemsAdjusterServiceProvider::class,
|
||||||
|
UtilsClassesServiceProvider::class,
|
||||||
);
|
);
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
@ -8,7 +8,7 @@ namespace Automattic\WooCommerce\Internal\DataStores\Orders;
|
||||||
defined( 'ABSPATH' ) || exit;
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This is the main class that controls the custom orders table feature. Its responsibilities are:
|
* This is the main class that controls the custom orders tables feature. Its responsibilities are:
|
||||||
*
|
*
|
||||||
* - Allowing to enable and disable the feature while it's in development (show_feature method)
|
* - Allowing to enable and disable the feature while it's in development (show_feature method)
|
||||||
* - Displaying UI components (entries in the tools page and in settings)
|
* - Displaying UI components (entries in the tools page and in settings)
|
||||||
|
@ -19,7 +19,7 @@ defined( 'ABSPATH' ) || exit;
|
||||||
class CustomOrdersTableController {
|
class CustomOrdersTableController {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The name of the option for enabling the usage of the custom orders table
|
* The name of the option for enabling the usage of the custom orders tables
|
||||||
*/
|
*/
|
||||||
const CUSTOM_ORDERS_TABLE_USAGE_ENABLED_OPTION = 'woocommerce_custom_orders_table_enabled';
|
const CUSTOM_ORDERS_TABLE_USAGE_ENABLED_OPTION = 'woocommerce_custom_orders_table_enabled';
|
||||||
|
|
||||||
|
@ -146,7 +146,7 @@ class CustomOrdersTableController {
|
||||||
* @return WC_Object_Data_Store_Interface|string The actual data store to use.
|
* @return WC_Object_Data_Store_Interface|string The actual data store to use.
|
||||||
*/
|
*/
|
||||||
private function get_data_store_instance( $default_data_store ) {
|
private function get_data_store_instance( $default_data_store ) {
|
||||||
if ( $this->is_feature_visible() && $this->custom_orders_table_usage_is_enabled() && ! $this->data_synchronizer->data_regeneration_is_in_progress() ) {
|
if ( $this->is_feature_visible() && $this->custom_orders_table_usage_is_enabled() ) {
|
||||||
return $this->data_store;
|
return $this->data_store;
|
||||||
} else {
|
} else {
|
||||||
return $default_data_store;
|
return $default_data_store;
|
||||||
|
@ -160,66 +160,37 @@ class CustomOrdersTableController {
|
||||||
* @param array $tools_array The array of tools to add the tool to.
|
* @param array $tools_array The array of tools to add the tool to.
|
||||||
* @return array The updated array of tools-
|
* @return array The updated array of tools-
|
||||||
*/
|
*/
|
||||||
private function add_initiate_regeneration_entry_to_tools_array(array $tools_array ): array {
|
private function add_initiate_regeneration_entry_to_tools_array( array $tools_array ): array {
|
||||||
if ( ! $this->is_feature_visible() ) {
|
if ( ! $this->is_feature_visible() ) {
|
||||||
return $tools_array;
|
return $tools_array;
|
||||||
}
|
}
|
||||||
|
|
||||||
$orders_table_exists = $this->data_synchronizer->check_orders_table_exists();
|
if ( $this->data_synchronizer->check_orders_table_exists() ) {
|
||||||
$generation_is_in_progress = $this->data_synchronizer->data_regeneration_is_in_progress();
|
|
||||||
|
|
||||||
if ( $orders_table_exists ) {
|
|
||||||
$generate_item_name = __( 'Regenerate the custom orders table', 'woocommerce' );
|
|
||||||
$generate_item_desc = __( 'This tool will regenerate the custom orders table data from existing orders data from the posts table. This process may take a while.', 'woocommerce' );
|
|
||||||
$generate_item_return = __( 'Custom orders table is being regenerated', 'woocommerce' );
|
|
||||||
$generate_item_button = __( 'Regenerate', 'woocommerce' );
|
|
||||||
} else {
|
|
||||||
$generate_item_name = __( 'Create and fill custom orders table', 'woocommerce' );
|
|
||||||
$generate_item_desc = __( 'This tool will create the custom orders table and fill it with existing orders data from the posts table. This process may take a while.', 'woocommerce' );
|
|
||||||
$generate_item_return = __( 'Custom orders table is being filled', 'woocommerce' );
|
|
||||||
$generate_item_button = __( 'Create', 'woocommerce' );
|
|
||||||
}
|
|
||||||
|
|
||||||
$entry = array(
|
|
||||||
'name' => $generate_item_name,
|
|
||||||
'desc' => $generate_item_desc,
|
|
||||||
'requires_refresh' => true,
|
|
||||||
'callback' => function() use ( $generate_item_return ) {
|
|
||||||
$this->initiate_regeneration_from_tools_page();
|
|
||||||
return $generate_item_return;
|
|
||||||
},
|
|
||||||
);
|
|
||||||
|
|
||||||
if ( $generation_is_in_progress ) {
|
|
||||||
$entry['button'] = sprintf(
|
|
||||||
/* translators: %d: How many orders have been processed so far. */
|
|
||||||
__( 'Filling in progress (%d)', 'woocommerce' ),
|
|
||||||
$this->data_synchronizer->get_regeneration_processed_orders_count()
|
|
||||||
);
|
|
||||||
$entry['disabled'] = true;
|
|
||||||
} else {
|
|
||||||
$entry['button'] = $generate_item_button;
|
|
||||||
}
|
|
||||||
|
|
||||||
$tools_array['regenerate_custom_orders_table'] = $entry;
|
|
||||||
|
|
||||||
if ( $orders_table_exists ) {
|
|
||||||
|
|
||||||
// Delete the table.
|
|
||||||
|
|
||||||
$tools_array['delete_custom_orders_table'] = array(
|
$tools_array['delete_custom_orders_table'] = array(
|
||||||
'name' => __( 'Delete the custom orders table', 'woocommerce' ),
|
'name' => __( 'Delete the custom orders tables', 'woocommerce' ),
|
||||||
'desc' => sprintf(
|
'desc' => sprintf(
|
||||||
'<strong class="red">%1$s</strong> %2$s',
|
'<strong class="red">%1$s</strong> %2$s',
|
||||||
__( 'Note:', 'woocommerce' ),
|
__( 'Note:', 'woocommerce' ),
|
||||||
__( 'This will delete the custom orders table. You can create it again with the "Create and fill custom orders table" tool.', 'woocommerce' )
|
__( 'This will delete the custom orders tables. The tables can be deleted only if they are not not in use (via Settings > Advanced > Custom data stores). You can create them again at any time with the "Create the custom orders tables" tool.', 'woocommerce' )
|
||||||
),
|
),
|
||||||
'button' => __( 'Delete', 'woocommerce' ),
|
|
||||||
'requires_refresh' => true,
|
'requires_refresh' => true,
|
||||||
'callback' => function () {
|
'callback' => function () {
|
||||||
$this->delete_custom_orders_table();
|
$this->delete_custom_orders_tables();
|
||||||
return __( 'Custom orders table has been deleted.', 'woocommerce' );
|
return __( 'Custom orders tables have been deleted.', 'woocommerce' );
|
||||||
},
|
},
|
||||||
|
'button' => __( 'Delete', 'woocommerce' ),
|
||||||
|
'disabled' => $this->custom_orders_table_usage_is_enabled(),
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$tools_array['create_custom_orders_table'] = array(
|
||||||
|
'name' => __( 'Create the custom orders tables', 'woocommerce' ),
|
||||||
|
'desc' => __( 'This tool will create the custom orders tables. Once created you can go to WooCommerce > Settings > Advanced > Custom data stores and configure the usage of the tables.', 'woocommerce' ),
|
||||||
|
'requires_refresh' => true,
|
||||||
|
'callback' => function() {
|
||||||
|
$this->create_custom_orders_tables();
|
||||||
|
return __( 'Custom orders tables have been created. You can now go to WooCommerce > Settings > Advanced > Custom data stores.', 'woocommerce' );
|
||||||
|
},
|
||||||
|
'button' => __( 'Create', 'woocommerce' ),
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -227,41 +198,35 @@ class CustomOrdersTableController {
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initiate the custom orders table (re)generation in response to the user pressing the tool button.
|
* Create the custom orders tables in response to the user pressing the tool button.
|
||||||
*
|
*
|
||||||
* @throws \Exception Can't initiate regeneration.
|
* @throws \Exception Can't create the tables.
|
||||||
*/
|
*/
|
||||||
private function initiate_regeneration_from_tools_page() {
|
private function create_custom_orders_tables() {
|
||||||
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput
|
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput
|
||||||
if ( ! isset( $_REQUEST['_wpnonce'] ) || false === wp_verify_nonce( $_REQUEST['_wpnonce'], 'debug_action' ) ) {
|
if ( ! isset( $_REQUEST['_wpnonce'] ) || false === wp_verify_nonce( $_REQUEST['_wpnonce'], 'debug_action' ) ) {
|
||||||
throw new \Exception( 'Invalid nonce' );
|
throw new \Exception( 'Invalid nonce' );
|
||||||
}
|
}
|
||||||
|
|
||||||
$this->check_can_do_table_regeneration();
|
|
||||||
$this->data_synchronizer->initiate_regeneration();
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Can the custom orders table regeneration be started?
|
|
||||||
*
|
|
||||||
* @throws \Exception The table regeneration can't be started.
|
|
||||||
*/
|
|
||||||
private function check_can_do_table_regeneration() {
|
|
||||||
if ( ! $this->is_feature_visible() ) {
|
if ( ! $this->is_feature_visible() ) {
|
||||||
throw new \Exception( "Can't do custom orders table regeneration: the feature isn't enabled" );
|
throw new \Exception( "Can't create the custom orders tables: the feature isn't enabled" );
|
||||||
}
|
}
|
||||||
|
|
||||||
if ( $this->data_synchronizer->data_regeneration_is_in_progress() ) {
|
$this->data_synchronizer->create_database_tables();
|
||||||
throw new \Exception( "Can't do custom orders table regeneration: regeneration is already in progress" );
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Delete the custom orders table and any related options and data.
|
* Delete the custom orders tables and any related options and data in response to the user pressing the tool button.
|
||||||
|
*
|
||||||
|
* @throws \Exception Can't delete the tables.
|
||||||
*/
|
*/
|
||||||
private function delete_custom_orders_table() {
|
private function delete_custom_orders_tables() {
|
||||||
|
if ( $this->custom_orders_table_usage_is_enabled() ) {
|
||||||
|
throw new \Exception( "Can't delete the custom orders tables: they are currently in use (via Settings > Advanced > Custom data stores)." );
|
||||||
|
}
|
||||||
|
|
||||||
delete_option( self::CUSTOM_ORDERS_TABLE_USAGE_ENABLED_OPTION );
|
delete_option( self::CUSTOM_ORDERS_TABLE_USAGE_ENABLED_OPTION );
|
||||||
$this->data_synchronizer->delete_custom_orders_table();
|
$this->data_synchronizer->delete_database_tables();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -282,7 +247,7 @@ class CustomOrdersTableController {
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Get the settings for the "Custom data stores" section in the "Advanced" tab,
|
* Get the settings for the "Custom data stores" section in the "Advanced" tab,
|
||||||
* with entries for managing the custom orders table if appropriate.
|
* with entries for managing the custom orders tables if appropriate.
|
||||||
*
|
*
|
||||||
* @param array $settings The original settings array.
|
* @param array $settings The original settings array.
|
||||||
* @param string $section_id The settings section to get the settings for.
|
* @param string $section_id The settings section to get the settings for.
|
||||||
|
@ -294,26 +259,31 @@ class CustomOrdersTableController {
|
||||||
}
|
}
|
||||||
|
|
||||||
$title_item = array(
|
$title_item = array(
|
||||||
'title' => __( 'Custom orders table', 'woocommerce' ),
|
'title' => __( 'Custom orders tables', 'woocommerce' ),
|
||||||
'type' => 'title',
|
'type' => 'title',
|
||||||
);
|
);
|
||||||
|
|
||||||
|
if ( $this->data_synchronizer->check_orders_table_exists() ) {
|
||||||
|
$settings[] = $title_item;
|
||||||
|
|
||||||
if ( ! $this->data_synchronizer->check_orders_table_exists() ) {
|
$settings[] = array(
|
||||||
$title_item['desc'] = __( 'Generate custom tables first by going to WooCommerce > Status > Tools > Create and fill custom orders table', 'woocommerce' );
|
'title' => __( 'Enable tables usage', 'woocommerce' ),
|
||||||
|
'desc' => __( 'Use the custom orders tables as the main orders data store.', 'woocommerce' ),
|
||||||
|
'id' => self::CUSTOM_ORDERS_TABLE_USAGE_ENABLED_OPTION,
|
||||||
|
'default' => 'no',
|
||||||
|
'type' => 'checkbox',
|
||||||
|
'checkboxgroup' => 'start',
|
||||||
|
);
|
||||||
|
} else {
|
||||||
|
$title_item['desc'] = sprintf(
|
||||||
|
/* translators: %1$ = <em> tag, %2$ = </em> tag. */
|
||||||
|
__( 'Create the tables first by going to %1$sWooCommerce > Status > Tools%2$s and running %1$sCreate the custom orders tables%2$s.', 'woocommerce' ),
|
||||||
|
'<em>',
|
||||||
|
'</em>'
|
||||||
|
);
|
||||||
|
$settings[] = $title_item;
|
||||||
}
|
}
|
||||||
|
|
||||||
$settings[] = $title_item;
|
|
||||||
|
|
||||||
$settings[] = array(
|
|
||||||
'title' => __( 'Enable table usage', 'woocommerce' ),
|
|
||||||
'desc' => __( 'Use the custom orders table as the main orders data store.', 'woocommerce' ),
|
|
||||||
'id' => self::CUSTOM_ORDERS_TABLE_USAGE_ENABLED_OPTION,
|
|
||||||
'default' => 'no',
|
|
||||||
'type' => 'checkbox',
|
|
||||||
'checkboxgroup' => 'start',
|
|
||||||
);
|
|
||||||
|
|
||||||
$settings[] = array( 'type' => 'sectionend' );
|
$settings[] = array( 'type' => 'sectionend' );
|
||||||
|
|
||||||
return $settings;
|
return $settings;
|
||||||
|
|
|
@ -5,21 +5,18 @@
|
||||||
|
|
||||||
namespace Automattic\WooCommerce\Internal\DataStores\Orders;
|
namespace Automattic\WooCommerce\Internal\DataStores\Orders;
|
||||||
|
|
||||||
use Automattic\WooCommerce\Utilities\DBUtil;
|
use Automattic\WooCommerce\Internal\Utilities\DatabaseUtil;
|
||||||
|
|
||||||
defined( 'ABSPATH' ) || exit;
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* This class handles the data migration/synchronization for the custom orders table. Its responsibilites are:
|
* This class handles the database structure creation and the data synchronization for the custom orders tables. Its responsibilites are:
|
||||||
*
|
*
|
||||||
* - Performing the initial table creation and filling (triggered by initiate_regeneration)
|
* - Providing entry points for creating and deleting the required database tables.
|
||||||
* - Synchronizing changes between the custom orders table and the posts table whenever changes in orders happen.
|
* - Synchronizing changes between the custom orders tables and the posts table whenever changes in orders happen.
|
||||||
*/
|
*/
|
||||||
class DataSynchronizer {
|
class DataSynchronizer {
|
||||||
|
|
||||||
const CUSTOM_ORDERS_TABLE_DATA_REGENERATION_IN_PROGRESS = 'woocommerce_custom_orders_table_data_regeneration_in_progress';
|
|
||||||
const CUSTOM_ORDERS_TABLE_DATA_REGENERATION_DONE_COUNT = 'woocommerce_custom_orders_table_data_regeneration_done_count';
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* The data store object to use.
|
* The data store object to use.
|
||||||
*
|
*
|
||||||
|
@ -27,6 +24,13 @@ class DataSynchronizer {
|
||||||
*/
|
*/
|
||||||
private $data_store;
|
private $data_store;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The database util object to use.
|
||||||
|
*
|
||||||
|
* @var DatabaseUtil
|
||||||
|
*/
|
||||||
|
private $database_util;
|
||||||
|
|
||||||
// TODO: Add a constructor to handle hooks as appropriate.
|
// TODO: Add a constructor to handle hooks as appropriate.
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -34,55 +38,41 @@ class DataSynchronizer {
|
||||||
*
|
*
|
||||||
* @internal
|
* @internal
|
||||||
* @param OrdersTableDataStore $data_store The data store to use.
|
* @param OrdersTableDataStore $data_store The data store to use.
|
||||||
|
* @param DatabaseUtil $database_util The database util class to use.
|
||||||
*/
|
*/
|
||||||
final public function init( OrdersTableDataStore $data_store ) {
|
final public function init( OrdersTableDataStore $data_store, DatabaseUtil $database_util ) {
|
||||||
$this->data_store = $data_store;
|
$this->data_store = $data_store;
|
||||||
|
$this->database_util = $database_util;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Does the custom orders table exist in the database?
|
* Does the custom orders tables exist in the database?
|
||||||
*
|
*
|
||||||
* @return bool True if the custom orders table exist in the database.
|
* @return bool True if the custom orders tables exist in the database.
|
||||||
*/
|
*/
|
||||||
public function check_orders_table_exists(): bool {
|
public function check_orders_table_exists(): bool {
|
||||||
$missing_tables = DBUtil::verify_database_tables_exist( $this->data_store->get_schema() );
|
$missing_tables = $this->database_util->get_missing_tables( $this->data_store->get_database_schema() );
|
||||||
if ( count( $missing_tables ) > 0 ) {
|
|
||||||
delete_option( self::CUSTOM_ORDERS_TABLE_DATA_REGENERATION_IN_PROGRESS );
|
|
||||||
}
|
|
||||||
return count( $missing_tables ) === 0;
|
return count( $missing_tables ) === 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Is a table regeneration in progress?
|
* Create the custom orders database tables.
|
||||||
*
|
|
||||||
* @return bool True if a table regeneration in currently progress
|
|
||||||
*/
|
*/
|
||||||
public function data_regeneration_is_in_progress(): bool {
|
public function create_database_tables() {
|
||||||
return 'yes' === get_option( self::CUSTOM_ORDERS_TABLE_DATA_REGENERATION_IN_PROGRESS );
|
$this->database_util->dbdelta( $this->data_store->get_database_schema() );
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Initiate a table regeneration process.
|
* Delete the custom orders database tables.
|
||||||
*/
|
*/
|
||||||
public function initiate_regeneration() {
|
public function delete_database_tables() {
|
||||||
update_option( self::CUSTOM_ORDERS_TABLE_DATA_REGENERATION_IN_PROGRESS, 'yes' );
|
$table_names = $this->data_store->get_all_table_names();
|
||||||
update_option( self::CUSTOM_ORDERS_TABLE_DATA_REGENERATION_DONE_COUNT, 0 );
|
|
||||||
DBUtil::create_database_tables( $this->data_store->get_schema() );
|
foreach ( $table_names as $table_name ) {
|
||||||
|
$this->database_util->drop_database_table( $table_name );
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
|
||||||
* How many orders have been processed as part of the custom orders table regeneration?
|
|
||||||
*
|
|
||||||
* @return int Number of orders already processed, 0 if no regeneration is in progress.
|
|
||||||
*/
|
|
||||||
public function get_regeneration_processed_orders_count(): int {
|
|
||||||
return (int)get_option( self::CUSTOM_ORDERS_TABLE_DATA_REGENERATION_DONE_COUNT, 0 );
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Delete the custom orders table and the associated information.
|
|
||||||
*/
|
|
||||||
public function delete_custom_orders_table() {
|
|
||||||
// TODO: Delete the tables and any associated data (e.g. options).
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
|
@ -5,8 +5,6 @@
|
||||||
|
|
||||||
namespace Automattic\WooCommerce\Internal\DataStores\Orders;
|
namespace Automattic\WooCommerce\Internal\DataStores\Orders;
|
||||||
|
|
||||||
use Automattic\Jetpack\Constants;
|
|
||||||
|
|
||||||
defined( 'ABSPATH' ) || exit;
|
defined( 'ABSPATH' ) || exit;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
@ -24,19 +22,42 @@ class OrdersTableDataStore extends \Abstract_WC_Order_Data_Store_CPT implements
|
||||||
return $wpdb->prefix . 'wc_orders';
|
return $wpdb->prefix . 'wc_orders';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the order addresses table name.
|
||||||
|
*
|
||||||
|
* @return string The order addresses table name.
|
||||||
|
*/
|
||||||
public function get_addresses_table_name() {
|
public function get_addresses_table_name() {
|
||||||
global $wpdb;
|
global $wpdb;
|
||||||
return $wpdb->prefix . 'wc_order_addresses';
|
return $wpdb->prefix . 'wc_order_addresses';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the orders operational data table name.
|
||||||
|
*
|
||||||
|
* @return string The orders operational data table name.
|
||||||
|
*/
|
||||||
public function get_operational_data_table_name() {
|
public function get_operational_data_table_name() {
|
||||||
global $wpdb;
|
global $wpdb;
|
||||||
return $wpdb->prefix . 'wc_order_operational_data';
|
return $wpdb->prefix . 'wc_order_operational_data';
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Get the names of all the tables involved in the custom orders table feature.
|
||||||
|
*
|
||||||
|
* @return string[]
|
||||||
|
*/
|
||||||
|
public function get_all_table_names() {
|
||||||
|
return array(
|
||||||
|
$this->get_orders_table_name(),
|
||||||
|
$this->get_addresses_table_name(),
|
||||||
|
$this->get_operational_data_table_name(),
|
||||||
|
);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Add methods for other table names as appropriate.
|
// TODO: Add methods for other table names as appropriate.
|
||||||
|
|
||||||
//phpcs:disable Squiz.Commenting.FunctionComment.Missing
|
//phpcs:disable Squiz.Commenting, Generic.Commenting
|
||||||
|
|
||||||
public function get_total_refunded( $order ) {
|
public function get_total_refunded( $order ) {
|
||||||
// TODO: Implement get_total_refunded() method.
|
// TODO: Implement get_total_refunded() method.
|
||||||
|
@ -153,14 +174,19 @@ class OrdersTableDataStore extends \Abstract_WC_Order_Data_Store_CPT implements
|
||||||
return 'line_item';
|
return 'line_item';
|
||||||
}
|
}
|
||||||
|
|
||||||
//phpcs:enable Squiz.Commenting.FunctionComment.Missing
|
//phpcs:enable Squiz.Commenting, Generic.Commenting
|
||||||
|
|
||||||
|
/**
|
||||||
public function get_schema() {
|
* Get the SQL needed to create all the tables needed for the custom orders table feature.
|
||||||
$orders_table_name = $this->get_orders_table_name();
|
*
|
||||||
$addresses_table_name = $this->get_addresses_table_name();
|
* @return string
|
||||||
|
*/
|
||||||
|
public function get_database_schema() {
|
||||||
|
$orders_table_name = $this->get_orders_table_name();
|
||||||
|
$addresses_table_name = $this->get_addresses_table_name();
|
||||||
$operational_data_table_name = $this->get_operational_data_table_name();
|
$operational_data_table_name = $this->get_operational_data_table_name();
|
||||||
$table = "
|
|
||||||
|
$sql = "
|
||||||
CREATE TABLE $orders_table_name (
|
CREATE TABLE $orders_table_name (
|
||||||
id bigint(20) unsigned auto_increment,
|
id bigint(20) unsigned auto_increment,
|
||||||
post_id bigint(20) unsigned null,
|
post_id bigint(20) unsigned null,
|
||||||
|
@ -222,6 +248,6 @@ CREATE TABLE $operational_data_table_name (
|
||||||
KEY order_id (order_id),
|
KEY order_id (order_id),
|
||||||
KEY order_key (order_key)
|
KEY order_key (order_key)
|
||||||
);";
|
);";
|
||||||
return $table;
|
return $sql;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?php
|
<?php
|
||||||
/**
|
/**
|
||||||
* ProductAttributesLookupServiceProvider class file.
|
* OrdersDataStoreServiceProvider class file.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
namespace Automattic\WooCommerce\Internal\DependencyManagement\ServiceProviders;
|
namespace Automattic\WooCommerce\Internal\DependencyManagement\ServiceProviders;
|
||||||
|
@ -9,9 +9,10 @@ use Automattic\WooCommerce\Internal\DependencyManagement\AbstractServiceProvider
|
||||||
use Automattic\WooCommerce\Internal\DataStores\Orders\DataSynchronizer;
|
use Automattic\WooCommerce\Internal\DataStores\Orders\DataSynchronizer;
|
||||||
use Automattic\WooCommerce\Internal\DataStores\Orders\CustomOrdersTableController;
|
use Automattic\WooCommerce\Internal\DataStores\Orders\CustomOrdersTableController;
|
||||||
use Automattic\WooCommerce\Internal\DataStores\Orders\OrdersTableDataStore;
|
use Automattic\WooCommerce\Internal\DataStores\Orders\OrdersTableDataStore;
|
||||||
|
use Automattic\WooCommerce\Internal\Utilities\DatabaseUtil;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Service provider for the ProductAttributesLookupServiceProvider namespace.
|
* Service provider for the classes in the Internal\DataStores\Orders namespace.
|
||||||
*/
|
*/
|
||||||
class OrdersDataStoreServiceProvider extends AbstractServiceProvider {
|
class OrdersDataStoreServiceProvider extends AbstractServiceProvider {
|
||||||
|
|
||||||
|
@ -30,7 +31,7 @@ class OrdersDataStoreServiceProvider extends AbstractServiceProvider {
|
||||||
* Register the classes.
|
* Register the classes.
|
||||||
*/
|
*/
|
||||||
public function register() {
|
public function register() {
|
||||||
$this->share( DataSynchronizer::class )->addArgument( OrdersTableDataStore::class );
|
$this->share( DataSynchronizer::class )->addArguments( array( OrdersTableDataStore::class, DatabaseUtil::class ) );
|
||||||
$this->share( CustomOrdersTableController::class )->addArguments( array( OrdersTableDataStore::class, DataSynchronizer::class ) );
|
$this->share( CustomOrdersTableController::class )->addArguments( array( OrdersTableDataStore::class, DataSynchronizer::class ) );
|
||||||
$this->share( OrdersTableDataStore::class );
|
$this->share( OrdersTableDataStore::class );
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* UtilsClassesServiceProvider class file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Automattic\WooCommerce\Internal\DependencyManagement\ServiceProviders;
|
||||||
|
|
||||||
|
use Automattic\WooCommerce\Internal\DependencyManagement\AbstractServiceProvider;
|
||||||
|
use Automattic\WooCommerce\Internal\Utilities\DatabaseUtil;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Service provider for the non-static utils classes in the Automattic\WooCommerce\src namespace.
|
||||||
|
*/
|
||||||
|
class UtilsClassesServiceProvider extends AbstractServiceProvider {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* The classes/interfaces that are serviced by this service provider.
|
||||||
|
*
|
||||||
|
* @var array
|
||||||
|
*/
|
||||||
|
protected $provides = array(
|
||||||
|
DatabaseUtil::class,
|
||||||
|
);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Register the classes.
|
||||||
|
*/
|
||||||
|
public function register() {
|
||||||
|
$this->share( DatabaseUtil::class );
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,46 +0,0 @@
|
||||||
<?php
|
|
||||||
/**
|
|
||||||
* A class of utilities for dealing with Database management.
|
|
||||||
*/
|
|
||||||
|
|
||||||
namespace Automattic\WooCommerce\Utilities;
|
|
||||||
|
|
||||||
use Automattic\Jetpack\Constants;
|
|
||||||
|
|
||||||
class DBUtil {
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Verify if the table(s) already exists.
|
|
||||||
*
|
|
||||||
* @param string $table_creation_sql Schema definition to check against.
|
|
||||||
*
|
|
||||||
* return array List of missing tables.
|
|
||||||
*/
|
|
||||||
public static function verify_database_tables_exist( $table_creation_sql ) {
|
|
||||||
require_once( Constants::get_constant( 'ABSPATH' ) . 'wp-admin/includes/upgrade.php' );
|
|
||||||
|
|
||||||
$missing_tables = array();
|
|
||||||
$queries = dbDelta( $table_creation_sql, false );
|
|
||||||
|
|
||||||
foreach ( $queries as $table_name => $result ) {
|
|
||||||
if ( "Created table $table_name" === $result ) {
|
|
||||||
$missing_tables[] = $table_name;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return $missing_tables;
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create DB tables for passed schema. Currently a wrapper for dbDelta.
|
|
||||||
*
|
|
||||||
* @param string $table_creation_sql Table SQL
|
|
||||||
*
|
|
||||||
* @return array List of tables that we were not able to create.
|
|
||||||
*/
|
|
||||||
public static function create_database_tables( $table_creation_sql ) {
|
|
||||||
require_once( Constants::get_constant( 'ABSPATH' ) . 'wp-admin/includes/upgrade.php' );
|
|
||||||
dbDelta( $table_creation_sql );
|
|
||||||
return self::verify_database_tables_exist( $table_creation_sql );
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
|
@ -0,0 +1,72 @@
|
||||||
|
<?php
|
||||||
|
/**
|
||||||
|
* DatabaseUtil class file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
namespace Automattic\WooCommerce\Internal\Utilities;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* A class of utilities for dealing with the database.
|
||||||
|
*/
|
||||||
|
class DatabaseUtil {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Wrapper for the WordPress dbDelta function, allows to execute a series of SQL queries.
|
||||||
|
*
|
||||||
|
* @param string $queries The SQL queries to execute.
|
||||||
|
* @param bool $execute Ture to actually execute the queries, false to only simulate the execution.
|
||||||
|
* @return array The result of the execution (or simulation) from dbDelta.
|
||||||
|
*/
|
||||||
|
public function dbdelta( string $queries = '', bool $execute = true ): array {
|
||||||
|
require_once ABSPATH . 'wp-admin/includes/upgrade.php';
|
||||||
|
|
||||||
|
return dbDelta( $queries, $execute );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Given a set of table creation SQL statements, check which of the tables are currently missing in the database.
|
||||||
|
*
|
||||||
|
* @param string $creation_queries The SQL queries to execute ("CREATE TABLE" statements, same format as for dbDelta).
|
||||||
|
* @return array An array containing the names of the tables that currently don't exist in the database.
|
||||||
|
*/
|
||||||
|
public function get_missing_tables( string $creation_queries ): array {
|
||||||
|
$dbdelta_output = $this->dbdelta( $creation_queries, false );
|
||||||
|
$parsed_output = $this->parse_dbdelta_output( $dbdelta_output );
|
||||||
|
return $parsed_output['created_tables'];
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Parses the output given by dbdelta and returns information about it.
|
||||||
|
*
|
||||||
|
* @param array $dbdelta_output The output from the execution of dbdelta.
|
||||||
|
* @return array[] An array containing a 'created_tables' key whose value is an array with the names of the tables that have been (or would have been) created.
|
||||||
|
*/
|
||||||
|
public function parse_dbdelta_output( array $dbdelta_output ): array {
|
||||||
|
$created_tables = array();
|
||||||
|
|
||||||
|
foreach ( $dbdelta_output as $table_name => $result ) {
|
||||||
|
if ( "Created table $table_name" === $result ) {
|
||||||
|
$created_tables[] = $table_name;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return array( 'created_tables' => $created_tables );
|
||||||
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Drops a database table.
|
||||||
|
*
|
||||||
|
* @param string $table_name The name of the table to drop.
|
||||||
|
* @param bool $add_prefix True if the table name passed needs to be prefixed with $wpdb->prefix before processing.
|
||||||
|
*/
|
||||||
|
public function drop_database_table( string $table_name, bool $add_prefix = false ) {
|
||||||
|
global $wpdb;
|
||||||
|
|
||||||
|
if ( $add_prefix ) {
|
||||||
|
$table_name = $wpdb->prefix . $table_name;
|
||||||
|
}
|
||||||
|
|
||||||
|
//phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||||
|
$wpdb->query( "DROP TABLE IF EXISTS {$table_name}" );
|
||||||
|
}
|
||||||
|
}
|
Loading…
Reference in New Issue