Disable features on tracking opt out (https://github.com/woocommerce/woocommerce-admin/pull/6075)
* Separate features into Features class * Fix Loader references * Move option to TOGGLE_OPTION_NAME constant * Disable features on tracking opt out * Remove errant classes * Create array of beta features in Features class * Update method names for exists and enabled * Only load enabled features client-side
This commit is contained in:
parent
716982adee
commit
c98e3ca343
|
@ -0,0 +1,304 @@
|
|||
<?php
|
||||
/**
|
||||
* Features loader for features developed in WooCommerce Admin.
|
||||
*/
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\Features;
|
||||
|
||||
use Automattic\WooCommerce\Admin\Loader;
|
||||
|
||||
/**
|
||||
* Features Class.
|
||||
*/
|
||||
class Features {
|
||||
/**
|
||||
* Class instance.
|
||||
*
|
||||
* @var Loader instance
|
||||
*/
|
||||
protected static $instance = null;
|
||||
|
||||
/**
|
||||
* Get class instance.
|
||||
*/
|
||||
public static function get_instance() {
|
||||
if ( ! self::$instance ) {
|
||||
self::$instance = new self();
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
// Load feature before WooCommerce update hooks.
|
||||
add_action( 'init', array( __CLASS__, 'load_features' ), 4 );
|
||||
add_filter( 'woocommerce_get_sections_advanced', array( __CLASS__, 'add_features_section' ) );
|
||||
add_filter( 'woocommerce_get_settings_advanced', array( __CLASS__, 'add_features_settings' ), 10, 2 );
|
||||
add_filter( 'woocommerce_get_settings_advanced', array( __CLASS__, 'maybe_load_beta_features_modal' ), 10, 2 );
|
||||
add_action( 'admin_enqueue_scripts', array( __CLASS__, 'load_scripts' ), 15 );
|
||||
add_filter( 'admin_body_class', array( __CLASS__, 'add_admin_body_classes' ) );
|
||||
add_filter( 'update_option_woocommerce_allow_tracking', array( __CLASS__, 'maybe_disable_features' ), 10, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets a build configured array of enabled WooCommerce Admin features/sections.
|
||||
*
|
||||
* @return array Enabled Woocommerce Admin features/sections.
|
||||
*/
|
||||
public static function get_features() {
|
||||
return apply_filters( 'woocommerce_admin_features', array() );
|
||||
}
|
||||
|
||||
/**
|
||||
* Gets the beta feature options as an associative array that can be toggled on or off.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_beta_feature_options() {
|
||||
$features = [];
|
||||
|
||||
$navigation_class = self::get_feature_class( 'navigation' );
|
||||
if ( $navigation_class ) {
|
||||
$features['navigation'] = $navigation_class::TOGGLE_OPTION_NAME;
|
||||
}
|
||||
|
||||
return $features;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns if a specific wc-admin feature exists in the current environment.
|
||||
*
|
||||
* @param string $feature Feature slug.
|
||||
* @return bool Returns true if the feature exists.
|
||||
*/
|
||||
public static function exists( $feature ) {
|
||||
$features = self::get_features();
|
||||
return in_array( $feature, $features, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the feature class as a string.
|
||||
*
|
||||
* @param string $feature Feature name.
|
||||
* @return string|null
|
||||
*/
|
||||
public static function get_feature_class( $feature ) {
|
||||
$feature = str_replace( '-', '', ucwords( strtolower( $feature ), '-' ) );
|
||||
$feature_class = 'Automattic\\WooCommerce\\Admin\\Features\\' . $feature;
|
||||
|
||||
if ( class_exists( $feature_class ) ) {
|
||||
return $feature_class;
|
||||
}
|
||||
|
||||
// Handle features contained in subdirectory.
|
||||
if ( class_exists( $feature_class . '\\Init' ) ) {
|
||||
return $feature_class . '\\Init';
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class loader for enabled WooCommerce Admin features/sections.
|
||||
*/
|
||||
public static function load_features() {
|
||||
$features = self::get_features();
|
||||
foreach ( $features as $feature ) {
|
||||
$feature_class = self::get_feature_class( $feature );
|
||||
|
||||
if ( $feature_class ) {
|
||||
new $feature_class();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a feature is enabled. Defaults to true for all features unless they are in beta.
|
||||
*
|
||||
* @param string $feature Feature slug.
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_enabled( $feature ) {
|
||||
if ( ! self::exists( $feature ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$features = self::get_beta_feature_options();
|
||||
|
||||
if ( isset( $features[ $feature ] ) ) {
|
||||
return 'yes' === get_option( $features[ $feature ], 'no' );
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable a toggleable beta feature.
|
||||
*
|
||||
* @param string $feature Feature name.
|
||||
* @return bool
|
||||
*/
|
||||
public static function disable( $feature ) {
|
||||
$features = self::get_beta_feature_options();
|
||||
|
||||
if ( isset( $features[ $feature ] ) ) {
|
||||
update_option( $features[ $feature ], 'no' );
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Disable features when opting out of tracking.
|
||||
*
|
||||
* @param string $old_value Old value.
|
||||
* @param string $value New value.
|
||||
*/
|
||||
public static function maybe_disable_features( $old_value, $value ) {
|
||||
if ( 'yes' === $value ) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( self::get_features() as $feature ) {
|
||||
self::disable( $feature );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the Features section to the advanced tab of WooCommerce Settings
|
||||
*
|
||||
* @param array $sections Sections.
|
||||
* @return array
|
||||
*/
|
||||
public static function add_features_section( $sections ) {
|
||||
$features = apply_filters(
|
||||
'woocommerce_settings_features',
|
||||
array()
|
||||
);
|
||||
|
||||
if ( empty( $features ) ) {
|
||||
return $sections;
|
||||
}
|
||||
|
||||
$sections['features'] = __( 'Features', 'woocommerce-admin' );
|
||||
return $sections;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the Features settings.
|
||||
*
|
||||
* @param array $settings Settings.
|
||||
* @param string $current_section Current section slug.
|
||||
* @return array
|
||||
*/
|
||||
public static function add_features_settings( $settings, $current_section ) {
|
||||
if ( 'features' !== $current_section ) {
|
||||
return $settings;
|
||||
}
|
||||
|
||||
$features = apply_filters(
|
||||
'woocommerce_settings_features',
|
||||
array()
|
||||
);
|
||||
|
||||
if ( empty( $features ) ) {
|
||||
return $settings;
|
||||
}
|
||||
|
||||
return array_merge(
|
||||
array(
|
||||
array(
|
||||
'title' => __( 'Features', 'woocommerce-admin' ),
|
||||
'type' => 'title',
|
||||
'desc' => __( 'Start using new features that are being progressively rolled out to improve the store management experience.', 'woocommerce-admin' ),
|
||||
'id' => 'features_options',
|
||||
),
|
||||
),
|
||||
$features,
|
||||
array(
|
||||
array(
|
||||
'type' => 'sectionend',
|
||||
'id' => 'features_options',
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Conditionally loads the beta features tracking modal.
|
||||
*
|
||||
* @param array $settings Settings.
|
||||
* @return array
|
||||
*/
|
||||
public static function maybe_load_beta_features_modal( $settings ) {
|
||||
$tracking_enabled = get_option( 'woocommerce_allow_tracking', 'no' );
|
||||
|
||||
if ( 'yes' === $tracking_enabled ) {
|
||||
return $settings;
|
||||
}
|
||||
|
||||
$rtl = is_rtl() ? '.rtl' : '';
|
||||
|
||||
wp_enqueue_style(
|
||||
'wc-admin-beta-features-tracking-modal',
|
||||
Loader::get_url( "beta-features-tracking-modal/style{$rtl}", 'css' ),
|
||||
array( 'wp-components' ),
|
||||
Loader::get_file_version( 'css' )
|
||||
);
|
||||
|
||||
wp_enqueue_script(
|
||||
'wc-admin-beta-features-tracking-modal',
|
||||
Loader::get_url( 'wp-admin-scripts/beta-features-tracking-modal', 'js' ),
|
||||
array( 'wp-i18n', 'wp-element', WC_ADMIN_APP ),
|
||||
Loader::get_file_version( 'js' ),
|
||||
true
|
||||
);
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Loads the required scripts on the correct pages.
|
||||
*/
|
||||
public static function load_scripts() {
|
||||
if ( ! Loader::is_admin_or_embed_page() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( ! Loader::user_can_analytics() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$features = self::get_features();
|
||||
$enabled_features = array();
|
||||
foreach ( $features as $key ) {
|
||||
$enabled_features[ $key ] = self::is_enabled( $key );
|
||||
}
|
||||
wp_add_inline_script( WC_ADMIN_APP, 'window.wcAdminFeatures = ' . wp_json_encode( $enabled_features ), 'before' );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Adds body classes to the main wp-admin wrapper, allowing us to better target elements in specific scenarios.
|
||||
*
|
||||
* @param string $admin_body_class Body class to add.
|
||||
*/
|
||||
public static function add_admin_body_classes( $admin_body_class = '' ) {
|
||||
if ( ! Loader::is_admin_or_embed_page() ) {
|
||||
return $admin_body_class;
|
||||
}
|
||||
|
||||
$classes = explode( ' ', trim( $admin_body_class ) );
|
||||
|
||||
$features = self::get_features();
|
||||
foreach ( $features as $feature_key ) {
|
||||
$classes[] = sanitize_html_class( 'woocommerce-feature-enabled-' . $feature_key );
|
||||
}
|
||||
|
||||
$admin_body_class = implode( ' ', array_unique( $classes ) );
|
||||
return " $admin_body_class ";
|
||||
}
|
||||
}
|
|
@ -17,6 +17,11 @@ use Automattic\WooCommerce\Admin\Features\Navigation\CoreMenu;
|
|||
* Contains logic for the Navigation
|
||||
*/
|
||||
class Init {
|
||||
/**
|
||||
* Option name used to toggle this feature.
|
||||
*/
|
||||
const TOGGLE_OPTION_NAME = 'woocommerce_navigation_enabled';
|
||||
|
||||
/**
|
||||
* Hook into WooCommerce.
|
||||
*/
|
||||
|
@ -24,7 +29,7 @@ class Init {
|
|||
add_filter( 'woocommerce_settings_features', array( $this, 'add_feature_toggle' ) );
|
||||
add_filter( 'woocommerce_admin_preload_options', array( $this, 'preload_options' ) );
|
||||
add_filter( 'woocommerce_admin_features', array( $this, 'maybe_remove_nav_feature' ), 0 );
|
||||
add_action( 'update_option_woocommerce_navigation_enabled', array( $this, 'reload_page_on_toggle' ), 10, 2 );
|
||||
add_action( 'update_option_' . self::TOGGLE_OPTION_NAME, array( $this, 'reload_page_on_toggle' ), 10, 2 );
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'maybe_enqueue_opt_out_scripts' ) );
|
||||
|
||||
if ( Loader::is_feature_enabled( 'navigation' ) ) {
|
||||
|
@ -63,7 +68,7 @@ class Init {
|
|||
$features[] = array(
|
||||
'title' => __( 'Navigation', 'woocommerce-admin' ),
|
||||
'desc' => $description . $update_text,
|
||||
'id' => 'woocommerce_navigation_enabled',
|
||||
'id' => self::TOGGLE_OPTION_NAME,
|
||||
'type' => 'checkbox',
|
||||
'class' => $needs_update ? 'disabled' : '',
|
||||
);
|
||||
|
@ -106,7 +111,7 @@ class Init {
|
|||
*/
|
||||
public function maybe_remove_nav_feature( $features ) {
|
||||
$has_feature_enabled = in_array( 'navigation', $features, true );
|
||||
$has_option_disabled = 'yes' !== get_option( 'woocommerce_navigation_enabled', 'no' );
|
||||
$has_option_disabled = 'yes' !== get_option( self::TOGGLE_OPTION_NAME, 'no' );
|
||||
$is_not_compatible = ! self::is_nav_compatible();
|
||||
|
||||
if ( ( $has_feature_enabled && $has_option_disabled ) || $is_not_compatible ) {
|
||||
|
@ -122,7 +127,7 @@ class Init {
|
|||
* @return array
|
||||
*/
|
||||
public function preload_options( $options ) {
|
||||
$options[] = 'woocommerce_navigation_enabled';
|
||||
$options[] = self::TOGGLE_OPTION_NAME;
|
||||
|
||||
return $options;
|
||||
}
|
||||
|
|
|
@ -7,9 +7,9 @@
|
|||
namespace Automattic\WooCommerce\Admin;
|
||||
|
||||
use \_WP_Dependency;
|
||||
use Automattic\WooCommerce\Admin\Features\Onboarding;
|
||||
use Automattic\WooCommerce\Admin\API\Reports\Orders\DataStore as OrdersDataStore;
|
||||
use Automattic\WooCommerce\Admin\API\Plugins;
|
||||
use Automattic\WooCommerce\Admin\Features\Features;
|
||||
use Automattic\WooCommerce\Admin\Features\Navigation\Screen;
|
||||
use WC_Marketplace_Suggestions;
|
||||
|
||||
|
@ -58,12 +58,8 @@ class Loader {
|
|||
* Hooks added here should be removed in `wc_admin_initialize` via the feature plugin.
|
||||
*/
|
||||
public function __construct() {
|
||||
Features::get_instance();
|
||||
add_action( 'init', array( __CLASS__, 'define_tables' ) );
|
||||
// Load feature before WooCommerce update hooks.
|
||||
add_action( 'init', array( __CLASS__, 'load_features' ), 4 );
|
||||
add_filter( 'woocommerce_get_sections_advanced', array( __CLASS__, 'add_features_section' ) );
|
||||
add_filter( 'woocommerce_get_settings_advanced', array( __CLASS__, 'add_features_settings' ), 10, 2 );
|
||||
add_filter( 'woocommerce_get_settings_advanced', array( __CLASS__, 'maybe_load_beta_features_modal' ), 10, 2 );
|
||||
add_action( 'admin_enqueue_scripts', array( __CLASS__, 'register_scripts' ) );
|
||||
add_action( 'admin_enqueue_scripts', array( __CLASS__, 'inject_wc_settings_dependencies' ), 14 );
|
||||
add_action( 'admin_enqueue_scripts', array( __CLASS__, 'load_scripts' ), 15 );
|
||||
|
@ -140,9 +136,11 @@ class Loader {
|
|||
* Gets a build configured array of enabled WooCommerce Admin features/sections.
|
||||
*
|
||||
* @return array Enabled Woocommerce Admin features/sections.
|
||||
*
|
||||
* @deprecated since 1.9.0, use Features::get_features()
|
||||
*/
|
||||
public static function get_features() {
|
||||
return apply_filters( 'woocommerce_admin_features', array() );
|
||||
return Features::get_features();
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -176,10 +174,11 @@ class Loader {
|
|||
*
|
||||
* @param string $feature Feature slug.
|
||||
* @return bool Returns true if the feature is enabled.
|
||||
*
|
||||
* @deprecated since 1.9.0, use Features::exists( $feature )
|
||||
*/
|
||||
public static function is_feature_enabled( $feature ) {
|
||||
$features = self::get_features();
|
||||
return in_array( $feature, $features, true );
|
||||
return Features::exists( $feature );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -190,7 +189,7 @@ class Loader {
|
|||
*/
|
||||
public static function should_use_minified_js_file( $script_debug ) {
|
||||
// minified files are only shipped in non-core versions of wc-admin, return false if minified files are not available.
|
||||
if ( ! self::is_feature_enabled( 'minified-js' ) ) {
|
||||
if ( ! Features::exists( 'minified-js' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
|
@ -240,119 +239,6 @@ class Loader {
|
|||
return ( 'css' === $ext ) ? WC_ADMIN_DIST_CSS_FOLDER : WC_ADMIN_DIST_JS_FOLDER;
|
||||
}
|
||||
|
||||
/**
|
||||
* Class loader for enabled WooCommerce Admin features/sections.
|
||||
*/
|
||||
public static function load_features() {
|
||||
$features = self::get_features();
|
||||
foreach ( $features as $feature ) {
|
||||
$feature = str_replace( '-', '', ucwords( strtolower( $feature ), '-' ) );
|
||||
$feature_class = 'Automattic\\WooCommerce\\Admin\\Features\\' . $feature;
|
||||
|
||||
// Handle features contained in subdirectory.
|
||||
if ( ! class_exists( $feature_class ) && class_exists( $feature_class . '\\Init' ) ) {
|
||||
$feature_class = $feature_class . '\\Init';
|
||||
}
|
||||
|
||||
if ( class_exists( $feature_class ) ) {
|
||||
new $feature_class();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the Features section to the advanced tab of WooCommerce Settings
|
||||
*
|
||||
* @param array $sections Sections.
|
||||
* @return array
|
||||
*/
|
||||
public static function add_features_section( $sections ) {
|
||||
$features = apply_filters(
|
||||
'woocommerce_settings_features',
|
||||
array()
|
||||
);
|
||||
|
||||
if ( empty( $features ) ) {
|
||||
return $sections;
|
||||
}
|
||||
|
||||
$sections['features'] = __( 'Features', 'woocommerce-admin' );
|
||||
return $sections;
|
||||
}
|
||||
|
||||
/**
|
||||
* Conditionally loads the beta features tracking modal.
|
||||
*
|
||||
* @param array $settings Settings.
|
||||
* @return array
|
||||
*/
|
||||
public static function maybe_load_beta_features_modal( $settings ) {
|
||||
$tracking_enabled = get_option( 'woocommerce_allow_tracking', 'no' );
|
||||
|
||||
if ( 'yes' === $tracking_enabled ) {
|
||||
return $settings;
|
||||
}
|
||||
|
||||
$rtl = is_rtl() ? '.rtl' : '';
|
||||
|
||||
wp_enqueue_style(
|
||||
'wc-admin-beta-features-tracking-modal',
|
||||
self::get_url( "beta-features-tracking-modal/style{$rtl}", 'css' ),
|
||||
array( 'wp-components' ),
|
||||
self::get_file_version( 'css' )
|
||||
);
|
||||
|
||||
wp_enqueue_script(
|
||||
'wc-admin-beta-features-tracking-modal',
|
||||
self::get_url( 'wp-admin-scripts/beta-features-tracking-modal', 'js' ),
|
||||
array( 'wp-i18n', 'wp-element', WC_ADMIN_APP ),
|
||||
self::get_file_version( 'js' ),
|
||||
true
|
||||
);
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the Features settings.
|
||||
*
|
||||
* @param array $settings Settings.
|
||||
* @param string $current_section Current section slug.
|
||||
* @return array
|
||||
*/
|
||||
public static function add_features_settings( $settings, $current_section ) {
|
||||
if ( 'features' !== $current_section ) {
|
||||
return $settings;
|
||||
}
|
||||
|
||||
$features = apply_filters(
|
||||
'woocommerce_settings_features',
|
||||
array()
|
||||
);
|
||||
|
||||
if ( empty( $features ) ) {
|
||||
return $settings;
|
||||
}
|
||||
|
||||
return array_merge(
|
||||
array(
|
||||
array(
|
||||
'title' => __( 'Features', 'woocommerce-admin' ),
|
||||
'type' => 'title',
|
||||
'desc' => __( 'Test new features to improve the store management experience. These features might be included in future versions of WooCommerce. <a href="https://href.li/?https://woocommerce.com/usage-tracking/">Requires usage tracking.</a>', 'woocommerce-admin' ),
|
||||
'id' => 'features_options',
|
||||
),
|
||||
),
|
||||
$features,
|
||||
array(
|
||||
array(
|
||||
'type' => 'sectionend',
|
||||
'id' => 'features_options',
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Connects existing WooCommerce pages.
|
||||
*
|
||||
|
@ -826,13 +712,6 @@ class Loader {
|
|||
// Grab translation strings from Webpack-generated chunks.
|
||||
add_filter( 'load_script_translation_file', array( __CLASS__, 'load_script_translation_file' ), 10, 3 );
|
||||
|
||||
$features = self::get_features();
|
||||
$enabled_features = array();
|
||||
foreach ( $features as $key ) {
|
||||
$enabled_features[ $key ] = self::is_feature_enabled( $key );
|
||||
}
|
||||
wp_add_inline_script( WC_ADMIN_APP, 'window.wcAdminFeatures = ' . wp_json_encode( $enabled_features ), 'before' );
|
||||
|
||||
wp_enqueue_script( WC_ADMIN_APP );
|
||||
wp_enqueue_style( WC_ADMIN_APP );
|
||||
wp_enqueue_style( 'wc-material-icons' );
|
||||
|
@ -957,7 +836,7 @@ class Loader {
|
|||
* TODO: See usage in `admin.php`. This needs refactored and implemented properly in core.
|
||||
*/
|
||||
public static function is_embed_page() {
|
||||
return wc_admin_is_connected_page() || ( ! self::is_admin_page() && Screen::is_woocommerce_page() );
|
||||
return wc_admin_is_connected_page() || ( ! self::is_admin_page() && class_exists( 'Automattic\WooCommerce\Admin\Features\Navigation\Screen' ) && Screen::is_woocommerce_page() );
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -1042,11 +921,6 @@ class Loader {
|
|||
$classes[] = 'woocommerce-admin-is-loading';
|
||||
}
|
||||
|
||||
$features = self::get_features();
|
||||
foreach ( $features as $feature_key ) {
|
||||
$classes[] = sanitize_html_class( 'woocommerce-feature-enabled-' . $feature_key );
|
||||
}
|
||||
|
||||
$admin_body_class = implode( ' ', array_unique( $classes ) );
|
||||
return " $admin_body_class ";
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue