Add initial layout for new HPOS setting.

This commit is contained in:
Vedanshu Jain 2023-06-27 18:39:11 +05:30
parent 1d04ddcd11
commit 47ca74bdcf
4 changed files with 157 additions and 47 deletions

View File

@ -11,6 +11,7 @@ use Automattic\WooCommerce\Internal\BatchProcessing\BatchProcessingController;
use Automattic\WooCommerce\Internal\Features\FeaturesController;
use Automattic\WooCommerce\Internal\Traits\AccessiblePrivateMethods;
use Automattic\WooCommerce\Utilities\OrderUtil;
use Automattic\WooCommerce\Utilities\PluginUtil;
defined( 'ABSPATH' ) || exit;
@ -98,6 +99,13 @@ class CustomOrdersTableController {
*/
private $order_cache_controller;
/**
* The plugin util object to use.
*
* @var PluginUtil
*/
private $plugin_util;
/**
* Class constructor.
*/
@ -120,6 +128,7 @@ class CustomOrdersTableController {
self::add_action( 'woocommerce_update_options_advanced_custom_data_stores', array( $this, 'process_options_updated' ), 10, 0 );
self::add_action( 'woocommerce_after_register_post_type', array( $this, 'register_post_type_for_order_placeholders' ), 10, 0 );
self::add_action( FeaturesController::FEATURE_ENABLED_CHANGED_ACTION, array( $this, 'handle_feature_enabled_changed' ), 10, 2 );
self::add_action( 'woocommerce_admin_field_hpos_setting', array( $this, 'render_hpos_setting' ), 10, 2 );
}
/**
@ -133,6 +142,7 @@ class CustomOrdersTableController {
* @param FeaturesController $features_controller The features controller instance to use.
* @param OrderCache $order_cache The order cache engine to use.
* @param OrderCacheController $order_cache_controller The order cache controller to use.
* @param PluginUtil $plugin_util The plugin util to use.
*/
final public function init(
OrdersTableDataStore $data_store,
@ -141,7 +151,9 @@ class CustomOrdersTableController {
BatchProcessingController $batch_processing_controller,
FeaturesController $features_controller,
OrderCache $order_cache,
OrderCacheController $order_cache_controller ) {
OrderCacheController $order_cache_controller,
PluginUtil $plugin_util
) {
$this->data_store = $data_store;
$this->data_synchronizer = $data_synchronizer;
$this->batch_processing_controller = $batch_processing_controller;
@ -149,6 +161,7 @@ class CustomOrdersTableController {
$this->features_controller = $features_controller;
$this->order_cache = $order_cache;
$this->order_cache_controller = $order_cache_controller;
$this->plugin_util = $plugin_util;
}
/**
@ -606,5 +619,82 @@ class CustomOrdersTableController {
);
}
/**
* Renders the HPOS setting in Features section of the settings page.
*
* @param array $value HPOS feature value as defined in the feature controller.
*/
private function render_hpos_setting( array $value ) {
$hpos_enabled = $this->custom_orders_table_usage_is_enabled();
$sync_status = $this->data_synchronizer->get_sync_status();
$sync_is_pending = 0 !== $sync_status['current_pending_count'];
$sync_in_progress = $this->batch_processing_controller->is_enqueued( get_class( $this->data_synchronizer ) );
$sync_enabled = get_option( DataSynchronizer::ORDERS_DATA_SYNC_ENABLED_OPTION );
$plugin_info = $this->features_controller->get_compatible_plugins_for_feature( 'custom_order_tables' );
$plugin_incompat_warning = $this->plugin_util->generate_incompatible_plugin_feature_warning( 'custom_order_tables', $plugin_info );
$can_hpos_enabled = count( array_merge( $plugin_info['compatible'], $plugin_info['incompatible'] ) ) === 0;
?>
<fieldset>
<tr>
<th scope="row" class="titledesc">
<?php echo esc_html( $value['title'] ); ?><br>
</th>
<td class="forminp">
<ul>
<li>
<label>
<input
type="radio"
name="<?php echo esc_attr( $value['field_name'] ); ?>"
value="post"
<?php checked( ! $hpos_enabled ); ?>
<?php disabled( $sync_is_pending ); ?>
class="<?php echo esc_attr( $value['class'] ); ?>"
/>
<?php echo esc_html( __( 'Posts table', 'woocommerce' ) ); ?>
</label>
</li>
<li>
<label>
<input
type="radio"
name="<?php echo esc_attr( $value['field_name'] ); ?>"
value="hpos"
<?php checked( $hpos_enabled ); ?>
<?php disabled( $sync_is_pending || ( ! $can_hpos_enabled ) ); ?>
class="<?php echo esc_attr( $value['class'] ); ?>"
/>
<?php echo esc_html( __( 'High Performance Order Storage (COT)', 'woocommerce' ) ); ?>
<br>
<p class="description description-thin" style="margin-top: 0.5rem;"><?php echo wp_kses_post( $plugin_incompat_warning ); ?></p>
</label>
</li>
</ul>
</td>
</tr>
<tr>
<td></td>
<td class="forminp" style="padding-top: 0px;">
<label for="<?php echo esc_attr( DataSynchronizer::ORDERS_DATA_SYNC_ENABLED_OPTION ); ?>">
<input
name="<?php echo esc_attr( DataSynchronizer::ORDERS_DATA_SYNC_ENABLED_OPTION ); ?>"
id="<?php echo esc_attr( DataSynchronizer::ORDERS_DATA_SYNC_ENABLED_OPTION ); ?>"
type="checkbox"
value="yes"
<?php checked( 'yes', $sync_enabled ); ?>
><?php echo esc_html( __( 'Keep posts and orders table in sync', 'woocommerce' ) ); ?>
</label>
</td>
</tr>
<tr>
<td></td>
<td class="forminp">
</td>
</tr>
</fieldset>
<?php
}
}

View File

@ -21,6 +21,7 @@ use Automattic\WooCommerce\Internal\DataStores\Orders\OrdersTableDataStoreMeta;
use Automattic\WooCommerce\Internal\Features\FeaturesController;
use Automattic\WooCommerce\Internal\Utilities\DatabaseUtil;
use Automattic\WooCommerce\Proxies\LegacyProxy;
use Automattic\WooCommerce\Utilities\PluginUtil;
/**
* Service provider for the classes in the Internal\DataStores\Orders namespace.
@ -69,6 +70,7 @@ class OrdersDataStoreServiceProvider extends AbstractServiceProvider {
FeaturesController::class,
OrderCache::class,
OrderCacheController::class,
PluginUtil::class,
)
);
$this->share( OrderCache::class );

View File

@ -110,10 +110,11 @@ class FeaturesController {
'disable_ui' => false,
),
'custom_order_tables' => array(
'name' => __( 'High-Performance order storage (COT)', 'woocommerce' ),
'name' => __( 'Data Storage for Orders', 'woocommerce' ),
'description' => __( 'Enable the high performance order storage feature.', 'woocommerce' ),
'is_experimental' => true,
'disable_ui' => false,
'type' => 'hpos_setting',
),
'cart_checkout_blocks' => array(
'name' => __( 'Cart & Checkout Blocks', 'woocommerce' ),
@ -611,7 +612,8 @@ class FeaturesController {
$description = $feature['description'];
$disabled = false;
$desc_tip = '';
$tooltip = isset( $feature['tooltip'] ) ? $feature['tooltip'] : '';
$tooltip = $feature['tooltip'] ?? '';
$type = $feature['type'] ?? 'checkbox';
if ( ( 'analytics' === $feature_id || 'new_navigation' === $feature_id ) && $admin_features_disabled ) {
$disabled = true;
@ -662,50 +664,9 @@ class FeaturesController {
}
if ( ! $this->is_legacy_feature( $feature_id ) && ! $disabled && $this->verify_did_woocommerce_init() ) {
$disabled = ! $this->feature_is_enabled( $feature_id );
$plugin_info_for_feature = $this->get_compatible_plugins_for_feature( $feature_id, true );
$incompatibles = array_merge( $plugin_info_for_feature['incompatible'], $plugin_info_for_feature['uncertain'] );
$incompatibles = array_filter( $incompatibles, 'is_plugin_active' );
$incompatible_count = count( $incompatibles );
if ( $incompatible_count > 0 ) {
if ( 1 === $incompatible_count ) {
/* translators: %s = printable plugin name */
$desc_tip = sprintf( __( "⚠ This feature shouldn't be enabled, the %s plugin is active and isn't compatible with it.", 'woocommerce' ), $this->plugin_util->get_plugin_name( $incompatibles[0] ) );
} elseif ( 2 === $incompatible_count ) {
/* translators: %1\$s, %2\$s = printable plugin names */
$desc_tip = sprintf(
__( "⚠ This feature shouldn't be enabled: the %1\$s and %2\$s plugins are active and aren't compatible with it.", 'woocommerce' ),
$this->plugin_util->get_plugin_name( $incompatibles[0] ),
$this->plugin_util->get_plugin_name( $incompatibles[1] )
);
} else {
/* translators: %1\$s, %2\$s = printable plugin names, %3\$d = plugins count */
$desc_tip = sprintf(
_n(
"⚠ This feature shouldn't be enabled: %1\$s, %2\$s and %3\$d more active plugin isn't compatible with it",
"⚠ This feature shouldn't be enabled: the %1\$s and %2\$s plugins are active and aren't compatible with it. There are %3\$d other incompatible plugins.",
$incompatible_count - 2,
'woocommerce'
),
$this->plugin_util->get_plugin_name( $incompatibles[0] ),
$this->plugin_util->get_plugin_name( $incompatibles[1] ),
$incompatible_count - 2
);
}
$incompatible_plugins_url = add_query_arg(
array(
'plugin_status' => 'incompatible_with_feature',
'feature_id' => $feature_id,
),
admin_url( 'plugins.php' )
);
/* translators: %s = URL of the plugins page */
$extra_desc_tip = sprintf( __( " <a href='%s'>Manage incompatible plugins</a>", 'woocommerce' ), $incompatible_plugins_url );
$desc_tip .= $extra_desc_tip;
$disabled = ! $this->feature_is_enabled( $feature_id );
}
$desc_tip = $this->plugin_util->generate_incompatible_plugin_feature_warning( $feature_id, $plugin_info_for_feature );
}
/**
@ -723,7 +684,7 @@ class FeaturesController {
return array(
'title' => $feature['name'],
'desc' => $description,
'type' => 'checkbox',
'type' => $type,
'id' => $this->feature_enable_option_name( $feature_id ),
'disabled' => $disabled && ! $this->force_allow_enabling_features,
'desc_tip' => $desc_tip,

View File

@ -171,4 +171,61 @@ class PluginUtil {
$this->woocommerce_aware_plugins = null;
$this->woocommerce_aware_active_plugins = null;
}
/**
* Util function to generate warning string for incompatible features based on active plugins.
*
* @param string $feature_id Feature id.
* @param array $plugin_feature_info Array of plugin feature info. See FeaturesControllers->get_compatible_plugins_for_feature() for details.
*
* @return string Warning string.
*/
public function generate_incompatible_plugin_feature_warning( string $feature_id, array $plugin_feature_info ) : string {
$feature_warning = '';
$incompatibles = array_merge( $plugin_feature_info['incompatible'], $plugin_feature_info['uncertain'] );
$incompatibles = array_filter( $incompatibles, 'is_plugin_active' );
$incompatible_count = count( $incompatibles );
if ( $incompatible_count > 0 ) {
if ( 1 === $incompatible_count ) {
/* translators: %s = printable plugin name */
$feature_warning = sprintf( __( '⚠ 1 Incompatible plugin detected (%s).', 'woocommerce' ), $this->get_plugin_name( $incompatibles[0] ) );
} elseif ( 2 === $incompatible_count ) {
$feature_warning = sprintf(
/* translators: %1\$s, %2\$s = printable plugin names */
__( '⚠ 2 Incompatible plugins detected (%1$s and %2$s).', 'woocommerce' ),
$this->get_plugin_name( $incompatibles[0] ),
$this->get_plugin_name( $incompatibles[1] )
);
} else {
$feature_warning = sprintf(
/* translators: %1\$s, %2\$s = printable plugin names, %3\$d = plugins count */
_n(
'⚠ Incompatible plugins detected (%1$s, %2$s and %3$d other).',
'⚠ Incompatible plugins detected (%1$s and %2$s plugins and %3$d others).',
$incompatible_count - 2,
'woocommerce'
),
$this->get_plugin_name( $incompatibles[0] ),
$this->get_plugin_name( $incompatibles[1] ),
$incompatible_count - 2
);
}
$incompatible_plugins_url = add_query_arg(
array(
'plugin_status' => 'incompatible_with_feature',
'feature_id' => $feature_id,
),
admin_url( 'plugins.php' )
);
/* translators: %s = URL of the plugins page */
$extra_desc_tip = sprintf( __( "<br><a href='%s'>View and manage</a>", 'woocommerce' ), $incompatible_plugins_url );
$feature_warning .= $extra_desc_tip;
}
return $feature_warning;
}
}