Skip to content

Conversation

@Konamiman
Copy link
Contributor

All Submissions:

Changes proposed in this Pull Request:

This is a remake of #34616, which was reverted due to failing tests

Background

In this context we define a feature as a major piece of the WooCommerce functionality that can be turned on or off via code API or via admin UI. Each feature has a unique alphanumeric identifier and a standardized name for the option that turns it on or off: woocommerce_feature_{id}_enabled (the value of the option is either yes or no like any other settings related option).

A feature can be mature or experimental, the later means that the feature either is still in development or is part of an experiment that could end up being successful or not; so the idea is that ultimately all the features that at one point are marked experimental eventually either become mature or are removed.

WooCommerce plugins may declare positive compatibility or negative compatibility with any of the existing features. Positive means that to the best of the plugin authors knowledge, the plugin will continue to work as expected when the feature is enabled. Negative means that there are known issues that will arise when the plugin is used with the feature enabled.

WooCommerce had already two "features" that were provided by the Admin code: enable analytics, and enable the new navigation. In this pull request these have been repurposed as part of the new "features engine"; as an exceptional case, the old enabling option name is used for those, instead of woocommerce_feature_{id}_enabled.

New classes

This pull request introduces two new classes:

  • An internal FeaturesController class. This class has methods to:

    • Get the list of the existing features. This list is hardcoded into the class.
    • Enable or disable a given feature by id (although normally this will be done via settings UI).
    • Declare compatibility (positive or negative) of a given plugin with a given feature.
    • Get a list of the plugins that have declared compatibility with a given feature.
    • Get a list of the features for which a given plugin has declared compatibility.
    • Render the feature settings UI page (Settings - Advanced - Features), replacing the rendering that was previously done by Admin code.
  • A public FeaturesUtil class with static methods that are proxies to FeaturesController.

FeaturesController is to be retrieved via the dependency injection container as usual, FeaturesUtil can be used directly.

Declaring feature compatibility

Both FeaturesController and FeaturesUtil have a declare_compatibility method that accepts a feature id, a plugin identifier and a boolean indicating positive or negative compatibility. It's mandatory to invoke these methods from inside the before_woocommerce_init action, so that by the time woocommerce_init is fired any plugin willing to declare feature compatibility has done so already. Plugins must use the method from FeaturesUtil and not the method from FeaturesController.

The plugin identifier to be passed to FeaturesUtil::declare_compatibility must be the path of the main plugin file, this will be converted to directory/file.php which is the format used by the keys in the array returned by the WordPress get_plugins function. The FeaturesController::declare_compatibility method assumes that the plugin identifier it receives is already in this format.

Thus this is the snippet that a plugin can use to declare compatibility with a feature (assuming it runs from the main plugin file):

 add_action('before_woocommerce_init', function() {
     \Automattic\WooCommerce\Utilities\FeaturesUtil::declare_compatibility('custom_order_tables', __FILE__, true);
 });

The feature settings UI

This is how the settings page for the features looks now:

image

At first sight it might look like the only change is the addition of the "Experimental" section, but actually the changes are deeper: now the entire settings page is rendered by the FeaturesController class, and additionally, all the rendered settings are tied to options with the format woocommerce_feature_{id}_enabled. The analytics and new navigation options were previously rendered by Admin code (they keep their old names for the enabling options).

This new settings page is still compatible with the woocommerce_settings_features filter. Any settings added there will be rendered in the "mature" settings section, right after the built-in WooCommerce settings.

Compatibility with the woocommerce_admin_disabled filter is also maintained. This is how the settings page will render if this filter returns true:

image

Enabling the custom orders table feature

Previously the custom orders table feature had to be enabled via the CustomOrdersTableController::show_feature method. This is no longer the case (the new features engine is used instead), and to make this extra clear, that show_feature method will throw an exception. This method (and the companion, hide_feature) will eventually be removed once the custom orders table feature becomes mature.

Compatibility with the old Admin settings

The FeaturesController class still uses the old option names for enabling/disabling the legacy features:

  • woocommerce_analytics_enabled for enabling analytics
  • woocommerce_navigation_enabled for enabling the new navigation

The Admin code related to the features settings page rendering has been modified: the hookings to woocommerce_get_sections_advanced and woocommerce_get_settings_advanced have been removed, and the methods that were the target of those have been turned into no-ops and marked as deprecated.

The feature enabled changed action

Last but not least, a new woocommerce_feature_enabled_changed action is introduced. This is fired whenever the enabled status for a feature changes and provides the feature id and whether it has been enabled or disabled.

What's missing

Apart from the revamped settings page there are no UI changes. An indication of which plugins are compatible with which features will be introduced in a separate pull request.

Closes #34419.

How to test the changes in this Pull Request:

Compatibility with the old settings and the custom order tables feature

  1. Go to WooCommerce - Settings - Advanced - Features and verify that enabling and disabling "Analytics" and "New navigation" continues to work as expected.

  2. Also verify that the custom orders table feature is properly enabled and disabled from that page (a quite immediate indication is that the "Custom data stores" section appears or disappears from the same settings page).

Declaring compatibility

  1. Create a dummy plugin and add compatibility (positive or negative) with the custom orders table, as in the snippet shown above in "Declaring feature compatibility".

  2. From the command line, verify that you can check compatibility either by plugin name...

$ wp eval 'print_r(Automattic\WooCommerce\Utilities\FeaturesUtil::get_compatible_features_for_plugin("foobar/foobar.php"));'

Array
(
    [compatible] => Array
        (
            [0] => custom_order_tables
        )

    [incompatible] => Array
        (
        )

)

...or by feature id:

