Improvements in the handling of feature compatibility for plugins (#48169)
- In the plugins list only features that are currently enabled will be considered for the list of features that are incompatible with a given plugin. - A per-feature flag named "plugins_are_incompatible_by_default" is used. Defaulting to false, when it's true for a given feature it means that plugins not declaring compatibility with a the feature are to be considered incompatible with the feature. The flag is set for the HPOS feature only. - A new 'woocommerce_plugins_are_incompatible_with_feature_by_default' filter is added, which allows to alter the flag for a given feature. - The "plugins incompatible with feature" page will display all the incompatible/uncertain plugins, even if the feature is disabled. The "plugins incompatible with ALL features" page still shows only plugins that are incompatible/uncertain with enabled features. - Add a --ignore-plugin-compatibility switch to the "wc hpos enable" command, to allow enabling even if there are incompatible plugins. - Add a new "wc hpos compatibility-info" command, which lists the plugins that are compatible/incompatible/uncertain with HPOS.
This commit is contained in:
parent
9bdd6cc45b
commit
cacb10065e
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: add
|
||||
|
||||
Improvements in the handling of feature compatibility for plugins
|
|
@ -7,6 +7,7 @@ use Automattic\WooCommerce\Internal\DataStores\Orders\DataSynchronizer;
|
|||
use Automattic\WooCommerce\Internal\DataStores\Orders\LegacyDataHandler;
|
||||
use Automattic\WooCommerce\Internal\DataStores\Orders\OrdersTableDataStore;
|
||||
use Automattic\WooCommerce\Internal\Features\FeaturesController;
|
||||
use Automattic\WooCommerce\Utilities\PluginUtil;
|
||||
use WP_CLI;
|
||||
|
||||
/**
|
||||
|
@ -76,6 +77,7 @@ class CLIRunner {
|
|||
WP_CLI::add_command( 'wc hpos status', array( $this, 'status' ) );
|
||||
WP_CLI::add_command( 'wc hpos diff', array( $this, 'diff' ) );
|
||||
WP_CLI::add_command( 'wc hpos backfill', array( $this, 'backfill' ) );
|
||||
WP_CLI::add_command( 'wc hpos compatibility-info', array( $this, 'compatibility_info' ) );
|
||||
WP_CLI::add_command( 'wc hpos compatibility-mode enable', array( $this, 'enable_compat_mode' ) );
|
||||
WP_CLI::add_command( 'wc hpos compatibility-mode disable', array( $this, 'disable_compat_mode' ) );
|
||||
|
||||
|
@ -736,6 +738,9 @@ ORDER BY $meta_table.order_id ASC, $meta_table.meta_key ASC;
|
|||
* default: false
|
||||
* ---
|
||||
*
|
||||
* [--ignore-plugin-compatibility]
|
||||
* : Enable even if there are active plugins that are incompatible with HPOS.
|
||||
*
|
||||
* ### EXAMPLES
|
||||
*
|
||||
* # Enable HPOS on new shops.
|
||||
|
@ -752,6 +757,7 @@ ORDER BY $meta_table.order_id ASC, $meta_table.meta_key ASC;
|
|||
array(
|
||||
'for-new-shop' => false,
|
||||
'with-sync' => false,
|
||||
'ignore-plugin-compatibility' => false,
|
||||
)
|
||||
);
|
||||
|
||||
|
@ -763,13 +769,19 @@ ORDER BY $meta_table.order_id ASC, $meta_table.meta_key ASC;
|
|||
WP_CLI::error( __( '[Failed] This is not a new shop, but --for-new-shop flag was passed.', 'woocommerce' ) );
|
||||
}
|
||||
|
||||
$container = wc_get_container();
|
||||
/** Feature controller instance @var FeaturesController $feature_controller */
|
||||
$feature_controller = wc_get_container()->get( FeaturesController::class );
|
||||
$plugin_info = $feature_controller->get_compatible_plugins_for_feature( 'custom_order_tables', true );
|
||||
if ( count( array_merge( $plugin_info['uncertain'], $plugin_info['incompatible'] ) ) > 0 ) {
|
||||
$feature_controller = $container->get( FeaturesController::class );
|
||||
if ( ! $assoc_args['ignore-plugin-compatibility'] ) {
|
||||
$compatibility_info = $feature_controller->get_compatible_plugins_for_feature( 'custom_order_tables', true );
|
||||
/** Plugin util instance @var PluginUtil $plugin_util */
|
||||
$plugin_util = $container->get( PluginUtil::class );
|
||||
$incompatibles = $plugin_util->get_items_considered_incompatible( 'custom_order_tables', $compatibility_info );
|
||||
if ( count( $incompatibles ) > 0 ) {
|
||||
WP_CLI::warning( __( '[Failed] Some installed plugins are incompatible. Please review the plugins by going to WooCommerce > Settings > Advanced > Features and see the "Order data storage" section.', 'woocommerce' ) );
|
||||
$enable_hpos = false;
|
||||
}
|
||||
}
|
||||
|
||||
/** DataSynchronizer instance @var DataSynchronizer $data_synchronizer */
|
||||
$data_synchronizer = wc_get_container()->get( DataSynchronizer::class );
|
||||
|
@ -1213,6 +1225,104 @@ ORDER BY $meta_table.order_id ASC, $meta_table.meta_key ASC;
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Show the list of WooCommerce-aware plugins known to be compatible, incompatible or without compatibility declaration for HPOS. Note that inactive plugins will always be listed in the "uncertain" list.
|
||||
*
|
||||
* [--include-inactive]
|
||||
* : Include inactive plugins in the list.
|
||||
*
|
||||
* [--display-filenames]
|
||||
* : Print plugin file names instead of plugin names.
|
||||
*
|
||||
* @since 9.1.0
|
||||
*
|
||||
* @param array $args Positional arguments passed to the command.
|
||||
* @param array $assoc_args Associative arguments (options) passed to the command.
|
||||
*/
|
||||
public function compatibility_info( array $args = array(), array $assoc_args = array() ): void {
|
||||
$container = wc_get_container();
|
||||
$feature_controller = $container->get( FeaturesController::class );
|
||||
$plugin_info = $feature_controller->get_compatible_plugins_for_feature( 'custom_order_tables', ! ( (bool) ( $assoc_args['include-inactive'] ?? null ) ) );
|
||||
$display_filenames = (bool) ( $assoc_args['display-filenames'] ?? null );
|
||||
|
||||
$compatibles = $this->get_printable_plugin_names( $plugin_info['compatible'], $display_filenames );
|
||||
$compatibles_count = count( $compatibles );
|
||||
$this->log(
|
||||
sprintf(
|
||||
// translators: $1$d = plugins count, %2$s = colon (if list follows) or empty.
|
||||
_n( "\n%%C%1\$d%%n compatible plugin found%2\$s", "\n%%C%1\$d%%n compatible plugins found%2\$s", $compatibles_count, 'woocommerce' ),
|
||||
$compatibles_count,
|
||||
$compatibles_count > 0 ? ":\n" : ''
|
||||
)
|
||||
);
|
||||
$this->print_plugin_names( $compatibles );
|
||||
|
||||
$incompatibles = $this->get_printable_plugin_names( $plugin_info['incompatible'], $display_filenames );
|
||||
$incompatibles_count = count( $incompatibles );
|
||||
$this->log(
|
||||
sprintf(
|
||||
// translators: $1$d = plugins count, %2$s = colon (if list follows) or empty.
|
||||
_n( "\n%%C%1\$d%%n incompatible plugin found%2\$s", "\n%%C%1\$d%%n incompatible plugins found%2\$s", $incompatibles_count, 'woocommerce' ),
|
||||
$incompatibles_count,
|
||||
$incompatibles_count > 0 ? ":\n" : ''
|
||||
)
|
||||
);
|
||||
$this->print_plugin_names( $incompatibles );
|
||||
|
||||
$uncertain = $this->get_printable_plugin_names( $plugin_info['uncertain'], $display_filenames );
|
||||
$uncertain_count = count( $uncertain );
|
||||
$this->log(
|
||||
sprintf(
|
||||
// translators: $1$d = plugins count, %2$s = colon (if list follows) or empty.
|
||||
_n( "\n%%C%1\$d%%n uncertain plugin found%2\$s", "\n%%C%1\$d%%n uncertain plugins found%2\$s", $uncertain_count, 'woocommerce' ),
|
||||
$uncertain_count,
|
||||
$uncertain_count > 0 ? ":\n" : ''
|
||||
)
|
||||
);
|
||||
$this->print_plugin_names( $uncertain );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the printable names for a set of plugins given their file names.
|
||||
*
|
||||
* @param array $plugins The plugin file names.
|
||||
* @param bool $display_filenames True to simply return the sorted list of plugin file names.
|
||||
* @return array A sorted array of plugin names or file names.
|
||||
*/
|
||||
private function get_printable_plugin_names( array $plugins, bool $display_filenames ): array {
|
||||
if ( $display_filenames ) {
|
||||
sort( $plugins );
|
||||
return $plugins;
|
||||
}
|
||||
|
||||
$plugin_names = array_map(
|
||||
fn( $plugin_file ) => get_plugin_data( WP_PLUGIN_DIR . DIRECTORY_SEPARATOR . $plugin_file, false )['Name'] ?? $plugin_file,
|
||||
$plugins
|
||||
);
|
||||
sort( $plugin_names );
|
||||
return $plugin_names;
|
||||
}
|
||||
|
||||
/**
|
||||
* Print a list of plugin names.
|
||||
*
|
||||
* @param array $plugins The names to print.
|
||||
*/
|
||||
private function print_plugin_names( array $plugins ): void {
|
||||
foreach ( $plugins as $plugin_file ) {
|
||||
$this->log( ' ' . $plugin_file );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Show a log message using the WP_CLI text colorization feature.
|
||||
*
|
||||
* @param string $text Text to show.
|
||||
*/
|
||||
private function log( string $text ) {
|
||||
WP_CLI::log( WP_CLI::colorize( $text ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables compatibility mode, which keeps the HPOS and posts datastore in sync.
|
||||
*
|
||||
|
|
|
@ -506,6 +506,7 @@ class CustomOrdersTableController {
|
|||
'enabled_by_default' => false,
|
||||
'order' => 50,
|
||||
'setting' => $this->get_hpos_setting_for_feature(),
|
||||
'plugins_are_incompatible_by_default' => true,
|
||||
'additional_settings' => array(
|
||||
$this->get_hpos_setting_for_sync(),
|
||||
),
|
||||
|
@ -544,11 +545,11 @@ class CustomOrdersTableController {
|
|||
};
|
||||
|
||||
$get_disabled = function () {
|
||||
$plugin_compatibility = $this->features_controller->get_compatible_plugins_for_feature( 'custom_order_tables', true );
|
||||
$compatibility_info = $this->features_controller->get_compatible_plugins_for_feature( 'custom_order_tables', true );
|
||||
$sync_complete = 0 === $this->data_synchronizer->get_current_orders_pending_sync_count();
|
||||
$disabled = array();
|
||||
// Changing something here? might also want to look at `enable|disable` functions in CLIRunner.
|
||||
$incompatible_plugins = array_merge( $plugin_compatibility['uncertain'], $plugin_compatibility['incompatible'] );
|
||||
// Changing something here? You might also want to look at `enable|disable` functions in Automattic\WooCommerce\DataBase\Migrations\CustomOrderTable\CLIRunner.
|
||||
$incompatible_plugins = $this->plugin_util->get_items_considered_incompatible( 'custom_order_tables', $compatibility_info );
|
||||
$incompatible_plugins = array_diff( $incompatible_plugins, $this->plugin_util->get_plugins_excluded_from_compatibility_ui() );
|
||||
if ( count( $incompatible_plugins ) > 0 ) {
|
||||
$disabled = array( 'yes' );
|
||||
|
|
|
@ -26,6 +26,8 @@ class FeaturesController {
|
|||
|
||||
public const FEATURE_ENABLED_CHANGED_ACTION = 'woocommerce_feature_enabled_changed';
|
||||
|
||||
public const PLUGINS_COMPATIBLE_BY_DEFAULT_OPTION = 'woocommerce_plugins_are_compatible_with_features_by_default';
|
||||
|
||||
/**
|
||||
* The existing feature definitions.
|
||||
*
|
||||
|
@ -146,6 +148,7 @@ class FeaturesController {
|
|||
'enabled_by_default' => false,
|
||||
'is_experimental' => true,
|
||||
'is_legacy' => false,
|
||||
'plugins_are_incompatible_by_default' => false,
|
||||
'name' => $name,
|
||||
'order' => 10,
|
||||
);
|
||||
|
@ -322,6 +325,34 @@ class FeaturesController {
|
|||
return $features;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if plugins that don't declare compatibility nor incompatibility with a given feature
|
||||
* are to be considered incompatible with that feature.
|
||||
*
|
||||
* @param string $feature_id Feature id to check.
|
||||
* @return bool True if plugins that don't declare compatibility nor incompatibility with the feature will be considered incompatible with the feature.
|
||||
* @throws \InvalidArgumentException The feature doesn't exist.
|
||||
*/
|
||||
public function get_plugins_are_incompatible_by_default( string $feature_id ): bool {
|
||||
$feature_definition = $this->get_feature_definitions()[ $feature_id ] ?? null;
|
||||
if ( is_null( $feature_definition ) ) {
|
||||
throw new \InvalidArgumentException( esc_html( "The WooCommerce feature '$feature_id' doesn't exist" ) );
|
||||
}
|
||||
|
||||
$incompatible_by_default = $feature_definition['plugins_are_incompatible_by_default'] ?? false;
|
||||
|
||||
/**
|
||||
* Filter to determine if plugins that don't declare compatibility nor incompatibility with a given feature
|
||||
* are to be considered incompatible with that feature.
|
||||
*
|
||||
* @param bool $incompatible_by_default Default value, true if plugins are to be considered incompatible by default with the feature.
|
||||
* @param string $feature_id The feature to check.
|
||||
*
|
||||
* @since 9.2.0
|
||||
*/
|
||||
return (bool) apply_filters( 'woocommerce_plugins_are_incompatible_with_feature_by_default', $incompatible_by_default, $feature_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a given feature is currently enabled.
|
||||
*
|
||||
|
@ -476,7 +507,7 @@ class FeaturesController {
|
|||
*
|
||||
* @param string $feature_id Feature id.
|
||||
* @param bool $active_only True to return only active plugins.
|
||||
* @return array An array having a 'compatible' and an 'incompatible' key, each holding an array of plugin names.
|
||||
* @return array An array having a 'compatible', an 'incompatible' and an 'uncertain' key, each holding an array of plugin names.
|
||||
*/
|
||||
public function get_compatible_plugins_for_feature( string $feature_id, bool $active_only = false ): array {
|
||||
$this->verify_did_woocommerce_init( __FUNCTION__ );
|
||||
|
@ -884,7 +915,7 @@ class FeaturesController {
|
|||
*
|
||||
* @param array $plugin_list The original list of plugins.
|
||||
*/
|
||||
private function filter_plugins_list( $plugin_list ): array {
|
||||
public function filter_plugins_list( $plugin_list ): array {
|
||||
if ( ! $this->verify_did_woocommerce_init() ) {
|
||||
return $plugin_list;
|
||||
}
|
||||
|
@ -910,10 +941,11 @@ class FeaturesController {
|
|||
*
|
||||
* @return array List of plugins incompatible with the given feature.
|
||||
*/
|
||||
private function get_incompatible_plugins( $feature_id, $plugin_list ) {
|
||||
public function get_incompatible_plugins( $feature_id, $plugin_list ) {
|
||||
$incompatibles = array();
|
||||
|
||||
$plugin_list = array_diff_key( $plugin_list, array_flip( $this->plugins_excluded_from_compatibility_ui ) );
|
||||
$feature_ids = 'all' === $feature_id ? array_keys( $this->get_feature_definitions() ) : array( $feature_id );
|
||||
$only_enabled_features = 'all' === $feature_id;
|
||||
|
||||
// phpcs:enable WordPress.Security.NonceVerification, WordPress.Security.ValidatedSanitizedInput
|
||||
foreach ( array_keys( $plugin_list ) as $plugin_name ) {
|
||||
|
@ -921,18 +953,19 @@ class FeaturesController {
|
|||
continue;
|
||||
}
|
||||
|
||||
$compatibility = $this->get_compatible_features_for_plugin( $plugin_name );
|
||||
$incompatible_with = array_filter(
|
||||
array_merge( $compatibility['incompatible'], $compatibility['uncertain'] ),
|
||||
function ( $feature_id ) {
|
||||
return ! $this->is_legacy_feature( $feature_id );
|
||||
}
|
||||
$compatibility_info = $this->get_compatible_features_for_plugin( $plugin_name );
|
||||
foreach ( $feature_ids as $feature_id ) {
|
||||
$features_considered_incompatible = array_filter(
|
||||
$this->plugin_util->get_items_considered_incompatible( $feature_id, $compatibility_info ),
|
||||
$only_enabled_features ?
|
||||
fn( $feature_id ) => $this->feature_is_enabled( $feature_id ) && ! $this->is_legacy_feature( $feature_id ) :
|
||||
fn( $feature_id ) => ! $this->is_legacy_feature( $feature_id )
|
||||
);
|
||||
|
||||
if ( ( 'all' === $feature_id && ! empty( $incompatible_with ) ) || in_array( $feature_id, $incompatible_with, true ) ) {
|
||||
if ( in_array( $feature_id, $features_considered_incompatible, true ) ) {
|
||||
$incompatibles[] = $plugin_name;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return array_intersect_key( $plugin_list, array_flip( $incompatibles ) );
|
||||
}
|
||||
|
@ -954,7 +987,7 @@ class FeaturesController {
|
|||
/**
|
||||
* Shows a warning when there are any incompatibility between active plugins and enabled features.
|
||||
* The warning is shown in on any admin screen except the plugins screen itself, since
|
||||
* there's already a "You are viewing
|
||||
* there's already a "You are viewing plugins that are incompatible" notice.
|
||||
*/
|
||||
private function maybe_display_feature_incompatibility_warning(): void {
|
||||
if ( ! current_user_can( 'activate_plugins' ) ) {
|
||||
|
@ -965,18 +998,25 @@ class FeaturesController {
|
|||
$relevant_plugins = array_diff( $this->plugin_util->get_woocommerce_aware_plugins( true ), $this->plugins_excluded_from_compatibility_ui );
|
||||
|
||||
foreach ( $relevant_plugins as $plugin ) {
|
||||
$compatibility = $this->get_compatible_features_for_plugin( $plugin, true );
|
||||
$incompatible_with = array_filter(
|
||||
array_merge( $compatibility['incompatible'], $compatibility['uncertain'] ),
|
||||
function ( $feature_id ) {
|
||||
return ! $this->is_legacy_feature( $feature_id );
|
||||
}
|
||||
);
|
||||
$compatibility_info = $this->get_compatible_features_for_plugin( $plugin, true );
|
||||
|
||||
if ( $incompatible_with ) {
|
||||
$incompatibles = array_filter( $compatibility_info['incompatible'], fn( $feature_id ) => ! $this->is_legacy_feature( $feature_id ) );
|
||||
if ( ! empty( $incompatibles ) ) {
|
||||
$incompatible_plugins = true;
|
||||
break;
|
||||
}
|
||||
|
||||
$uncertains = array_filter( $compatibility_info['uncertain'], fn( $feature_id ) => ! $this->is_legacy_feature( $feature_id ) );
|
||||
foreach ( $uncertains as $feature_id ) {
|
||||
if ( $this->get_plugins_are_incompatible_by_default( $feature_id ) ) {
|
||||
$incompatible_plugins = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $incompatible_plugins ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( ! $incompatible_plugins ) {
|
||||
|
|
|
@ -5,6 +5,7 @@
|
|||
|
||||
namespace Automattic\WooCommerce\Utilities;
|
||||
|
||||
use Automattic\WooCommerce\Internal\Features\FeaturesController;
|
||||
use Automattic\WooCommerce\Internal\Traits\AccessiblePrivateMethods;
|
||||
use Automattic\WooCommerce\Internal\Utilities\PluginInstaller;
|
||||
use Automattic\WooCommerce\Proxies\LegacyProxy;
|
||||
|
@ -189,13 +190,12 @@ class PluginUtil {
|
|||
* the Legacy REST API and HPOS are active.
|
||||
*
|
||||
* @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.
|
||||
* @param array $plugin_feature_info Array of plugin feature info, as provided by FeaturesController->get_compatible_plugins_for_feature().
|
||||
*
|
||||
* @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 = $this->get_items_considered_incompatible( $feature_id, $plugin_feature_info );
|
||||
$incompatibles = array_filter( $incompatibles, 'is_plugin_active' );
|
||||
$incompatibles = array_values( array_diff( $incompatibles, $this->get_plugins_excluded_from_compatibility_ui() ) );
|
||||
$incompatible_count = count( $incompatibles );
|
||||
|
@ -268,6 +268,7 @@ class PluginUtil {
|
|||
),
|
||||
admin_url( 'plugins.php' )
|
||||
);
|
||||
|
||||
$feature_warnings[] = sprintf(
|
||||
/* translators: %1$s opening link tag %2$s closing link tag. */
|
||||
__( '%1$sView and manage%2$s', 'woocommerce' ),
|
||||
|
@ -279,6 +280,23 @@ class PluginUtil {
|
|||
return str_replace( "\n", '<br>', implode( "\n", $feature_warnings ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter plugin/feature compatibility info, returning the names of the plugins/features that are considered incompatible.
|
||||
* "Uncertain" information will be included or not depending on the value of the value of the 'plugins_are_incompatible_by_default'
|
||||
* flag in the feature definition (default is true).
|
||||
*
|
||||
* @param string $feature_id Feature id.
|
||||
* @param array $compatibility_info Array containing "compatible', 'incompatible' and 'uncertain' keys.
|
||||
* @return array Items in 'incompatible' and 'uncertain' if plugins are incompatible by default with the feature; only items in 'incompatible' otherwise.
|
||||
*/
|
||||
public function get_items_considered_incompatible( string $feature_id, array $compatibility_info ): array {
|
||||
$incompatible_by_default = wc_get_container()->get( FeaturesController::class )->get_plugins_are_incompatible_by_default( $feature_id );
|
||||
|
||||
return $incompatible_by_default ?
|
||||
array_merge( $compatibility_info['incompatible'], $compatibility_info['uncertain'] ) :
|
||||
$compatibility_info['incompatible'];
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the names of the plugins that are excluded from the feature compatibility UI.
|
||||
* These plugins won't be considered as incompatible with any existing feature for the purposes
|
||||
|
|
|
@ -799,7 +799,7 @@ class FeaturesControllerTest extends \WC_Unit_Test_Case {
|
|||
*/
|
||||
public function test_no_warning_when_all_plugin_are_hpos_compatible() {
|
||||
$this->simulate_inside_before_woocommerce_init_hook();
|
||||
// phpcs:disable Squiz.Commenting
|
||||
// phpcs:disable Squiz.Commenting, Generic.CodeAnalysis.UnusedFunctionParameter.Found
|
||||
$fake_plugin_util = new class() extends PluginUtil {
|
||||
private $active_plugins;
|
||||
|
||||
|
@ -826,7 +826,7 @@ class FeaturesControllerTest extends \WC_Unit_Test_Case {
|
|||
},
|
||||
)
|
||||
);
|
||||
// phpcs:enable
|
||||
// phpcs:enable Squiz.Commenting, Generic.CodeAnalysis.UnusedFunctionParameter.Found
|
||||
|
||||
$local_sut = new FeaturesController();
|
||||
|
||||
|
@ -884,10 +884,15 @@ class FeaturesControllerTest extends \WC_Unit_Test_Case {
|
|||
|
||||
/**
|
||||
* @testDox If there is an incompatible plugin, it is returned by get_incompatible_plugins.
|
||||
*
|
||||
* @testWith [true]
|
||||
* [false]
|
||||
*
|
||||
* @param bool $hpos_is_enabled True to test with HPOS enabled, false to test with HPOS disabled.
|
||||
*/
|
||||
public function test_show_warning_when_a_plugin_is_not_hpos_compatible() {
|
||||
public function test_show_warning_when_a_plugin_is_not_hpos_compatible_if_hpos_is_enabled( bool $hpos_is_enabled ) {
|
||||
$this->simulate_inside_before_woocommerce_init_hook();
|
||||
// phpcs:disable Squiz.Commenting
|
||||
// phpcs:disable Squiz.Commenting, Generic.CodeAnalysis.UnusedFunctionParameter.Found
|
||||
$fake_plugin_util = new class() extends PluginUtil {
|
||||
private $active_plugins;
|
||||
|
||||
|
@ -906,7 +911,6 @@ class FeaturesControllerTest extends \WC_Unit_Test_Case {
|
|||
return array();
|
||||
}
|
||||
};
|
||||
// phpcs:enable
|
||||
|
||||
$this->register_legacy_proxy_function_mocks(
|
||||
array(
|
||||
|
@ -915,8 +919,10 @@ class FeaturesControllerTest extends \WC_Unit_Test_Case {
|
|||
},
|
||||
)
|
||||
);
|
||||
// phpcs:enable Squiz.Commenting, Generic.CodeAnalysis.UnusedFunctionParameter.Found
|
||||
|
||||
$local_sut = new FeaturesController();
|
||||
$local_sut->change_feature_enable( 'custom_order_tables', $hpos_is_enabled );
|
||||
|
||||
add_action(
|
||||
'woocommerce_register_feature_definitions',
|
||||
|
@ -926,8 +932,10 @@ class FeaturesControllerTest extends \WC_Unit_Test_Case {
|
|||
$features = array(
|
||||
'custom_order_tables' => array(
|
||||
'name' => __( 'High-Performance order storage', 'woocommerce' ),
|
||||
'is_experimental' => true,
|
||||
'is_experimental' => false,
|
||||
'enabled_by_default' => false,
|
||||
'option_key' => CustomOrdersTableController::CUSTOM_ORDERS_TABLE_USAGE_ENABLED_OPTION,
|
||||
'plugins_are_incompatible_by_default' => true,
|
||||
),
|
||||
'cart_checkout_blocks' => array(
|
||||
'name' => __( 'Cart & Checkout Blocks', 'woocommerce' ),
|
||||
|
@ -966,6 +974,8 @@ class FeaturesControllerTest extends \WC_Unit_Test_Case {
|
|||
$incompatible_plugins = function () use ( $plugins ) {
|
||||
return $this->get_incompatible_plugins( 'all', array_flip( $plugins ) );
|
||||
};
|
||||
$this->assertEquals( array( 'incompatible_plugin' ), array_keys( $incompatible_plugins->call( $local_sut ) ) );
|
||||
|
||||
$expected = $hpos_is_enabled ? array( 'incompatible_plugin' ) : array();
|
||||
$this->assertEquals( $expected, array_keys( $incompatible_plugins->call( $local_sut ) ) );
|
||||
}
|
||||
}
|
||||
|
|
|
@ -2,6 +2,8 @@
|
|||
|
||||
namespace Automattic\WooCommerce\Tests\Utilities;
|
||||
|
||||
use Automattic\WooCommerce\Internal\DataStores\Orders\CustomOrdersTableController;
|
||||
use Automattic\WooCommerce\Internal\Features\FeaturesController;
|
||||
use Automattic\WooCommerce\Utilities\PluginUtil;
|
||||
use Automattic\WooCommerce\Utilities\StringUtil;
|
||||
|
||||
|
@ -123,7 +125,7 @@ class PluginUtilTests extends \WC_Unit_Test_Case {
|
|||
$this->reset_legacy_proxy_mocks();
|
||||
$this->register_legacy_proxy_function_mocks(
|
||||
array(
|
||||
'get_plugins' => function() {
|
||||
'get_plugins' => function () {
|
||||
return array(
|
||||
'woocommerce/woocommerce.php' => array( 'WC tested up to' => '1.0' ),
|
||||
'jetpack/jetpack.php' => array( 'foo' => 'bar' ),
|
||||
|
@ -133,13 +135,13 @@ class PluginUtilTests extends \WC_Unit_Test_Case {
|
|||
)
|
||||
);
|
||||
|
||||
// Unix style
|
||||
// Unix style.
|
||||
$this->assertEquals( 'woocommerce/woocommerce.php', $this->sut->get_wp_plugin_id( 'woocommerce/woocommerce.php' ) );
|
||||
$this->assertEquals( 'woocommerce/woocommerce.php', $this->sut->get_wp_plugin_id( '6.9.2/woocommerce.php' ) );
|
||||
$this->assertEquals( 'woocommerce/woocommerce.php', $this->sut->get_wp_plugin_id( '/srv/htdocs/woocommerce/latest/woocommerce.php' ) );
|
||||
$this->assertEquals( 'woocommerce/woocommerce.php', $this->sut->get_wp_plugin_id( '../../../../wordpress/plugins/woocommerce/latest/woocommerce.php' ) );
|
||||
|
||||
// Windows style
|
||||
// Windows style.
|
||||
$this->assertEquals( 'woocommerce/woocommerce.php', $this->sut->get_wp_plugin_id( 'woocommerce\\woocommerce.php' ) );
|
||||
$this->assertEquals( 'woocommerce/woocommerce.php', $this->sut->get_wp_plugin_id( '6.9.2\\woocommerce.php' ) );
|
||||
$this->assertEquals( 'woocommerce/woocommerce.php', $this->sut->get_wp_plugin_id( 'D:\\WordPress\\plugins\\woocommerce\\6.9.2\\woocommerce.php' ) );
|
||||
|
@ -155,7 +157,7 @@ class PluginUtilTests extends \WC_Unit_Test_Case {
|
|||
private function mock_plugin_functions() {
|
||||
$this->register_legacy_proxy_function_mocks(
|
||||
array(
|
||||
'get_plugins' => function() {
|
||||
'get_plugins' => function () {
|
||||
return array(
|
||||
'woo_aware_1' => array( 'WC tested up to' => '1.0' ),
|
||||
'woo_aware_2' => array( 'WC tested up to' => '2.0' ),
|
||||
|
@ -164,10 +166,10 @@ class PluginUtilTests extends \WC_Unit_Test_Case {
|
|||
'not_woo_aware_2' => array( 'foo' => 'bar' ),
|
||||
);
|
||||
},
|
||||
'is_plugin_active' => function( $plugin_name ) {
|
||||
'is_plugin_active' => function ( $plugin_name ) {
|
||||
return 'woo_aware_3' !== $plugin_name;
|
||||
},
|
||||
'get_plugin_data' => function( $plugin_name ) {
|
||||
'get_plugin_data' => function ( $plugin_name ) {
|
||||
return StringUtil::ends_with( $plugin_name, 'woo_aware_1' ) ?
|
||||
array(
|
||||
'WC tested up to' => '1.0',
|
||||
|
@ -178,4 +180,76 @@ class PluginUtilTests extends \WC_Unit_Test_Case {
|
|||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* @testdox Test the `get_items_considered_incompatible` method.
|
||||
*/
|
||||
public function test_get_items_considered_incompatible() {
|
||||
$this->reset_container_resolutions();
|
||||
|
||||
add_action(
|
||||
'woocommerce_register_feature_definitions',
|
||||
function ( $features_controller ) {
|
||||
$features = array(
|
||||
'test_feature_1' => array(
|
||||
'name' => 'Test feature 1',
|
||||
'plugins_are_incompatible_by_default' => true,
|
||||
),
|
||||
'test_feature_2' => array(
|
||||
'name' => 'Test feature 2',
|
||||
'plugins_are_incompatible_by_default' => false,
|
||||
),
|
||||
'test_feature_3' => array(
|
||||
'name' => 'Test feature 2',
|
||||
),
|
||||
);
|
||||
|
||||
foreach ( $features as $slug => $definition ) {
|
||||
$features_controller->add_feature_definition( $slug, $definition['name'], $definition );
|
||||
}
|
||||
},
|
||||
20
|
||||
);
|
||||
|
||||
$plugin_compatibility_info = array(
|
||||
'compatible' => array(
|
||||
'compatible_1.php',
|
||||
'compatible_2.php',
|
||||
),
|
||||
'incompatible' => array(
|
||||
'incompatible_1.php',
|
||||
'incompatible_2.php',
|
||||
),
|
||||
'uncertain' => array(
|
||||
'uncertain_1.php',
|
||||
'uncertain_2.php',
|
||||
),
|
||||
);
|
||||
|
||||
$expected = array(
|
||||
'incompatible_1.php',
|
||||
'incompatible_2.php',
|
||||
'uncertain_1.php',
|
||||
'uncertain_2.php',
|
||||
);
|
||||
|
||||
$actual = $this->sut->get_items_considered_incompatible( 'test_feature_1', $plugin_compatibility_info );
|
||||
|
||||
sort( $actual );
|
||||
sort( $expected );
|
||||
$this->assertEquals( $expected, $actual );
|
||||
|
||||
$expected = array(
|
||||
'incompatible_1.php',
|
||||
'incompatible_2.php',
|
||||
);
|
||||
|
||||
$actual = $this->sut->get_items_considered_incompatible( 'test_feature_2', $plugin_compatibility_info );
|
||||
sort( $actual );
|
||||
$this->assertEquals( $expected, $actual );
|
||||
|
||||
$actual = $this->sut->get_items_considered_incompatible( 'test_feature_3', $plugin_compatibility_info );
|
||||
sort( $actual );
|
||||
$this->assertEquals( $expected, $actual );
|
||||
}
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue