Commit bca7e78afb for woocommerce
commit bca7e78afbee8e2d694587a310ad492e5e9f50e8
Author: Chi-Hsuan Huang <chihsuan.tw@gmail.com>
Date: Thu Dec 4 16:18:51 2025 +0900
Add import mode to analytics settings (#62187)
* Update analytics settings to include import interval and adjust label for clarity
* Changed the label for the immediate import setting from 'Update' to 'Updates' for better clarity.
* Added a hidden setting for the analytics import interval, which retrieves and formats the interval into a human-readable string for display on the client side.
* Refactored the OrdersScheduler to utilize a dedicated method for fetching the import interval, enhancing code maintainability.
* Add import mode confirmation modal and enhance settings configuration
* Introduced a new confirmation modal for switching to immediate import mode in analytics settings, providing users with a warning about potential performance impacts.
* Updated the settings configuration to include the new import mode setting, allowing users to choose between scheduled and immediate updates.
* Enhanced the settings component to handle the modal's open/close state and confirm/cancel actions for the import mode change.
* Added radio control support in the settings component for better user interaction with the new import mode option.
* Add changelog
* Refactor import interval setting in analytics configuration
* Moved the import interval setting inside the conditional check for the analytics scheduled import feature, ensuring it is only defined when the feature is enabled. This improves code clarity and maintains the intended functionality.
* Remove unnecessary comments from ImportModeConfirmationModal component for improved code clarity.
* Update button variant in analytics settings from tertiary to secondary for improved UI consistency.
* Remove unnecessary styling for radio control label in analytics settings SCSS file to streamline code.
* Fix lint
* Add unit tests
* Fix lint
* Fix lint
* Fix lint
* Update plugins/woocommerce/client/admin/client/analytics/settings/config.js
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
* Update plugins/woocommerce/src/Internal/Admin/Settings.php
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update plugins/woocommerce/client/admin/client/analytics/settings/index.js
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
* Update doc comments
* Ensure config exits
* Update option label
* Ensure import interval is an integer in settings
* Add aria-labels to buttons in import mode confirmation modal for improved accessibility
* Prevent input changes when import mode modal is open in analytics settings
* Update changelog
* Refactor class names in import mode confirmation modal for consistency with WooCommerce naming conventions
---------
Co-authored-by: coderabbitai[bot] <136622811+coderabbitai[bot]@users.noreply.github.com>
Co-authored-by: Copilot <175728472+Copilot@users.noreply.github.com>
diff --git a/plugins/woocommerce/changelog/wooa7s-792-settings-ui-add-import-mode-to-analytics-settings b/plugins/woocommerce/changelog/wooa7s-792-settings-ui-add-import-mode-to-analytics-settings
new file mode 100644
index 0000000000..3bec6c2c5a
--- /dev/null
+++ b/plugins/woocommerce/changelog/wooa7s-792-settings-ui-add-import-mode-to-analytics-settings
@@ -0,0 +1,4 @@
+Significance: minor
+Type: add
+
+Add import mode control to Analytics settings, allowing users to choose between scheduled (every 12 hours) and immediate updates
diff --git a/plugins/woocommerce/client/admin/client/analytics/settings/config.js b/plugins/woocommerce/client/admin/client/analytics/settings/config.js
index 25b4e57e5e..465742ab87 100644
--- a/plugins/woocommerce/client/admin/client/analytics/settings/config.js
+++ b/plugins/woocommerce/client/admin/client/analytics/settings/config.js
@@ -23,6 +23,8 @@ export const DEFAULT_ORDER_STATUSES = [
'on-hold',
];
export const DEFAULT_DATE_RANGE = 'period=month&compare=previous_year';
+export const IMMEDIATE_IMPORT_SETTING_NAME =
+ 'woocommerce_analytics_immediate_import';
const filteredOrderStatuses = Object.keys( ORDER_STATUSES )
.filter( ( status ) => status !== 'refunded' )
@@ -80,7 +82,7 @@ const orderStatusOptions = [
* @filter woocommerce_admin_analytics_settings
* @param {Object} reportSettings Report settings.
*/
-export const config = applyFilters( SETTINGS_FILTER, {
+const baseConfig = {
woocommerce_excluded_report_order_statuses: {
label: __( 'Excluded statuses:', 'woocommerce' ),
inputType: 'checkboxGroup',
@@ -151,4 +153,47 @@ export const config = applyFilters( SETTINGS_FILTER, {
'woocommerce'
),
},
-} );
+};
+
+// Add import mode setting if feature is enabled
+if ( !! window.wcAdminFeatures?.[ 'analytics-scheduled-import' ] ) {
+ const importInterval = getAdminSetting(
+ 'woocommerce_analytics_import_interval',
+ __( '12 hours', 'woocommerce' ) // Default value for the import interval.
+ );
+
+ baseConfig[ IMMEDIATE_IMPORT_SETTING_NAME ] = {
+ name: IMMEDIATE_IMPORT_SETTING_NAME,
+ label: __( 'Updates:', 'woocommerce' ),
+ inputType: 'radio',
+ options: [
+ {
+ label: __( 'Scheduled (recommended)', 'woocommerce' ),
+ value: 'no',
+ description: sprintf(
+ /* translators: %s: import interval, e.g. "12 hours" */
+ __(
+ 'Updates automatically every %s. Lowest impact on your site.',
+ 'woocommerce'
+ ),
+ importInterval
+ ),
+ },
+ {
+ label: __( 'Immediately', 'woocommerce' ),
+ value: 'yes',
+ description: __(
+ 'Updates as soon as new data is available. May slow busy stores.',
+ 'woocommerce'
+ ),
+ },
+ ],
+ // This default value is primarily used when users click "Reset defaults" for settings.
+ // We set 'no' (Scheduled) as the default for new installs, since it is the recommended, lowest-impact option.
+ // Note: The PHP backend defaults to 'yes' (Immediate) to preserve legacy behavior for existing stores and avoid disrupting current site operations.
+ // This intentional difference ensures new stores use the best-practice default, while existing stores are not affected by updates.
+ defaultValue: 'no',
+ };
+}
+
+export const config = applyFilters( SETTINGS_FILTER, baseConfig );
diff --git a/plugins/woocommerce/client/admin/client/analytics/settings/import-mode-confirmation-modal.tsx b/plugins/woocommerce/client/admin/client/analytics/settings/import-mode-confirmation-modal.tsx
new file mode 100644
index 0000000000..bd718b89c4
--- /dev/null
+++ b/plugins/woocommerce/client/admin/client/analytics/settings/import-mode-confirmation-modal.tsx
@@ -0,0 +1,70 @@
+/**
+ * External dependencies
+ */
+import {
+ Button,
+ Modal,
+ Flex,
+ __experimentalText as Text,
+} from '@wordpress/components';
+import { __ } from '@wordpress/i18n';
+
+interface ImportModeConfirmationModalProps {
+ isOpen: boolean;
+ onClose: () => void;
+ onConfirm: () => void;
+}
+
+export const ImportModeConfirmationModal = ( {
+ isOpen,
+ onClose,
+ onConfirm,
+}: ImportModeConfirmationModalProps ) => {
+ if ( ! isOpen ) {
+ return null;
+ }
+
+ return (
+ <Modal
+ title={ __( 'Are you sure?', 'woocommerce' ) }
+ onRequestClose={ onClose }
+ className="woocommerce-analytics-import-mode-confirmation-modal"
+ size="medium"
+ >
+ <Flex direction="column" gap={ 6 }>
+ <Text>
+ { __(
+ 'Immediate updates to Analytics can impact your performance as it may slow busy stores.',
+ 'woocommerce'
+ ) }
+ </Text>
+ <Flex
+ direction="row"
+ className="woocommerce-analytics-import-mode-confirmation-modal__buttons"
+ justify="flex-end"
+ >
+ <Button
+ variant="tertiary"
+ onClick={ onClose }
+ aria-label={ __(
+ 'Cancel import mode change',
+ 'woocommerce'
+ ) }
+ >
+ { __( 'Cancel', 'woocommerce' ) }
+ </Button>
+ <Button
+ variant="primary"
+ onClick={ onConfirm }
+ aria-label={ __(
+ 'Confirm switching to immediate import mode',
+ 'woocommerce'
+ ) }
+ >
+ { __( 'Confirm', 'woocommerce' ) }
+ </Button>
+ </Flex>
+ </Flex>
+ </Modal>
+ );
+};
diff --git a/plugins/woocommerce/client/admin/client/analytics/settings/index.js b/plugins/woocommerce/client/admin/client/analytics/settings/index.js
index af83ec0cb5..e73c51d822 100644
--- a/plugins/woocommerce/client/admin/client/analytics/settings/index.js
+++ b/plugins/woocommerce/client/admin/client/analytics/settings/index.js
@@ -3,7 +3,7 @@
*/
import { __ } from '@wordpress/i18n';
import { Button } from '@wordpress/components';
-import { Fragment, useEffect, useRef } from '@wordpress/element';
+import { Fragment, useEffect, useRef, useState } from '@wordpress/element';
import { compose } from '@wordpress/compose';
import { withDispatch } from '@wordpress/data';
import { SectionHeader, ScrollTo } from '@woocommerce/components';
@@ -14,9 +14,10 @@ import { recordEvent } from '@woocommerce/tracks';
* Internal dependencies
*/
import './index.scss';
-import { config } from './config';
+import { config, IMMEDIATE_IMPORT_SETTING_NAME } from './config';
import Setting from './setting';
import HistoricalData from './historical-data';
+import { ImportModeConfirmationModal } from './import-mode-confirmation-modal';
const Settings = ( { createNotice, query } ) => {
const {
@@ -29,6 +30,10 @@ const Settings = ( { createNotice, query } ) => {
wcAdminSettings,
} = useSettings( 'wc_admin', [ 'wcAdminSettings' ] );
const hasSaved = useRef( false );
+ const [ isImportModeModalOpen, setIsImportModeModalOpen ] =
+ useState( false );
+ const [ pendingImportModeChange, setPendingImportModeChange ] =
+ useState( null );
useEffect( () => {
function warnIfUnsavedChanges( event ) {
@@ -110,7 +115,25 @@ const Settings = ( { createNotice, query } ) => {
};
const handleInputChange = ( e ) => {
+ if ( isImportModeModalOpen ) {
+ return;
+ }
+
const { checked, name, type, value } = e.target;
+
+ // Intercept import mode change from scheduled to immediate
+ if (
+ name === IMMEDIATE_IMPORT_SETTING_NAME &&
+ config[ IMMEDIATE_IMPORT_SETTING_NAME ] &&
+ wcAdminSettings[ name ] === 'no' &&
+ value === 'yes'
+ ) {
+ setPendingImportModeChange( { name, value } );
+ setIsImportModeModalOpen( true );
+
+ return;
+ }
+
const nextSettings = { ...wcAdminSettings };
if ( type === 'checkbox' ) {
@@ -127,6 +150,22 @@ const Settings = ( { createNotice, query } ) => {
updateSettings( 'wcAdminSettings', nextSettings );
};
+ const handleImportModeConfirm = () => {
+ if ( pendingImportModeChange ) {
+ const nextSettings = { ...wcAdminSettings };
+ nextSettings[ pendingImportModeChange.name ] =
+ pendingImportModeChange.value;
+ updateSettings( 'wcAdminSettings', nextSettings );
+ }
+ setIsImportModeModalOpen( false );
+ setPendingImportModeChange( null );
+ };
+
+ const handleImportModeCancel = () => {
+ setIsImportModeModalOpen( false );
+ setPendingImportModeChange( null );
+ };
+
return (
<Fragment>
<SectionHeader
@@ -143,11 +182,11 @@ const Settings = ( { createNotice, query } ) => {
/>
) ) }
<div className="woocommerce-settings__actions">
- <Button isSecondary onClick={ resetDefaults }>
+ <Button variant="secondary" onClick={ resetDefaults }>
{ __( 'Reset defaults', 'woocommerce' ) }
</Button>
<Button
- isPrimary
+ variant="primary"
isBusy={ isRequesting }
onClick={ saveChanges }
>
@@ -162,6 +201,13 @@ const Settings = ( { createNotice, query } ) => {
) : (
<HistoricalData createNotice={ createNotice } />
) }
+ { config[ IMMEDIATE_IMPORT_SETTING_NAME ] && (
+ <ImportModeConfirmationModal
+ isOpen={ isImportModeModalOpen }
+ onClose={ handleImportModeCancel }
+ onConfirm={ handleImportModeConfirm }
+ />
+ ) }
</Fragment>
);
};
diff --git a/plugins/woocommerce/client/admin/client/analytics/settings/setting.js b/plugins/woocommerce/client/admin/client/analytics/settings/setting.js
index c0ce772ce7..7e2c455d88 100644
--- a/plugins/woocommerce/client/admin/client/analytics/settings/setting.js
+++ b/plugins/woocommerce/client/admin/client/analytics/settings/setting.js
@@ -1,7 +1,12 @@
/**
* External dependencies
*/
-import { Button, CheckboxControl, SelectControl } from '@wordpress/components';
+import {
+ Button,
+ CheckboxControl,
+ RadioControl,
+ SelectControl,
+} from '@wordpress/components';
import { Component } from '@wordpress/element';
import { compose } from '@wordpress/compose';
import PropTypes from 'prop-types';
@@ -59,7 +64,7 @@ class Setting extends Component {
case 'button':
return (
<Button
- isSecondary
+ variant="secondary"
onClick={ this.handleInputCallback }
disabled={ disabled }
>
@@ -91,6 +96,22 @@ class Setting extends Component {
}
/>
);
+ case 'radio':
+ return (
+ <RadioControl
+ selected={ value }
+ options={ options }
+ onChange={ ( newValue ) =>
+ handleChange( {
+ target: {
+ name,
+ type: 'radio',
+ value: newValue,
+ },
+ } )
+ }
+ />
+ );
case 'text':
default:
const id = uniqueId( name );
@@ -205,6 +226,7 @@ Setting.propTypes = {
'text',
'component',
'select',
+ 'radio',
] ),
/**
* Label used for describing the setting.
diff --git a/plugins/woocommerce/client/admin/client/analytics/settings/setting.scss b/plugins/woocommerce/client/admin/client/analytics/settings/setting.scss
index c746ca4d76..b1c9797e0b 100644
--- a/plugins/woocommerce/client/admin/client/analytics/settings/setting.scss
+++ b/plugins/woocommerce/client/admin/client/analytics/settings/setting.scss
@@ -27,7 +27,8 @@
}
}
- label {
+ // No need to style the radio control label as it already has the expected styles.
+ label:not(.components-radio-control__label) {
width: 100%;
display: block;
margin-bottom: $gap-small;
@@ -62,3 +63,11 @@
font-style: italic;
color: $gray-700;
}
+
+.woocommerce-analytics-import-mode-confirmation-modal {
+ .components-modal__header-heading {
+ font-size: 20px;
+ font-weight: 500;
+ line-height: 24px;
+ }
+}
diff --git a/plugins/woocommerce/client/admin/client/analytics/settings/test/index.test.js b/plugins/woocommerce/client/admin/client/analytics/settings/test/index.test.js
new file mode 100644
index 0000000000..9d2f4c0af4
--- /dev/null
+++ b/plugins/woocommerce/client/admin/client/analytics/settings/test/index.test.js
@@ -0,0 +1,205 @@
+/**
+ * External dependencies
+ */
+import { render, screen, waitFor, fireEvent } from '@testing-library/react';
+import { useSettings } from '@woocommerce/data';
+
+/**
+ * Internal dependencies
+ */
+import Settings from '../index';
+import { IMMEDIATE_IMPORT_SETTING_NAME } from '../config';
+
+// Mock dependencies.
+jest.mock( '@woocommerce/data', () => ( {
+ useSettings: jest.fn(),
+} ) );
+
+jest.mock( '@woocommerce/tracks', () => ( {
+ recordEvent: jest.fn(),
+} ) );
+
+// Enable the feature flag before mocking config.
+window.wcAdminFeatures = {
+ 'analytics-scheduled-import': true,
+};
+
+jest.mock( '../config', () => ( {
+ config: {
+ woocommerce_analytics_immediate_import: {
+ name: 'woocommerce_analytics_immediate_import',
+ label: 'Updates:',
+ inputType: 'radio',
+ options: [
+ {
+ label: 'Scheduled (recommended)',
+ value: 'no',
+ description: 'Updates automatically every 12 hours.',
+ },
+ {
+ label: 'Immediately',
+ value: 'yes',
+ description: 'Updates as soon as new data is available.',
+ },
+ ],
+ defaultValue: 'no',
+ },
+ },
+ IMMEDIATE_IMPORT_SETTING_NAME: 'woocommerce_analytics_immediate_import',
+} ) );
+
+jest.mock( '../historical-data', () => ( {
+ __esModule: true,
+ default: () => <div>Historical Data</div>,
+} ) );
+
+describe( 'Settings - Import Mode Modal', () => {
+ const mockUpdateSettings = jest.fn();
+ const mockPersistSettings = jest.fn();
+
+ beforeEach( () => {
+ jest.clearAllMocks();
+
+ useSettings.mockReturnValue( {
+ settingsError: false,
+ isRequesting: false,
+ isDirty: false,
+ persistSettings: mockPersistSettings,
+ updateAndPersistSettings: jest.fn(),
+ updateSettings: mockUpdateSettings,
+ wcAdminSettings: {
+ [ IMMEDIATE_IMPORT_SETTING_NAME ]: 'no',
+ },
+ } );
+
+ // Mock window.wcAdminFeatures.
+ window.wcAdminFeatures = {
+ 'analytics-scheduled-import': true,
+ };
+ } );
+
+ afterEach( () => {
+ delete window.wcAdminFeatures;
+ } );
+
+ it( 'renders import mode radio control', () => {
+ render( <Settings createNotice={ jest.fn() } query={ {} } /> );
+
+ // Verify radio buttons are rendered.
+ expect(
+ screen.getByRole( 'radio', { name: /scheduled/i } )
+ ).toBeInTheDocument();
+ expect(
+ screen.getByRole( 'radio', { name: /immediately/i } )
+ ).toBeInTheDocument();
+
+ // Verify scheduled is selected by default.
+ expect(
+ screen.getByRole( 'radio', { name: /scheduled/i } )
+ ).toBeChecked();
+ } );
+
+ it( 'shows modal when switching from scheduled to immediate mode', async () => {
+ render( <Settings createNotice={ jest.fn() } query={ {} } /> );
+
+ // Find the "Immediately" radio button.
+ const immediatelyRadio = screen.getByRole( 'radio', {
+ name: /immediately/i,
+ } );
+
+ // Click the radio button.
+ fireEvent.click( immediatelyRadio );
+
+ // Modal should appear - WordPress Modal uses dialog role.
+ expect( await screen.findByRole( 'dialog' ) ).toBeInTheDocument();
+
+ expect( screen.getByText( /are you sure\?/i ) ).toBeInTheDocument();
+
+ expect(
+ screen.getByText(
+ /immediate updates to analytics can impact your performance/i
+ )
+ ).toBeInTheDocument();
+ } );
+
+ it( 'does not update setting when modal is cancelled', async () => {
+ render( <Settings createNotice={ jest.fn() } query={ {} } /> );
+
+ // Click "Immediately" radio button.
+ const immediatelyRadio = screen.getByRole( 'radio', {
+ name: /immediately/i,
+ } );
+ fireEvent.click( immediatelyRadio );
+
+ // Wait for modal to appear.
+ expect( await screen.findByRole( 'dialog' ) ).toBeInTheDocument();
+
+ // Click Cancel button.
+ const cancelButton = screen.getByRole( 'button', {
+ name: /cancel/i,
+ } );
+ fireEvent.click( cancelButton );
+
+ // Modal should close and setting should not be updated.
+ await waitFor( () => {
+ expect( screen.queryByRole( 'dialog' ) ).not.toBeInTheDocument();
+ } );
+
+ expect( mockUpdateSettings ).not.toHaveBeenCalled();
+ } );
+
+ it( 'updates setting when modal is confirmed', async () => {
+ render( <Settings createNotice={ jest.fn() } query={ {} } /> );
+
+ // Click "Immediately" radio button.
+ const immediatelyRadio = screen.getByRole( 'radio', {
+ name: /immediately/i,
+ } );
+ fireEvent.click( immediatelyRadio );
+
+ // Wait for modal to appear.
+ expect( await screen.findByRole( 'dialog' ) ).toBeInTheDocument();
+
+ // Click Confirm button.
+ const confirmButton = screen.getByRole( 'button', {
+ name: /confirm/i,
+ } );
+ fireEvent.click( confirmButton );
+
+ // Setting should be updated.
+ expect( mockUpdateSettings ).toHaveBeenCalledWith( 'wcAdminSettings', {
+ woocommerce_analytics_immediate_import: 'yes',
+ } );
+ } );
+
+ it( 'does not show modal when switching from immediate to scheduled', async () => {
+ // Set initial state to immediate mode.
+ useSettings.mockReturnValue( {
+ settingsError: false,
+ isRequesting: false,
+ isDirty: false,
+ persistSettings: mockPersistSettings,
+ updateAndPersistSettings: jest.fn(),
+ updateSettings: mockUpdateSettings,
+ wcAdminSettings: {
+ woocommerce_analytics_immediate_import: 'yes',
+ },
+ } );
+
+ render( <Settings createNotice={ jest.fn() } query={ {} } /> );
+
+ // Click "Scheduled" radio button.
+ const scheduledRadio = screen.getByRole( 'radio', {
+ name: /scheduled/i,
+ } );
+ fireEvent.click( scheduledRadio );
+
+ // Modal should NOT appear.
+ expect( screen.queryByRole( 'dialog' ) ).not.toBeInTheDocument();
+
+ // Setting should be updated immediately.
+ expect( mockUpdateSettings ).toHaveBeenCalledWith( 'wcAdminSettings', {
+ woocommerce_analytics_immediate_import: 'no',
+ } );
+ } );
+} );
diff --git a/plugins/woocommerce/src/Internal/Admin/Schedulers/OrdersScheduler.php b/plugins/woocommerce/src/Internal/Admin/Schedulers/OrdersScheduler.php
index 89aa0360ba..52e8f4a3a2 100644
--- a/plugins/woocommerce/src/Internal/Admin/Schedulers/OrdersScheduler.php
+++ b/plugins/woocommerce/src/Internal/Admin/Schedulers/OrdersScheduler.php
@@ -382,13 +382,7 @@ AND status NOT IN ( 'wc-auto-draft', 'trash', 'auto-draft' )
return;
}
- /**
- * Filters the interval for the recurring batch processor.
- *
- * @since 10.4.0
- * @param int $interval Interval in seconds. Default 12 hours.
- */
- $interval = apply_filters( 'woocommerce_analytics_import_interval', 12 * HOUR_IN_SECONDS );
+ $interval = self::get_import_interval();
as_schedule_recurring_action( time(), $interval, $action_hook, array(), static::$group, true );
}
@@ -561,6 +555,22 @@ AND status NOT IN ( 'wc-auto-draft', 'trash', 'auto-draft' )
}
}
+ /**
+ * Get the import interval.
+ *
+ * @internal
+ * @return int The import interval in seconds.
+ */
+ public static function get_import_interval() {
+ /**
+ * Filter the analytics import interval.
+ *
+ * @since 10.4.0
+ * @param int $interval The import interval in seconds. Default is 12 hours.
+ */
+ return apply_filters( 'woocommerce_analytics_import_interval', 12 * HOUR_IN_SECONDS );
+ }
+
/**
* Get orders updated since the specified cursor position.
*
diff --git a/plugins/woocommerce/src/Internal/Admin/Settings.php b/plugins/woocommerce/src/Internal/Admin/Settings.php
index 10005c796f..4e19552cac 100644
--- a/plugins/woocommerce/src/Internal/Admin/Settings.php
+++ b/plugins/woocommerce/src/Internal/Admin/Settings.php
@@ -353,15 +353,26 @@ class Settings {
$settings[] = array(
'id' => 'woocommerce_analytics_immediate_import',
'option_key' => 'woocommerce_analytics_immediate_import',
- 'label' => __( 'Update', 'woocommerce' ),
+ 'label' => __( 'Updates', 'woocommerce' ),
'description' => __( 'Controls how analytics data is imported from orders.', 'woocommerce' ),
'type' => 'radio',
'default' => 'yes', // Default to immediate import for backward compatibility to ensure we don't accidentally change the behavior for existing stores.
'options' => array(
- 'no' => __( 'Scheduled (Recommended)', 'woocommerce' ),
+ 'no' => __( 'Scheduled (recommended)', 'woocommerce' ),
'yes' => __( 'Immediately', 'woocommerce' ),
),
);
+
+ // Add hidden setting for the import interval to display in the client side.
+ $import_interval = \Automattic\WooCommerce\Internal\Admin\Schedulers\OrdersScheduler::get_import_interval();
+ $import_interval = absint( $import_interval );
+ // Format the import interval to a human-readable string.
+ $import_interval_string = human_time_diff( 0, $import_interval );
+ $settings[] = array(
+ 'id' => 'woocommerce_analytics_import_interval',
+ 'type' => 'hidden',
+ 'default' => $import_interval_string,
+ );
}
return $settings;