$ wp eval 'print_r(Automattic\WooCommerce\Utilities\FeaturesUtil::get_compatible_plugins_for_feature("custom_order_tables"));'

Array
(
    [compatible] => Array
        (
            [0] => foobar/foobar.php
        )

    [incompatible] => Array
        (
        )

)

Others

  1. Verify that any settings added via the woocommerce_settings_features filter are still rendered, e.g. add the following to your dummy plugin:
add_filter('woocommerce_settings_features', function($features) {
    $features[] = [
        'title' => 'Foobar',
        'desc' => 'Fizzbuzz',
        'type' => 'checkbox',
        'id' => 'woocommerce_foobuzz',
        'desc_tip' => 'Fooes the bars and fizzes the buzzs'
    ];
    return $features;
}, 10, 1);
  1. Verify that the old Admin settings are disabled when you use the woocommerce_admin_disabled filter:
add_filter('woocommerce_admin_disabled', '__return_true');

Other information:

  • Have you added an explanation of what your changes do and why you'd like us to include them?
  • Have you written new tests for your changes, as applicable?
  • Have you successfully run tests with your changes locally?
  • Have you created a changelog file for each project being changed, ie pnpm changelog add --filter=<project>?

FOR PR REVIEWER ONLY:

  • I have reviewed that everything is sanitized/escaped appropriately for any SQL or XSS injection possibilities. I made sure Linting is not ignored or disabled.

- Add the FeaturesController and FeaturesUtil classes
- Remove the old code to handle Admin related feature toggling
- Modify CustomOrdersTableController to handle the COT feature
  using the new features controller
- Add the StringUtil::plugin_name_from_plugin_file method
- Add wc_doing_it_wrong in show/hide_feature for COT
@github-actions github-actions bot added focus: react admin plugin: woocommerce Issues related to the WooCommerce Core plugin. labels Sep 19, 2022
@github-actions
Copy link
Contributor

github-actions bot commented Sep 19, 2022

Test Results Summary

Commit SHA: 7b8b11e

Test 🧪Passed ✅Failed 🚨Broken 🚧Skipped ⏭️Unknown ❔Total 📊Duration ⏱️
API Tests11800201200m 47s
E2E Tests185002018713m 11s
To view the full API test report, click here.
To view the full E2E test report, click here.
To view all test reports, visit the WooCommerce Test Reports Dashboard.

@Konamiman Konamiman marked this pull request as ready for review September 22, 2022 07:34
@Konamiman Konamiman mentioned this pull request Sep 22, 2022
5 tasks
oaratovskyi and others added 8 commits September 27, 2022 08:42
* Initial commit

* Implement APMs toggle button
- Add valid links to each APM
- Add valid link to the marketplace

* Implement APMs toggle button
- Add valid links to each APM
- Add valid link to the marketplace

* Refactor the code to be more explicit

* Delete the apm on toggle off if it's local state

* Implement FAQ simple block
- Style a notice about APM is enabled
- Add noreferrer and target=_blank to external links

* Add todo comments

* FAQ simple styling fix (improve padding)

* Fixes after inner review

* Add changelog item

* Address PR review comments

* Remove Affirm as it's not in the store

* Style fixes, proper internationalization and put valid link

* Styling fixes, translators comment, rename ApmsProps component to ApmListProps

* Two more styling fixes

* Styling fix

* Styling fix

* Remove text-decoration: none to match the design
* Skip changelog deletion if none is provided closes #34604

* Change fetch depth to 0
* Add shipping class section and dropdown

* Add comment suggestions

* Add a Spinner during shipping classes resolution
Delete changelog files for 34807

Co-authored-by: WooCommerce Bot <[email protected]>
…#34793)

(HPOS/COT) prevent user from paging beyond available range (admin list table for orders).
@Konamiman Konamiman force-pushed the add/features-controller-with-plugin-compatibility-declaration-take-2 branch from 138eadc to 057595b Compare September 27, 2022 06:46
@github-actions github-actions bot added the package: @woocommerce/data issues related to @woocommerce/data label Sep 27, 2022
@github-actions github-actions bot removed the package: @woocommerce/data issues related to @woocommerce/data label Sep 27, 2022
Copy link
Contributor

@vedanshujain vedanshujain left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

LGTM!

@Konamiman Konamiman merged commit 6e66de7 into trunk Sep 27, 2022
@Konamiman Konamiman deleted the add/features-controller-with-plugin-compatibility-declaration-take-2 branch September 27, 2022 07:26
@github-actions github-actions bot added this to the 7.1.0 milestone Sep 27, 2022
@github-actions
Copy link
Contributor

Hi @Konamiman, thanks for merging this pull request. Please take a look at these follow-up tasks you may need to perform:

  • Add the release: add testing instructions label

rodrigoprimo added a commit to mailpoet/mailpoet that referenced this pull request Oct 3, 2022
The latest version development build of WooCommerce contains a change
that modified the method that should be called to enable Woo Custom
Orders Tables (see this Woo PR for more information:
woocommerce/woocommerce#34727. This commit
update the plugin that we use in the acceptance and integration tests to
reflect this change.

[MAILPOET-4691]
costasovo pushed a commit to mailpoet/mailpoet that referenced this pull request Oct 4, 2022
The latest version development build of WooCommerce contains a change
that modified the method that should be called to enable Woo Custom
Orders Tables (see this Woo PR for more information:
woocommerce/woocommerce#34727. This commit
update the plugin that we use in the acceptance and integration tests to
reflect this change.

[MAILPOET-4691]
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

plugin: woocommerce Issues related to the WooCommerce Core plugin.

Projects

None yet

Development

Successfully merging this pull request may close these issues.

[COT] Implement compatibility API for plugins to declare incompatibility with COT

8 participants