From 7bba8dcdee23f7dd67207ac5ec6fb99f57f17c96 Mon Sep 17 00:00:00 2001 From: louwie17 Date: Thu, 10 Mar 2022 09:42:55 -0400 Subject: [PATCH] Rename Settings.php to more specific name and create new Settings.php class to handle WooCommerce Admin settings (https://github.com/woocommerce/woocommerce-admin/pull/8443) --- .../includes/core-functions.php | 4 +- .../src-internal/Admin/Homescreen.php | 4 +- .../src-internal/Admin/Loader.php | 265 +------------- .../src-internal/Admin/Settings.php | 337 ++++++++++++------ .../Admin/SettingsNavigationFeature.php | 177 +++++++++ .../src/Features/Features.php | 2 +- 6 files changed, 414 insertions(+), 375 deletions(-) create mode 100644 plugins/woocommerce-admin/src-internal/Admin/SettingsNavigationFeature.php diff --git a/plugins/woocommerce-admin/includes/core-functions.php b/plugins/woocommerce-admin/includes/core-functions.php index fa2dbea7cf1..9c40a1a9bd3 100644 --- a/plugins/woocommerce-admin/includes/core-functions.php +++ b/plugins/woocommerce-admin/includes/core-functions.php @@ -7,7 +7,7 @@ * @package WooCommerce\Admin\Functions */ -use \Automattic\WooCommerce\Internal\Admin\Loader; +use \Automattic\WooCommerce\Internal\Admin\Settings; /** * Format a number using the decimal and thousands separator settings in WooCommerce. @@ -16,7 +16,7 @@ use \Automattic\WooCommerce\Internal\Admin\Loader; * @return string */ function wc_admin_number_format( $number ) { - $currency_settings = Loader::get_currency_settings(); + $currency_settings = Settings::get_currency_settings(); return number_format( $number, 0, diff --git a/plugins/woocommerce-admin/src-internal/Admin/Homescreen.php b/plugins/woocommerce-admin/src-internal/Admin/Homescreen.php index f299e597be6..63cd353ecce 100644 --- a/plugins/woocommerce-admin/src-internal/Admin/Homescreen.php +++ b/plugins/woocommerce-admin/src-internal/Admin/Homescreen.php @@ -6,7 +6,7 @@ namespace Automattic\WooCommerce\Internal\Admin; -use Automattic\WooCommerce\Internal\Admin\Loader; +use Automattic\WooCommerce\Internal\Admin\Settings; /** * Contains backend logic for the homescreen feature. @@ -186,7 +186,7 @@ class Homescreen { * @param array $settings Shared component settings. */ public function component_settings( $settings ) { - $allowed_statuses = Loader::get_order_statuses( wc_get_order_statuses() ); + $allowed_statuses = Settings::get_order_statuses( wc_get_order_statuses() ); // Remove the Draft Order status (from the Checkout Block). unset( $allowed_statuses['checkout-draft'] ); diff --git a/plugins/woocommerce-admin/src-internal/Admin/Loader.php b/plugins/woocommerce-admin/src-internal/Admin/Loader.php index f5dc8ffd81a..26e960b77d8 100644 --- a/plugins/woocommerce-admin/src-internal/Admin/Loader.php +++ b/plugins/woocommerce-admin/src-internal/Admin/Loader.php @@ -6,14 +6,10 @@ namespace Automattic\WooCommerce\Internal\Admin; -use \_WP_Dependency; -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 Automattic\WooCommerce\Admin\PageController; use Automattic\WooCommerce\Admin\PluginsHelper; -use WC_Marketplace_Suggestions; +use Automattic\WooCommerce\Internal\Admin\Settings; /** * Loader Class. @@ -69,16 +65,11 @@ class Loader { WCAdminSharedSettings::get_instance(); Translations::get_instance(); WCAdminUser::get_instance(); + Settings::get_instance(); - // Old settings injection. - add_filter( 'woocommerce_components_settings', array( __CLASS__, 'add_component_settings' ) ); - // New settings injection. - add_filter( 'woocommerce_admin_shared_settings', array( __CLASS__, 'add_component_settings' ) ); add_filter( 'admin_body_class', array( __CLASS__, 'add_admin_body_classes' ) ); add_filter( 'admin_title', array( __CLASS__, 'update_admin_title' ) ); add_action( 'in_admin_header', array( __CLASS__, 'embed_page_header' ) ); - add_filter( 'woocommerce_settings_groups', array( __CLASS__, 'add_settings_group' ) ); - add_filter( 'woocommerce_settings-wc_admin', array( __CLASS__, 'add_settings' ) ); add_action( 'admin_head', array( __CLASS__, 'remove_notices' ) ); add_action( 'admin_head', array( __CLASS__, 'smart_app_banner' ) ); add_action( 'admin_notices', array( __CLASS__, 'inject_before_notices' ), -9999 ); @@ -297,258 +288,6 @@ class Loader { isset( $settings['siteLocale'] ) - ? $settings['siteLocale'] - : get_locale(), - 'userLocale' => isset( $settings['l10n']['userLocale'] ) - ? $settings['l10n']['userLocale'] - : get_user_locale(), - 'weekdaysShort' => isset( $settings['l10n']['weekdaysShort'] ) - ? $settings['l10n']['weekdaysShort'] - : array_values( $wp_locale->weekday_abbrev ), - ]; - } - - $preload_data_endpoints = apply_filters( 'woocommerce_component_settings_preload_endpoints', array() ); - if ( class_exists( 'Jetpack' ) ) { - $preload_data_endpoints['jetpackStatus'] = '/jetpack/v4/connection'; - } - if ( ! empty( $preload_data_endpoints ) ) { - $preload_data = array_reduce( - array_values( $preload_data_endpoints ), - 'rest_preload_api_request' - ); - } - - $preload_options = apply_filters( 'woocommerce_admin_preload_options', array() ); - if ( ! empty( $preload_options ) ) { - foreach ( $preload_options as $option ) { - $settings['preloadOptions'][ $option ] = get_option( $option ); - } - } - - $preload_settings = apply_filters( 'woocommerce_admin_preload_settings', array() ); - if ( ! empty( $preload_settings ) ) { - $setting_options = new \WC_REST_Setting_Options_V2_Controller(); - foreach ( $preload_settings as $group ) { - $group_settings = $setting_options->get_group_settings( $group ); - $preload_settings = []; - foreach ( $group_settings as $option ) { - $preload_settings[ $option['id'] ] = $option['value']; - } - $settings['preloadSettings'][ $group ] = $preload_settings; - } - } - - $user_controller = new \WP_REST_Users_Controller(); - $request = new \WP_REST_Request(); - $request->set_query_params( array( 'context' => 'edit' ) ); - $user_response = $user_controller->get_current_item( $request ); - $current_user_data = is_wp_error( $user_response ) ? (object) array() : $user_response->get_data(); - - $settings['currentUserData'] = $current_user_data; - $settings['reviewsEnabled'] = get_option( 'woocommerce_enable_reviews' ); - $settings['manageStock'] = get_option( 'woocommerce_manage_stock' ); - $settings['commentModeration'] = get_option( 'comment_moderation' ); - $settings['notifyLowStockAmount'] = get_option( 'woocommerce_notify_low_stock_amount' ); - // @todo On merge, once plugin images are added to core WooCommerce, `wcAdminAssetUrl` can be retired, - // and `wcAssetUrl` can be used in its place throughout the codebase. - $settings['wcAdminAssetUrl'] = plugins_url( 'images/', dirname( __DIR__ ) . '/woocommerce-admin.php' ); - $settings['wcVersion'] = WC_VERSION; - $settings['siteUrl'] = site_url(); - $settings['shopUrl'] = get_permalink( wc_get_page_id( 'shop' ) ); - $settings['homeUrl'] = home_url(); - $settings['dateFormat'] = get_option( 'date_format' ); - $settings['timeZone'] = wc_timezone_string(); - $settings['plugins'] = array( - 'installedPlugins' => PluginsHelper::get_installed_plugin_slugs(), - 'activePlugins' => Plugins::get_active_plugins(), - ); - // Plugins that depend on changing the translation work on the server but not the client - - // WooCommerce Branding is an example of this - so pass through the translation of - // 'WooCommerce' to wcSettings. - $settings['woocommerceTranslation'] = __( 'WooCommerce', 'woocommerce-admin' ); - // We may have synced orders with a now-unregistered status. - // E.g An extension that added statuses is now inactive or removed. - $settings['unregisteredOrderStatuses'] = self::get_unregistered_order_statuses(); - // The separator used for attributes found in Variation titles. - $settings['variationTitleAttributesSeparator'] = apply_filters( 'woocommerce_product_variation_title_attributes_separator', ' - ', new \WC_Product() ); - - if ( ! empty( $preload_data_endpoints ) ) { - $settings['dataEndpoints'] = isset( $settings['dataEndpoints'] ) - ? $settings['dataEndpoints'] - : []; - foreach ( $preload_data_endpoints as $key => $endpoint ) { - // Handle error case: rest_do_request() doesn't guarantee success. - if ( empty( $preload_data[ $endpoint ] ) ) { - $settings['dataEndpoints'][ $key ] = array(); - } else { - $settings['dataEndpoints'][ $key ] = $preload_data[ $endpoint ]['body']; - } - } - } - $settings = self::get_custom_settings( $settings ); - if ( PageController::is_embed_page() ) { - $settings['embedBreadcrumbs'] = self::get_embed_breadcrumbs(); - } - - $settings['allowMarketplaceSuggestions'] = WC_Marketplace_Suggestions::allow_suggestions(); - $settings['connectNonce'] = wp_create_nonce( 'connect' ); - $settings['wcpay_welcome_page_connect_nonce'] = wp_create_nonce( 'wcpay-connect' ); - - return $settings; - } - - /** - * Format order statuses by removing a leading 'wc-' if present. - * - * @param array $statuses Order statuses. - * @return array formatted statuses. - */ - public static function get_order_statuses( $statuses ) { - $formatted_statuses = array(); - foreach ( $statuses as $key => $value ) { - $formatted_key = preg_replace( '/^wc-/', '', $key ); - $formatted_statuses[ $formatted_key ] = $value; - } - return $formatted_statuses; - } - - /** - * Get all order statuses present in analytics tables that aren't registered. - * - * @return array Unregistered order statuses. - */ - public static function get_unregistered_order_statuses() { - $registered_statuses = wc_get_order_statuses(); - $all_synced_statuses = OrdersDataStore::get_all_statuses(); - $unregistered_statuses = array_diff( $all_synced_statuses, array_keys( $registered_statuses ) ); - $formatted_status_keys = self::get_order_statuses( array_fill_keys( $unregistered_statuses, '' ) ); - $formatted_statuses = array_keys( $formatted_status_keys ); - - return array_combine( $formatted_statuses, $formatted_statuses ); - } - - /** - * Register the admin settings for use in the WC REST API - * - * @param array $groups Array of setting groups. - * @return array - */ - public static function add_settings_group( $groups ) { - $groups[] = array( - 'id' => 'wc_admin', - 'label' => __( 'WooCommerce Admin', 'woocommerce-admin' ), - 'description' => __( 'Settings for WooCommerce admin reporting.', 'woocommerce-admin' ), - ); - return $groups; - } - - /** - * Add WC Admin specific settings - * - * @param array $settings Array of settings in wc admin group. - * @return array - */ - public static function add_settings( $settings ) { - $unregistered_statuses = self::get_unregistered_order_statuses(); - $registered_statuses = self::get_order_statuses( wc_get_order_statuses() ); - $all_statuses = array_merge( $unregistered_statuses, $registered_statuses ); - - $settings[] = array( - 'id' => 'woocommerce_excluded_report_order_statuses', - 'option_key' => 'woocommerce_excluded_report_order_statuses', - 'label' => __( 'Excluded report order statuses', 'woocommerce-admin' ), - 'description' => __( 'Statuses that should not be included when calculating report totals.', 'woocommerce-admin' ), - 'default' => array( 'pending', 'cancelled', 'failed' ), - 'type' => 'multiselect', - 'options' => $all_statuses, - ); - $settings[] = array( - 'id' => 'woocommerce_actionable_order_statuses', - 'option_key' => 'woocommerce_actionable_order_statuses', - 'label' => __( 'Actionable order statuses', 'woocommerce-admin' ), - 'description' => __( 'Statuses that require extra action on behalf of the store admin.', 'woocommerce-admin' ), - 'default' => array( 'processing', 'on-hold' ), - 'type' => 'multiselect', - 'options' => $all_statuses, - ); - $settings[] = array( - 'id' => 'woocommerce_default_date_range', - 'option_key' => 'woocommerce_default_date_range', - 'label' => __( 'Default Date Range', 'woocommerce-admin' ), - 'description' => __( 'Default Date Range', 'woocommerce-admin' ), - 'default' => 'period=month&compare=previous_year', - 'type' => 'text', - ); - return $settings; - } - - /** - * Gets custom settings used for WC Admin. - * - * @param array $settings Array of settings to merge into. - * @return array - */ - public static function get_custom_settings( $settings ) { - $wc_rest_settings_options_controller = new \WC_REST_Setting_Options_Controller(); - $wc_admin_group_settings = $wc_rest_settings_options_controller->get_group_settings( 'wc_admin' ); - $settings['wcAdminSettings'] = array(); - - foreach ( $wc_admin_group_settings as $setting ) { - if ( ! empty( $setting['id'] ) ) { - $settings['wcAdminSettings'][ $setting['id'] ] = $setting['value']; - } - } - return $settings; - } - - /** - * Return an object defining the currecy options for the site's current currency - * - * @return array Settings for the current currency { - * Array of settings. - * - * @type string $code Currency code. - * @type string $precision Number of decimals. - * @type string $symbol Symbol for currency. - * } - */ - public static function get_currency_settings() { - $code = get_woocommerce_currency(); - - return apply_filters( - 'wc_currency_settings', - array( - 'code' => $code, - 'precision' => wc_get_price_decimals(), - 'symbol' => html_entity_decode( get_woocommerce_currency_symbol( $code ) ), - 'symbolPosition' => get_option( 'woocommerce_currency_pos' ), - 'decimalSeparator' => wc_get_price_decimal_separator(), - 'thousandSeparator' => wc_get_price_thousand_separator(), - 'priceFormat' => html_entity_decode( get_woocommerce_price_format() ), - ) - ); - } - /** * Delete woocommerce_onboarding_homepage_post_id field when the homepage is deleted * diff --git a/plugins/woocommerce-admin/src-internal/Admin/Settings.php b/plugins/woocommerce-admin/src-internal/Admin/Settings.php index 878be1872df..5ae40a45a0e 100644 --- a/plugins/woocommerce-admin/src-internal/Admin/Settings.php +++ b/plugins/woocommerce-admin/src-internal/Admin/Settings.php @@ -6,16 +6,16 @@ namespace Automattic\WooCommerce\Internal\Admin; +use Automattic\WooCommerce\Admin\API\Plugins; use Automattic\WooCommerce\Admin\PageController; +use Automattic\WooCommerce\Admin\API\Reports\Orders\DataStore as OrdersDataStore; +use Automattic\WooCommerce\Admin\PluginsHelper; +use WC_Marketplace_Suggestions; /** - * Contains backend logic for the Settings feature. + * Contains logic in regards to WooCommerce Admin Settings. */ class Settings { - /** - * Option name used to toggle this feature. - */ - const TOGGLE_OPTION_NAME = 'woocommerce_settings_enabled'; /** * Class instance. @@ -38,140 +38,263 @@ class Settings { * Hook into WooCommerce. */ public function __construct() { - if ( ! is_admin() ) { - return; - } - - add_filter( 'woocommerce_settings_features', array( $this, 'add_feature_toggle' ) ); - - if ( 'yes' !== get_option( 'woocommerce_settings_enabled', 'no' ) ) { - return; - } - - add_filter( 'woocommerce_admin_shared_settings', array( __CLASS__, 'add_component_settings' ) ); - // Run this after the original WooCommerce settings have been added. - add_action( 'admin_menu', array( $this, 'register_pages' ), 60 ); - add_action( 'init', array( $this, 'redirect_core_settings_pages' ) ); + // Old settings injection. + add_filter( 'woocommerce_components_settings', array( $this, 'add_component_settings' ) ); + // New settings injection. + add_filter( 'woocommerce_admin_shared_settings', array( $this, 'add_component_settings' ) ); + add_filter( 'woocommerce_settings_groups', array( $this, 'add_settings_group' ) ); + add_filter( 'woocommerce_settings-wc_admin', array( $this, 'add_settings' ) ); } /** - * Add the necessary data to initially load the WooCommerce Settings pages. + * Format order statuses by removing a leading 'wc-' if present. + * + * @param array $statuses Order statuses. + * @return array formatted statuses. + */ + public static function get_order_statuses( $statuses ) { + $formatted_statuses = array(); + foreach ( $statuses as $key => $value ) { + $formatted_key = preg_replace( '/^wc-/', '', $key ); + $formatted_statuses[ $formatted_key ] = $value; + } + return $formatted_statuses; + } + + /** + * Get all order statuses present in analytics tables that aren't registered. + * + * @return array Unregistered order statuses. + */ + private function get_unregistered_order_statuses() { + $registered_statuses = wc_get_order_statuses(); + $all_synced_statuses = OrdersDataStore::get_all_statuses(); + $unregistered_statuses = array_diff( $all_synced_statuses, array_keys( $registered_statuses ) ); + $formatted_status_keys = self::get_order_statuses( array_fill_keys( $unregistered_statuses, '' ) ); + $formatted_statuses = array_keys( $formatted_status_keys ); + + return array_combine( $formatted_statuses, $formatted_statuses ); + } + + /** + * Return an object defining the currecy options for the site's current currency + * + * @return array Settings for the current currency { + * Array of settings. + * + * @type string $code Currency code. + * @type string $precision Number of decimals. + * @type string $symbol Symbol for currency. + * } + */ + public static function get_currency_settings() { + $code = get_woocommerce_currency(); + + return apply_filters( + 'wc_currency_settings', + array( + 'code' => $code, + 'precision' => wc_get_price_decimals(), + 'symbol' => html_entity_decode( get_woocommerce_currency_symbol( $code ) ), + 'symbolPosition' => get_option( 'woocommerce_currency_pos' ), + 'decimalSeparator' => wc_get_price_decimal_separator(), + 'thousandSeparator' => wc_get_price_thousand_separator(), + 'priceFormat' => html_entity_decode( get_woocommerce_price_format() ), + ) + ); + } + + /** + * Hooks extra neccessary data into the component settings array already set in WooCommerce core. * * @param array $settings Array of component settings. * @return array Array of component settings. */ - public static function add_component_settings( $settings ) { + public function add_component_settings( $settings ) { if ( ! is_admin() ) { return $settings; } - $setting_pages = \WC_Admin_Settings::get_settings_pages(); - $pages = array(); - foreach ( $setting_pages as $setting_page ) { - $pages = $setting_page->add_settings_page( $pages ); + if ( ! function_exists( 'wc_blocks_container' ) ) { + global $wp_locale; + // inject data not available via older versions of wc_blocks/woo. + $settings['orderStatuses'] = self::get_order_statuses( wc_get_order_statuses() ); + $settings['stockStatuses'] = self::get_order_statuses( wc_get_product_stock_status_options() ); + $settings['currency'] = self::get_currency_settings(); + $settings['locale'] = [ + 'siteLocale' => isset( $settings['siteLocale'] ) + ? $settings['siteLocale'] + : get_locale(), + 'userLocale' => isset( $settings['l10n']['userLocale'] ) + ? $settings['l10n']['userLocale'] + : get_user_locale(), + 'weekdaysShort' => isset( $settings['l10n']['weekdaysShort'] ) + ? $settings['l10n']['weekdaysShort'] + : array_values( $wp_locale->weekday_abbrev ), + ]; } - $settings['settingsPages'] = $pages; + $preload_data_endpoints = apply_filters( 'woocommerce_component_settings_preload_endpoints', array() ); + if ( class_exists( 'Jetpack' ) ) { + $preload_data_endpoints['jetpackStatus'] = '/jetpack/v4/connection'; + } + if ( ! empty( $preload_data_endpoints ) ) { + $preload_data = array_reduce( + array_values( $preload_data_endpoints ), + 'rest_preload_api_request' + ); + } + + $preload_options = apply_filters( 'woocommerce_admin_preload_options', array() ); + if ( ! empty( $preload_options ) ) { + foreach ( $preload_options as $option ) { + $settings['preloadOptions'][ $option ] = get_option( $option ); + } + } + + $preload_settings = apply_filters( 'woocommerce_admin_preload_settings', array() ); + if ( ! empty( $preload_settings ) ) { + $setting_options = new \WC_REST_Setting_Options_V2_Controller(); + foreach ( $preload_settings as $group ) { + $group_settings = $setting_options->get_group_settings( $group ); + $preload_settings = []; + foreach ( $group_settings as $option ) { + $preload_settings[ $option['id'] ] = $option['value']; + } + $settings['preloadSettings'][ $group ] = $preload_settings; + } + } + + $user_controller = new \WP_REST_Users_Controller(); + $request = new \WP_REST_Request(); + $request->set_query_params( array( 'context' => 'edit' ) ); + $user_response = $user_controller->get_current_item( $request ); + $current_user_data = is_wp_error( $user_response ) ? (object) array() : $user_response->get_data(); + + $settings['currentUserData'] = $current_user_data; + $settings['reviewsEnabled'] = get_option( 'woocommerce_enable_reviews' ); + $settings['manageStock'] = get_option( 'woocommerce_manage_stock' ); + $settings['commentModeration'] = get_option( 'comment_moderation' ); + $settings['notifyLowStockAmount'] = get_option( 'woocommerce_notify_low_stock_amount' ); + // @todo On merge, once plugin images are added to core WooCommerce, `wcAdminAssetUrl` can be retired, + // and `wcAssetUrl` can be used in its place throughout the codebase. + $settings['wcAdminAssetUrl'] = plugins_url( 'images/', dirname( __DIR__ ) . '/woocommerce-admin.php' ); + $settings['wcVersion'] = WC_VERSION; + $settings['siteUrl'] = site_url(); + $settings['shopUrl'] = get_permalink( wc_get_page_id( 'shop' ) ); + $settings['homeUrl'] = home_url(); + $settings['dateFormat'] = get_option( 'date_format' ); + $settings['timeZone'] = wc_timezone_string(); + $settings['plugins'] = array( + 'installedPlugins' => PluginsHelper::get_installed_plugin_slugs(), + 'activePlugins' => Plugins::get_active_plugins(), + ); + // Plugins that depend on changing the translation work on the server but not the client - + // WooCommerce Branding is an example of this - so pass through the translation of + // 'WooCommerce' to wcSettings. + $settings['woocommerceTranslation'] = __( 'WooCommerce', 'woocommerce-admin' ); + // We may have synced orders with a now-unregistered status. + // E.g An extension that added statuses is now inactive or removed. + $settings['unregisteredOrderStatuses'] = $this->get_unregistered_order_statuses(); + // The separator used for attributes found in Variation titles. + $settings['variationTitleAttributesSeparator'] = apply_filters( 'woocommerce_product_variation_title_attributes_separator', ' - ', new \WC_Product() ); + + if ( ! empty( $preload_data_endpoints ) ) { + $settings['dataEndpoints'] = isset( $settings['dataEndpoints'] ) + ? $settings['dataEndpoints'] + : []; + foreach ( $preload_data_endpoints as $key => $endpoint ) { + // Handle error case: rest_do_request() doesn't guarantee success. + if ( empty( $preload_data[ $endpoint ] ) ) { + $settings['dataEndpoints'][ $key ] = array(); + } else { + $settings['dataEndpoints'][ $key ] = $preload_data[ $endpoint ]['body']; + } + } + } + $settings = $this->get_custom_settings( $settings ); + if ( PageController::is_embed_page() ) { + $settings['embedBreadcrumbs'] = wc_admin_get_breadcrumbs(); + } + + $settings['allowMarketplaceSuggestions'] = WC_Marketplace_Suggestions::allow_suggestions(); + $settings['connectNonce'] = wp_create_nonce( 'connect' ); + $settings['wcpay_welcome_page_connect_nonce'] = wp_create_nonce( 'wcpay-connect' ); return $settings; } /** - * Add the feature toggle to the features settings. + * Register the admin settings for use in the WC REST API * - * @param array $features Feature sections. + * @param array $groups Array of setting groups. * @return array */ - public static function add_feature_toggle( $features ) { - $features[] = array( - 'title' => __( 'Settings', 'woocommerce-admin' ), - 'desc' => __( - 'Adds the new WooCommerce settings UI.', - 'woocommerce-admin' - ), - 'id' => 'woocommerce_settings_enabled', - 'type' => 'checkbox', + public function add_settings_group( $groups ) { + $groups[] = array( + 'id' => 'wc_admin', + 'label' => __( 'WooCommerce Admin', 'woocommerce-admin' ), + 'description' => __( 'Settings for WooCommerce admin reporting.', 'woocommerce-admin' ), ); - - return $features; + return $groups; } /** - * Registers settings pages. - */ - public function register_pages() { - $controller = PageController::get_instance(); - - $setting_pages = \WC_Admin_Settings::get_settings_pages(); - $settings = array(); - foreach ( $setting_pages as $setting_page ) { - $settings = $setting_page->add_settings_page( $settings ); - } - - $order = 0; - foreach ( $settings as $key => $setting ) { - $order += 10; - $settings_page = array( - 'parent' => 'woocommerce-settings', - 'title' => $setting, - 'id' => 'settings-' . $key, - 'path' => "/settings/$key", - 'nav_args' => array( - 'capability' => 'manage_woocommerce', - 'order' => $order, - 'parent' => 'woocommerce-settings', - ), - ); - - // Replace the old menu with the first settings item. - if ( 10 === $order ) { - $this->replace_settings_page( $settings_page ); - } - - $controller->register_page( $settings_page ); - } - } - - /** - * Replace the Settings page in the original WooCommerce menu. + * Add WC Admin specific settings * - * @param array $page Page used to replace the original. + * @param array $settings Array of settings in wc admin group. + * @return array */ - protected function replace_settings_page( $page ) { - global $submenu; + public function add_settings( $settings ) { + $unregistered_statuses = $this->get_unregistered_order_statuses(); + $registered_statuses = self::get_order_statuses( wc_get_order_statuses() ); + $all_statuses = array_merge( $unregistered_statuses, $registered_statuses ); - // Check if WooCommerce parent menu has been registered. - if ( ! isset( $submenu['woocommerce'] ) ) { - return; - } - - foreach ( $submenu['woocommerce'] as &$item ) { - // The "slug" (aka the path) is the third item in the array. - if ( 0 === strpos( $item[2], 'wc-settings' ) ) { - $item[2] = wc_admin_url( "&path={$page['path']}" ); - } - } + $settings[] = array( + 'id' => 'woocommerce_excluded_report_order_statuses', + 'option_key' => 'woocommerce_excluded_report_order_statuses', + 'label' => __( 'Excluded report order statuses', 'woocommerce-admin' ), + 'description' => __( 'Statuses that should not be included when calculating report totals.', 'woocommerce-admin' ), + 'default' => array( 'pending', 'cancelled', 'failed' ), + 'type' => 'multiselect', + 'options' => $all_statuses, + ); + $settings[] = array( + 'id' => 'woocommerce_actionable_order_statuses', + 'option_key' => 'woocommerce_actionable_order_statuses', + 'label' => __( 'Actionable order statuses', 'woocommerce-admin' ), + 'description' => __( 'Statuses that require extra action on behalf of the store admin.', 'woocommerce-admin' ), + 'default' => array( 'processing', 'on-hold' ), + 'type' => 'multiselect', + 'options' => $all_statuses, + ); + $settings[] = array( + 'id' => 'woocommerce_default_date_range', + 'option_key' => 'woocommerce_default_date_range', + 'label' => __( 'Default Date Range', 'woocommerce-admin' ), + 'description' => __( 'Default Date Range', 'woocommerce-admin' ), + 'default' => 'period=month&compare=previous_year', + 'type' => 'text', + ); + return $settings; } /** - * Redirect the old settings page URLs to the new ones. + * Gets custom settings used for WC Admin. + * + * @param array $settings Array of settings to merge into. + * @return array */ - public function redirect_core_settings_pages() { - /* phpcs:disable WordPress.Security.NonceVerification */ - if ( ! isset( $_GET['page'] ) || 'wc-settings' !== $_GET['page'] ) { - return; + private function get_custom_settings( $settings ) { + $wc_rest_settings_options_controller = new \WC_REST_Setting_Options_Controller(); + $wc_admin_group_settings = $wc_rest_settings_options_controller->get_group_settings( 'wc_admin' ); + $settings['wcAdminSettings'] = array(); + + foreach ( $wc_admin_group_settings as $setting ) { + if ( ! empty( $setting['id'] ) ) { + $settings['wcAdminSettings'][ $setting['id'] ] = $setting['value']; + } } - - if ( ! current_user_can( 'manage_woocommerce' ) ) { - return; - } - - $setting_pages = \WC_Admin_Settings::get_settings_pages(); - $default_setting = isset( $setting_pages[0] ) ? $setting_pages[0]->get_id() : ''; - $setting = isset( $_GET['tab'] ) ? sanitize_text_field( wp_unslash( $_GET['tab'] ) ) : $default_setting; - /* phpcs:enable */ - - wp_safe_redirect( wc_admin_url( "&path=/settings/$setting" ) ); - exit; + return $settings; } } diff --git a/plugins/woocommerce-admin/src-internal/Admin/SettingsNavigationFeature.php b/plugins/woocommerce-admin/src-internal/Admin/SettingsNavigationFeature.php new file mode 100644 index 00000000000..40c2c2b10d4 --- /dev/null +++ b/plugins/woocommerce-admin/src-internal/Admin/SettingsNavigationFeature.php @@ -0,0 +1,177 @@ +add_settings_page( $pages ); + } + + $settings['settingsPages'] = $pages; + + return $settings; + } + + /** + * Add the feature toggle to the features settings. + * + * @param array $features Feature sections. + * @return array + */ + public static function add_feature_toggle( $features ) { + $features[] = array( + 'title' => __( 'Settings', 'woocommerce-admin' ), + 'desc' => __( + 'Adds the new WooCommerce settings UI.', + 'woocommerce-admin' + ), + 'id' => 'woocommerce_settings_enabled', + 'type' => 'checkbox', + ); + + return $features; + } + + /** + * Registers settings pages. + */ + public function register_pages() { + $controller = PageController::get_instance(); + + $setting_pages = \WC_Admin_Settings::get_settings_pages(); + $settings = array(); + foreach ( $setting_pages as $setting_page ) { + $settings = $setting_page->add_settings_page( $settings ); + } + + $order = 0; + foreach ( $settings as $key => $setting ) { + $order += 10; + $settings_page = array( + 'parent' => 'woocommerce-settings', + 'title' => $setting, + 'id' => 'settings-' . $key, + 'path' => "/settings/$key", + 'nav_args' => array( + 'capability' => 'manage_woocommerce', + 'order' => $order, + 'parent' => 'woocommerce-settings', + ), + ); + + // Replace the old menu with the first settings item. + if ( 10 === $order ) { + $this->replace_settings_page( $settings_page ); + } + + $controller->register_page( $settings_page ); + } + } + + /** + * Replace the Settings page in the original WooCommerce menu. + * + * @param array $page Page used to replace the original. + */ + protected function replace_settings_page( $page ) { + global $submenu; + + // Check if WooCommerce parent menu has been registered. + if ( ! isset( $submenu['woocommerce'] ) ) { + return; + } + + foreach ( $submenu['woocommerce'] as &$item ) { + // The "slug" (aka the path) is the third item in the array. + if ( 0 === strpos( $item[2], 'wc-settings' ) ) { + $item[2] = wc_admin_url( "&path={$page['path']}" ); + } + } + } + + /** + * Redirect the old settings page URLs to the new ones. + */ + public function redirect_core_settings_pages() { + /* phpcs:disable WordPress.Security.NonceVerification */ + if ( ! isset( $_GET['page'] ) || 'wc-settings' !== $_GET['page'] ) { + return; + } + + if ( ! current_user_can( 'manage_woocommerce' ) ) { + return; + } + + $setting_pages = \WC_Admin_Settings::get_settings_pages(); + $default_setting = isset( $setting_pages[0] ) ? $setting_pages[0]->get_id() : ''; + $setting = isset( $_GET['tab'] ) ? sanitize_text_field( wp_unslash( $_GET['tab'] ) ) : $default_setting; + /* phpcs:enable */ + + wp_safe_redirect( wc_admin_url( "&path=/settings/$setting" ) ); + exit; + } +} diff --git a/plugins/woocommerce-admin/src/Features/Features.php b/plugins/woocommerce-admin/src/Features/Features.php index 84e2e8d61df..4fabbaf2e22 100644 --- a/plugins/woocommerce-admin/src/Features/Features.php +++ b/plugins/woocommerce-admin/src/Features/Features.php @@ -413,7 +413,7 @@ class Features { 'Automattic\WooCommerce\Internal\Admin\Marketing' => 'Automattic\WooCommerce\Admin\Features\Marketing', 'Automattic\WooCommerce\Internal\Admin\MobileAppBanner' => 'Automattic\WooCommerce\Admin\Features\MobileAppBanner', 'Automattic\WooCommerce\Internal\Admin\RemoteInboxNotifications' => 'Automattic\WooCommerce\Admin\Features\RemoteInboxNotifications', - 'Automattic\WooCommerce\Internal\Admin\Settings' => 'Automattic\WooCommerce\Admin\Features\Settings', + 'Automattic\WooCommerce\Internal\Admin\SettingsNavigationFeature' => 'Automattic\WooCommerce\Admin\Features\Settings', 'Automattic\WooCommerce\Internal\Admin\ShippingLabelBanner' => 'Automattic\WooCommerce\Admin\Features\ShippingLabelBanner', 'Automattic\WooCommerce\Internal\Admin\ShippingLabelBannerDisplayRules' => 'Automattic\WooCommerce\Admin\Features\ShippingLabelBannerDisplayRules', 'Automattic\WooCommerce\Internal\Admin\WcPayWelcomePage' => 'Automattic\WooCommerce\Admin\Features\WcPayWelcomePage',