automatewoo/admin/admin.php
fei-source 47d3c9a8b6 Update to v6.2.2
Source: GrootMade/Festinger Vault
2026-03-15 08:31:15 +08:00

1116 lines
32 KiB
PHP

<?php
namespace AutomateWoo;
use AutomateWoo\Admin\Analytics;
use AutomateWoo\Admin\AssetData;
use AutomateWoo\Admin\WCAdminConnectPages;
use AutomateWoo\HPOS_Helper;
use Automattic\WooCommerce\Admin\PageController;
use Automattic\WooCommerce\Blocks\Assets\AssetDataRegistry;
use Automattic\WooCommerce\Blocks\Package as BlocksPackage;
/**
* @class Admin
*/
class Admin {
/**
* Initialize the Admin class.
*/
public static function init() {
$self = __CLASS__; /** @var $self Admin (for IDE) */
Admin_Ajax::init();
AdminNotices::init();
( new WCAdminConnectPages() )->init();
Analytics::init();
add_action( 'current_screen', [ $self, 'includes' ] );
add_action( 'admin_enqueue_scripts', [ $self, 'register_scripts' ] );
add_action( 'admin_enqueue_scripts', [ $self, 'register_styles' ] );
add_action( 'admin_enqueue_scripts', [ $self, 'enqueue_scripts_and_styles' ], 20 );
add_action( 'admin_enqueue_scripts', [ $self, 'load_react_ui_scripts' ] );
add_action( 'admin_menu', [ $self, 'admin_menu' ] );
add_action( 'admin_footer', [ $self, 'replace_top_level_menu' ] );
add_action( 'admin_head', [ $self, 'menu_highlight' ] );
add_filter( 'submenu_file', [ $self, 'submenu_highlight' ], 10, 2 );
add_filter( 'admin_menu', [ $self, 'alter_menu' ] );
add_filter( 'woocommerce_screen_ids', [ $self, 'filter_woocommerce_screen_ids' ] );
add_filter( 'woocommerce_display_admin_footer_text', [ $self, 'filter_woocommerce_display_footer_text' ] );
add_action( 'current_screen', [ $self, 'remove_woocommerce_help_tab' ], 100 );
add_filter( 'woocommerce_reports_screen_ids', [ $self, 'inject_woocommerce_reports_screen_ids' ] );
add_filter( 'editor_stylesheets', [ $self, 'add_editor_styles' ] );
add_action( 'current_screen', [ $self, 'screen_options' ] );
add_filter( 'set-screen-option', [ $self, 'handle_save_screen_option' ], 10, 3 );
add_action( 'before_delete_post', [ $self, 'flush_group_caches' ], 8 );
add_action( 'wp_trash_post', [ $self, 'flush_group_caches' ] );
add_action( 'untrash_post', [ $self, 'flush_group_caches' ] );
if ( aw_request( 'action' ) === 'automatewoo-settings' ) {
add_action( 'wp_loaded', [ $self, 'save_settings' ] );
}
if ( aw_request( 'page' ) === 'automatewoo-preview' && aw_request( 'action' ) === 'loading' ) {
add_action( 'admin_init', [ $self, 'cache_preview_loader' ] );
}
if ( aw_request( 'page' ) === 'automatewoo-preview' ) {
add_action( 'admin_notices', [ $self, 'remove_admin_notices' ], 0 );
}
$registry = BlocksPackage::container()->get( AssetDataRegistry::class );
( new AssetData( $registry ) )->add_data();
// Include workflow duplication feature.
if ( current_user_can( 'manage_woocommerce' ) ) {
new Workflow_Duplicate();
}
}
/**
* Initialize classes based on current screen.
*/
public static function includes() {
switch ( self::get_screen_id() ) {
case 'aw_workflow':
new Admin_Workflow_Edit();
break;
case 'edit-aw_workflow':
new Admin_Workflow_List();
break;
case 'edit-shop_coupon':
new \AW_Admin_Coupons_List();
break;
}
}
/**
* Add screen options based on current screen.
*/
public static function screen_options() {
$screen_id = self::get_screen_id();
switch ( $screen_id ) {
case 'opt-ins':
$screen_id = 'optins'; // Screen option with dash is not supported.
case 'logs':
case 'carts':
case 'guests':
case 'queue':
add_screen_option(
'per_page',
[
'option' => "automatewoo_{$screen_id}_per_page",
'default' => 20,
]
);
break;
}
}
/**
* Handle saving screen option.
*
* @param bool $keep
* @param string $option
* @param int $value
*
* @return bool|int
*/
public static function handle_save_screen_option( $keep, $option, $value ) {
$options = [
'automatewoo_logs_per_page',
'automatewoo_carts_per_page',
'automatewoo_queue_per_page',
'automatewoo_guests_per_page',
'automatewoo_optins_per_page',
];
if ( in_array( $option, $options, true ) ) {
return $value;
}
return $keep;
}
/**
* Add menu entries.
*/
public static function admin_menu() {
$sub_menu = [];
$position = '55.6324'; // fix for rare position clash bug
$icon = 'data:image/svg+xml;base64,PD94bWwgdmVyc2lvbj0iMS4wIiBlbmNvZGluZz0idXRmLTgiPz48c3ZnIHZlcnNpb249IjEuMSIgaWQ9IkxheWVyXzEiIHhtbG5zPSJodHRwOi8vd3d3LnczLm9yZy8yMDAwL3N2ZyIgeG1sbnM6eGxpbms9Imh0dHA6Ly93d3cudzMub3JnLzE5OTkveGxpbmsiIHg9IjBweCIgeT0iMHB4IiB2aWV3Qm94PSIwIDAgNTEyIDUxMiIgZW5hYmxlLWJhY2tncm91bmQ9Im5ldyAwIDAgNTEyIDUxMiIgeG1sOnNwYWNlPSJwcmVzZXJ2ZSI+PGc+PHBvbHlnb24gZmlsbD0iIzlFQTNBOCIgcG9pbnRzPSIxMTcuNiwyNzIuNyAxNjYuOSwyNzIuNyAxNDIuMywyMDUuNCAiLz48cGF0aCBmaWxsPSIjOUVBM0E4IiBkPSJNNDY0LDU0LjRINDhDMjUuMSw1NC40LDYuNCw3My4xLDYuNCw5NnYzMjBjMCwyMi45LDE4LjcsNDEuNiw0MS42LDQxLjZoNDE2YzIyLjksMCw0MS42LTE4LjcsNDEuNi00MS42Vjk2QzUwNS42LDczLjEsNDg2LjksNTQuNCw0NjQsNTQuNHogTTE5My4zLDM0NS4xbC0xNC45LTQwLjdIMTA2bC0xNC44LDQwLjdINTQuNkwxMjMsMTY2LjloNDAuMkwyMzEsMzQ1LjFIMTkzLjN6IE00MDguMSwzNDUuMWgtMzUuN2wtNDAuNy0xMjYuOUwyOTEsMzQ1LjFoLTM2LjJsLTQ5LjUtMTc4LjJIMjQybDMyLjcsMTIyLjZsMzkuNS0xMjIuNmgzNS45TDM4OS45LDI5MEw0MjIsMTY2LjloMzUuNEw0MDguMSwzNDUuMXoiLz48L2c+PC9zdmc+';
add_menu_page(
__( 'AutomateWoo', 'automatewoo' ),
__( 'AutomateWoo', 'automatewoo' ),
'manage_woocommerce',
'automatewoo',
[ 'AutomateWoo\Admin', 'load_controller' ],
$icon,
$position
);
$sub_menu['dashboard'] = [
'title' => __( 'Dashboard', 'automatewoo' ),
'function' => [ __CLASS__, 'load_controller' ],
];
// Workflows menu group
$sub_menu['workflows'] = [
'title' => __( 'Workflows', 'automatewoo' ),
'slug' => 'edit.php?post_type=aw_workflow',
];
$sub_menu['logs'] = [
'title' => __( 'Logs', 'automatewoo' ),
'function' => [ __CLASS__, 'load_controller' ],
];
$sub_menu['queue'] = [
'title' => __( 'Queue', 'automatewoo' ),
'function' => [ __CLASS__, 'load_controller' ],
];
if ( Options::abandoned_cart_enabled() ) {
$sub_menu['carts'] = [
'title' => __( 'Carts', 'automatewoo' ),
'function' => [ __CLASS__, 'load_controller' ],
];
}
$sub_menu['guests'] = [
'title' => __( 'Guests', 'automatewoo' ),
'function' => [ __CLASS__, 'load_controller' ],
];
$sub_menu['opt-ins'] = [
'title' => Options::optin_enabled() ? __( 'Opt-ins', 'automatewoo' ) : __( 'Opt-outs', 'automatewoo' ),
'function' => [ __CLASS__, 'load_controller' ],
];
$sub_menu['reports'] = [
'title' => __( 'Reports', 'automatewoo' ),
'function' => [ __CLASS__, 'load_controller' ],
'enabled' => ! HPOS_Helper::is_HPOS_enabled(),
];
$sub_menu['tools'] = [
'title' => __( 'Tools', 'automatewoo' ),
'function' => [ __CLASS__, 'load_controller' ],
];
$sub_menu['settings'] = [
'title' => __( 'Settings', 'automatewoo' ),
'function' => [ __CLASS__, 'load_controller' ],
];
$sub_menu['preview'] = [
'title' => __( 'Preview', 'automatewoo' ),
'function' => [ __CLASS__, 'load_controller' ],
];
$sub_menu['data-upgrade'] = [
'title' => __( 'AutomateWoo Data Update', 'automatewoo' ),
'function' => [ __CLASS__, 'page_data_upgrade' ],
];
foreach ( $sub_menu as $key => $item ) {
if ( empty( $item['function'] ) ) {
$item['function'] = '';
}
if ( empty( $item['capability'] ) ) {
$item['capability'] = 'manage_woocommerce';
}
if ( empty( $item['slug'] ) ) {
$item['slug'] = 'automatewoo-' . $key;
}
if ( empty( $item['page_title'] ) ) {
$item['page_title'] = $item['title'];
}
$is_enabled = $item['enabled'] ?? true;
add_submenu_page( $is_enabled ? 'automatewoo' : 'automatewoo_disabled', $item['page_title'], $item['title'], $item['capability'], $item['slug'], $item['function'] );
if ( $key === 'workflows' ) {
do_action( 'automatewoo/admin/submenu_pages', 'automatewoo' );
}
}
if ( WC()->is_wc_admin_active() ) {
wc_admin_register_page(
[
'id' => 'automatewoo-manual-workflow-runner',
'title' => __( 'Manual Workflow Runner', 'automatewoo' ),
'parent' => 'automatewoo',
'path' => '/automatewoo/manual-workflow-runner',
]
);
}
}
/**
* This function alters some items in AutomateWoo submenu
* This is because we need to add .hide-if-js classname in the submenu for hide them in Calypso for wp.com
* The classes are usually loaded in position 4 in the submenu.
*
* @see Menu::migrate_menu_items for a reference of how WC Admin loads this class. (https://github.com/woocommerce/woocommerce/blob/47e4d918c91ea980c41f4567e823256acbac4317/plugins/woocommerce/src/Admin/Features/Navigation/Menu.php#L636)
* @param array $menu Menu items
* @return array Menu items
*/
public static function alter_menu( $menu ) {
global $submenu;
if ( isset( $submenu['automatewoo'] ) ) {
foreach ( $submenu['automatewoo'] as $index => $submenu_item ) {
if (
$submenu_item[0] === 'AutomateWoo' ||
$submenu_item[0] === 'AutomateWoo Data Update' ||
$submenu_item[0] === 'Manual Workflow Runner' ||
$submenu_item[0] === 'Preview'
) {
if ( isset( $submenu_item[4] ) ) {
$submenu_item[4] .= ' hide-if-js'; // if there are some classes already, concat the new one
} else {
$submenu_item[] = 'hide-if-js'; // Otherwise, add the new class
}
// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
$submenu['automatewoo'][ $index ] = $submenu_item;
}
}
}
return $menu;
}
/**
* Highlight the correct top level admin menu item
*/
public static function menu_highlight() {
global $parent_file, $post_type;
switch ( $post_type ) {
case 'aw_workflow':
// phpcs:ignore WordPress.WP.GlobalVariablesOverride.Prohibited
$parent_file = 'automatewoo';
break;
}
}
/**
* Filter to highlight submenu that cannot be handled well in WordPress core.
*
* @param string|null $submenu_file
* @param string $parent_file
*
* @return string|null
*/
public static function submenu_highlight( $submenu_file, $parent_file ) {
// To highlight the "Workflows" submenu for the "Add New Workflow" page,
// it makes the `$submenu_file` match the "Workflows" submenu's slug registered
// in the `self::admin_menu`.
//
// Ref:
// - https://github.com/WordPress/wordpress-develop/blob/5.9.0/src/wp-admin/menu-header.php#L40-L48
// - https://github.com/WordPress/wordpress-develop/blob/5.9.0/src/wp-admin/menu-header.php#L223-L227
if (
$parent_file === 'automatewoo' &&
PageController::get_instance()->get_current_screen_id() === 'aw_workflow-add'
) {
return 'edit.php?post_type=aw_workflow';
}
return $submenu_file;
}
/**
* Register admin scripts.
*/
public static function register_scripts() {
if ( defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) {
$url = AW()->admin_assets_url( '/js' );
$suffix = '';
} else {
$url = AW()->admin_assets_url( '/js/min' );
$suffix = '.min';
}
$is_wc_10_3_plus = version_compare( WC()->version, '10.3.0', '>=' );
$js_cookie_handle = $is_wc_10_3_plus ? 'wc-js-cookie' : 'js-cookie';
$tiptip_handle = $is_wc_10_3_plus ? 'wc-jquery-tiptip' : 'jquery-tiptip';
wp_register_script( $js_cookie_handle, WC()->plugin_url() . "/assets/js/js-cookie/js.cookie{$suffix}.js", [], '2.1.4', true );
wp_register_script( 'automatewoo', "{$url}/automatewoo{$suffix}.js", [ 'jquery', 'jquery-ui-datepicker', $tiptip_handle, 'backbone', 'underscore' ], AW()->version, false );
wp_register_script( 'automatewoo-validate', "{$url}/validate{$suffix}.js", [ 'automatewoo' ], AW()->version, false );
wp_register_script( 'automatewoo-tracks', "{$url}/tracks{$suffix}.js", [ 'automatewoo' ], AW()->version, false );
wp_register_script( 'automatewoo-workflows', "{$url}/workflows{$suffix}.js", [ 'automatewoo', 'automatewoo-validate', 'automatewoo-modal', 'automatewoo-tracks', 'wp-util' ], AW()->version, false );
wp_register_script( 'automatewoo-variables', "{$url}/variables{$suffix}.js", [ 'automatewoo-modal', 'clipboard' ], AW()->version, false );
wp_register_script( 'automatewoo-tools', "{$url}/tools{$suffix}.js", [ 'automatewoo' ], AW()->version, false );
wp_register_script( 'automatewoo-sms-test', "{$url}/sms-test{$suffix}.js", [ 'automatewoo' ], AW()->version, false );
wp_register_script( 'automatewoo-modal', "{$url}/modal{$suffix}.js", [ 'automatewoo' ], AW()->version, false );
wp_register_script( 'automatewoo-rules', "{$url}/rules{$suffix}.js", [ 'automatewoo', 'automatewoo-workflows' ], AW()->version, false );
wp_register_script( 'automatewoo-dashboard', "{$url}/dashboard{$suffix}.js", [ 'automatewoo', 'automatewoo-modal', 'jquery-masonry', 'flot', 'flot-resize', 'flot-time', 'flot-pie', 'flot-stack' ], AW()->version, false );
wp_register_script( 'automatewoo-preview', "{$url}/preview{$suffix}.js", [ 'automatewoo' ], AW()->version, false );
wp_register_script( 'automatewoo-settings', "{$url}/settings{$suffix}.js", [ 'automatewoo' ], AW()->version, false );
global $wp_locale;
wp_localize_script( 'automatewoo-dashboard', 'automatewooDashboardLocalizeScript', [] );
wp_localize_script(
'automatewoo-validate',
'automatewooValidateLocalizedErrorMessages',
[
'noVariablesSupport' => __( 'This field does not support variables.', 'automatewoo' ),
/* translators: Variable name. */
'invalidDataType' => __( "Variable '%s' is not available with the selected trigger. Please only use variables listed in the the variables box.", 'automatewoo' ),
/* translators: Variable name. */
'invalidVariable' => __( "Variable '%s' is not valid. Please only use variables listed in the variables box.", 'automatewoo' ),
'noTrigger' => __( 'Choose a trigger before selecting a variable.', 'automatewoo' ),
]
);
$settings = [
'url' => [
'admin' => admin_url(),
'ajax' => admin_url( 'admin-ajax.php' ),
],
'locale' => [
'month_abbrev' => array_values( $wp_locale->month_abbrev ),
'currency_symbol' => get_woocommerce_currency_symbol(),
'currency_decimal_separator' => wc_get_price_decimal_separator(),
'currency_thousand_separator' => wc_get_price_thousand_separator(),
'currency_position' => get_option( 'woocommerce_currency_pos' ),
],
'nonces' => [
'remove_notice' => wp_create_nonce( 'aw-remove-notice' ),
'aw_dismiss_system_error_notice' => wp_create_nonce( 'aw_dismiss_system_error_notice' ),
'aw_toggle_workflow_status' => wp_create_nonce( 'aw_toggle_workflow_status' ),
],
];
wp_localize_script(
'automatewoo',
'automatewooLocalizeScript',
apply_filters( 'automatewoo/admin/js_settings', $settings )
);
wp_localize_script(
'automatewoo-preview',
'automatewooPreviewLocalizeScript',
[
'nonce' => wp_create_nonce( 'aw_send_test_email' ),
]
);
wp_localize_script(
'automatewoo-sms-test',
'automatewooSmsTestLocalizeScript',
[
'nonce' => wp_create_nonce( 'aw_test_sms' ),
]
);
}
/**
* Register admin styles.
*/
public static function register_styles() {
wp_register_style(
'automatewoo-main',
AW()->admin_assets_url( '/css/aw-main.css' ),
[],
AW()->version
);
wp_register_style( 'automatewoo-preview', AW()->admin_assets_url( '/css/preview.css' ), [], AW()->version );
}
/**
* Enqueue scripts based on screen id
*/
public static function enqueue_scripts_and_styles() {
$screen_id = self::get_current_screen_id();
$is_aw_screen = self::is_automatewoo_screen();
// Load WC Admin styles for AW pages before our own styles
if ( defined( 'WC_ADMIN_APP' ) && $is_aw_screen ) {
wp_enqueue_style( WC_ADMIN_APP );
}
wp_enqueue_script( 'automatewoo' );
wp_enqueue_style( 'automatewoo-main' );
if ( self::should_react_ui_be_loaded() ) {
wp_enqueue_style(
'automatewoo-webpack',
AW()->admin_assets_url( '/build/index.css' ),
[ 'wc-admin-app' ],
AW()->version
);
}
if ( $is_aw_screen ) {
$is_wc_10_3_plus = version_compare( WC()->version, '10.3.0', '>=' );
$js_cookie_handle = $is_wc_10_3_plus ? 'wc-js-cookie' : 'js-cookie';
$tiptip_handle = $is_wc_10_3_plus ? 'wc-jquery-tiptip' : 'jquery-tiptip';
wp_enqueue_script( 'woocommerce_admin' );
wp_enqueue_script( 'wc-enhanced-select' );
wp_enqueue_script( $tiptip_handle );
wp_enqueue_script( 'jquery-ui-sortable' );
wp_enqueue_script( 'jquery-ui-autocomplete' );
wp_enqueue_script( $js_cookie_handle );
wp_enqueue_style( 'woocommerce_admin_styles' );
wp_enqueue_style( 'jquery-ui-style' );
}
if ( $screen_id === 'automatewoo_page_automatewoo-preview' ) {
wp_enqueue_script( 'automatewoo-preview' );
wp_enqueue_style( 'automatewoo-preview' );
}
}
/**
* Should the react UI load?
*
* If the current page is an AW php page or a WC Admin JS-powered page, then yes.
*
* @since 5.1.2
*
* @return bool
*/
protected static function should_react_ui_be_loaded() {
return WC()->is_wc_admin_active() && ( self::is_automatewoo_screen() || wc_admin_is_registered_page() );
}
/**
* Load react powered admin JS.
*
* @since 5.0.0
*/
public static function load_react_ui_scripts() {
if ( ! self::should_react_ui_be_loaded() ) {
return;
}
$asset_file_path = AW()->admin_path() . '/assets/build/index.asset.php';
if ( ! file_exists( $asset_file_path ) ) {
return;
}
$asset_file = (array) include $asset_file_path;
$dependencies = isset( $asset_file['dependencies'] ) ? $asset_file['dependencies'] : [];
// Depend on main admin script for plugin settings
$dependencies = array_merge( $dependencies, [ 'jquery', 'automatewoo', 'wc-settings' ] );
$version = isset( $asset_file['version'] ) ? $asset_file['version'] : false;
$handle = 'automatewoo-react-ui';
wp_enqueue_script(
$handle,
AW()->admin_assets_url() . '/build/index.js',
$dependencies,
$version,
true
);
wp_set_script_translations( $handle, 'automatewoo', AW()->path( '/languages' ) );
}
/**
* Return filtered screen ids.
*
* @return array List of screen ids.
*/
public static function screen_ids() {
$ids = [];
$prefix = 'automatewoo_page_automatewoo';
$ids[] = "$prefix-dashboard";
$ids[] = "$prefix-logs";
$ids[] = "$prefix-reports";
$ids[] = "$prefix-settings";
$ids[] = "$prefix-tools";
$ids[] = "$prefix-carts";
$ids[] = "$prefix-queue";
$ids[] = "$prefix-guests";
$ids[] = "$prefix-opt-ins";
$ids[] = "$prefix-preview";
$ids[] = 'aw_workflow';
$ids[] = 'edit-aw_workflow';
return apply_filters( 'automatewoo/admin/screen_ids', $ids );
}
/**
* Add AW screens to the woocommerce screen IDs list.
* Important for admin script loading.
*
* @since 4.4.2
*
* @param array $screen_ids
*
* @return array
*/
public static function filter_woocommerce_screen_ids( $screen_ids ) {
$screen_ids = array_merge( $screen_ids, self::screen_ids() );
return $screen_ids;
}
/**
* Hide the WC footer message on AW screens.
*
* @since 4.4.2
*
* @param bool $display
*
* @return bool
*/
public static function filter_woocommerce_display_footer_text( $display ) {
if ( self::is_automatewoo_screen() ) {
$display = false;
}
return $display;
}
/**
* Remove the WC help tab on AW screens
*
* @since 4.4.2
*/
public static function remove_woocommerce_help_tab() {
if ( self::is_automatewoo_screen() ) {
$screen = get_current_screen();
$screen->remove_help_tabs();
}
}
/**
* Dynamic replace top level menu
*/
public static function replace_top_level_menu() {
?>
<script type="text/javascript">
jQuery('#adminmenu').find('a.toplevel_page_automatewoo').attr('href', '<?php echo esc_url( self::page_url( 'dashboard' ) ); ?>');
</script>
<?php
}
/**
* Return a page URL based on page type.
*
* @param string $page
* @param bool|int $id
* @return false|string
*/
public static function page_url( $page, $id = false ) {
switch ( $page ) {
case 'dashboard':
return admin_url( 'admin.php?page=automatewoo-dashboard' );
case 'workflows':
return admin_url( 'edit.php?post_type=aw_workflow' );
case 'workflow-presets':
return admin_url( 'edit.php?post_type=aw_workflow#presets' );
case 'settings':
return admin_url( 'admin.php?page=automatewoo-settings' );
case 'settings-bitly':
return admin_url( 'admin.php?page=automatewoo-settings&tab=bitly' );
case 'logs':
return admin_url( 'admin.php?page=automatewoo-logs' );
case 'queue':
return admin_url( 'admin.php?page=automatewoo-queue' );
case 'guests':
return admin_url( 'admin.php?page=automatewoo-guests' );
case 'guest':
return admin_url( "admin.php?page=automatewoo-guests&action=view&guest_id=$id" );
case 'email-tracking':
return admin_url( 'admin.php?page=automatewoo-reports&tab=email-tracking' );
case 'carts':
return admin_url( 'admin.php?page=automatewoo-carts' );
case 'opt-ins':
return admin_url( 'admin.php?page=automatewoo-opt-ins' );
case 'conversions':
return admin_url( 'admin.php?page=automatewoo-reports&tab=conversions' );
case 'workflows-report':
return admin_url( 'admin.php?page=automatewoo-reports&tab=runs-by-date' );
case 'tools':
return admin_url( 'admin.php?page=automatewoo-tools' );
case 'tool-optin-importer':
return admin_url( 'admin.php?page=automatewoo-tools&action=view&tool_id=optin_importer' );
case 'tool-optout-importer':
return admin_url( 'admin.php?page=automatewoo-tools&action=view&tool_id=optout_importer' );
case 'status':
return admin_url( 'admin.php?page=automatewoo-settings&tab=status' );
case 'manual-workflow-runner':
$url = admin_url( 'admin.php?page=wc-admin&path=/automatewoo/manual-workflow-runner' );
if ( $id ) {
// SEMGREP WARNING EXPLANATION
// URL is escaped. However, Semgrep only considers esc_url as valid.
return esc_url_raw( add_query_arg( 'workflowId', $id, $url ) );
}
return $url;
case 'analytics':
$url = admin_url( 'admin.php?page=wc-admin&path=/analytics/automatewoo-' . $id );
return $url;
case 'documentation':
return 'https://woocommerce.com/document/automatewoo/?utm_source=wordpress&utm_medium=all-plugins-page&utm_campaign=doc-link&utm_content=automatewoo';
}
return false;
}
/**
* Data upgrade page.
*/
public static function page_data_upgrade() {
self::get_view( 'page-data-upgrade' );
}
/**
* Get a view.
*
* Both calling extract and include are based off of the methods used in `wc_get_template`.
*
* @param string $view
* @param array $imported_variables
* @param mixed $path
*/
public static function get_view( $view, $imported_variables = [], $path = false ) {
if ( $imported_variables && is_array( $imported_variables ) ) {
extract( $imported_variables ); // phpcs:ignore WordPress.PHP.DontExtract.extract_extract
}
if ( ! $path ) {
$path = AW()->admin_path( '/views/' );
}
include "{$path}{$view}.php"; // nosemgrep No user input reached. This is for loading our views.
}
/**
* Load controller.
*/
public static function load_controller() {
$screen_id = self::get_screen_id();
if ( ! $screen_id ) {
return;
}
if ( $screen_id === 'toplevel_page_automatewoo' ) {
$screen_id = 'dashboard';
}
$controller = Admin\Controllers::get( $screen_id );
if ( $controller ) {
$controller->handle();
}
}
/**
* Get the current screen ID.
*
* @return string|bool
*/
public static function get_screen_id() {
$screen_id = self::get_current_screen_id();
// Replace hidden screen ID's without AutomateWoo as parent.
$screen_id = str_replace( 'admin_page_automatewoo-', '', $screen_id );
if ( ! $screen_id ) {
return false;
}
$base_screen = sanitize_title( __( 'AutomateWoo', 'automatewoo' ) ); // required if plugin name was translated
return str_replace( $base_screen . '_page_automatewoo-', '', $screen_id );
}
/**
* Save settings on wp_loaded
*/
public static function save_settings() {
$controller = Admin\Controllers::get( 'settings' );
if ( $controller ) {
$controller->save();
}
}
/**
* Check if we are on a specific page.
*
* @param string $page
* @return bool
*/
public static function is_page( $page ) {
$current_page = Clean::string( aw_request( 'page' ) );
$current_tab = Clean::string( aw_request( 'tab' ) );
switch ( $page ) {
case 'dashboard':
return $current_page === 'automatewoo-dashboard';
case 'settings':
return $current_page === 'automatewoo-settings';
case 'reports':
return $current_page === 'automatewoo-reports';
case 'status':
return $current_page === 'automatewoo-settings' && $current_tab === 'status';
}
return false;
}
/**
* Display an admin notice.
*
* @param string $type (warning,error,success)
* @param string $strong highlighted notice content (text or html)
* @param string $more notice content (text or html)
* @param string $classes extra classes to add to the notice (eg., is-dismissible)
* @param string $button_text text to display on the primary button (not displayed if empty)
* @param string $button_link link for the button (not displayed if empty)
* @param string $button_class extra classes to add to the button
*/
public static function notice( $type, $strong, $more = '', $classes = '', $button_text = '', $button_link = '', $button_class = '' ) {
self::get_view(
'simple-notice',
[
'type' => $type,
'class' => $classes,
'strong' => $strong,
'message' => $more,
'button_text' => $button_text,
'button_link' => $button_link,
'button_class' => $button_class,
]
);
}
/**
* Add WooCommerce Reports screen IDs.
*
* @param array $ids
* @return array
*/
public static function inject_woocommerce_reports_screen_ids( $ids ) {
$ids[] = 'automatewoo_page_automatewoo-reports';
return $ids;
}
/**
* Add editor styles.
*
* @param array $stylesheets
* @return array
*/
public static function add_editor_styles( $stylesheets ) {
$stylesheets[] = AW()->admin_assets_url( '/css/editor.css' );
return $stylesheets;
}
/**
* Add a meta box.
*
* @param string $id
* @param string $title
* @param callable $callback
* @param null $screen
* @param string $context
* @param string $priority
* @param null $callback_args
*/
public static function add_meta_box( $id, $title, $callback, $screen = null, $context = 'advanced', $priority = 'default', $callback_args = null ) {
$id = 'aw_' . $id;
add_meta_box( $id, $title, $callback, $screen, $context, $priority, $callback_args );
add_filter( "postbox_classes_{$screen}_{$id}", [ __CLASS__, 'inject_postbox_class' ] );
}
/**
* Add postbox class.
*
* @param array $classes
*
* @return array
*/
public static function inject_postbox_class( $classes ) {
$classes[] = 'automatewoo-metabox';
$classes[] = 'no-drag';
return $classes;
}
/**
* Add hidden form inputs.
*
* @param array $vars
*/
public static function get_hidden_form_inputs_from_query( $vars ) {
foreach ( $vars as $var ) {
// Adding a nonce is handled by the calling functions.
// Validating of sanatized input is done when the values are read (we are copying the values here).
// phpcs:disable WordPress.Security.NonceVerification.Recommended, WordPress.Security.ValidatedSanitizedInput
if ( empty( $_GET[ $var ] ) ) {
continue;
}
echo '<input type="hidden" name="' . esc_attr( $var ) . '" value="' . esc_attr( $_GET[ $var ] ) . '">';
// phpcs:enable
}
}
/**
* Display a help tip.
*
* @param string $tip The tip to display. Not expected to be escaped.
* @param bool $pull_right Whether the tip should include the automatewoo-help-tip--right class
*/
public static function help_tip( $tip, $pull_right = true ) {
$tip = wc_sanitize_tooltip( $tip );
if ( empty( $tip ) ) {
return;
}
$classes = array_filter(
[
'automatewoo-help-tip',
'woocommerce-help-tip',
$pull_right ? 'automatewoo-help-tip--right' : '',
]
);
printf( '<span class="%1$s" data-tip="%2$s"></span>', esc_attr( join( ' ', $classes ) ), esc_attr( $tip ) );
}
/**
* Return an AutomateWoo badge.
*
* @param string $type
* @param string $dashicon
* @param bool $tip
* @return string
*/
public static function badge( $type, $dashicon, $tip = false ) {
$html = '<span class="automatewoo-badge automatewoo-badge--' . $type . ' automatewoo-tiptip" data-tip="' . esc_attr( $tip ) . '">';
$html .= '<span class="dashicons dashicons-' . $dashicon . '"></span>';
$html .= '</span>';
return $html;
}
/**
* Get a help link.
*
* @param string $url
* @param bool $pull_right
* @return string
*/
public static function help_link( $url, $pull_right = true ) {
return '<a href="' . esc_url( $url ) . '" class="automatewoo-help-link ' . ( $pull_right ? 'automatewoo-help-link--right' : '' ) . '" target="_blank"></a>';
}
/**
* Get documentation link.
*
* @param string $page
* @param string|bool $utm_source
* @param string|bool $utm_campaign
* @return string
*/
public static function get_docs_link( $page = '', $utm_source = false, $utm_campaign = false ) {
return esc_url_raw( self::get_website_link( "docs/$page", $utm_source, $utm_campaign ) );
}
/**
* Get a website link.
*
* @param string $page
* @param string|bool $utm_source
* @param string|bool $utm_campaign
* @return string
*/
public static function get_website_link( $page = '', $utm_source = false, $utm_campaign = false ) {
$url = 'https://automatewoo.com/' . ( $page ? trailingslashit( $page ) : '' );
if ( $utm_source ) {
// SEMGREP WARNING EXPLANATION
// This is escaped in the consumer function.
$url = add_query_arg(
[
'utm_source' => $utm_source,
'utm_medium' => 'plugin',
'utm_campaign' => $utm_campaign ? $utm_campaign : 'plugin-links',
],
$url
);
}
return $url;
}
/**
* Get WooCommerce.com marketplace product link.
*
* @since 3.7.0
*
* @param string $product
*
* @return string
*/
public static function get_marketplace_product_link( $product = 'automatewoo' ) {
return "https://woocommerce.com/products/$product/";
}
/**
* Output loader
*/
public static function cache_preview_loader() {
// phpcs:disable WordPress.PHP.NoSilencedErrors.Discouraged
@header_remove( 'Cache-Control' );
@header( 'Expires: ' . gmdate( 'D, d M Y H:i:s', time() + DAY_IN_SECONDS ) . ' GMT' );
// phpcs:enable
}
/**
* Create a new page.
*
* @param string $slug
* @param string $page_title
* @param string $page_content
* @param string $option
* @return int|bool Page ID
*/
public static function create_page( $slug, $page_title, $page_content, $option ) {
if ( get_option( $option ) ) {
return false; // page is already defined in settings
}
$page_data = [
'post_status' => 'publish',
'post_type' => 'page',
'post_author' => 1,
'post_name' => $slug,
'post_title' => $page_title,
'post_content' => $page_content,
'comment_status' => 'closed',
];
$page_id = wp_insert_post( $page_data );
update_option( $option, $page_id, false );
return $page_id;
}
/**
* Return the current WP screen ID.
*
* @since 4.4.2
*
* @return bool|string
*/
public static function get_current_screen_id() {
$screen = get_current_screen();
return $screen ? $screen->id : false;
}
/**
* Is the current WP screen an AutomateWoo screen?
*
* @since 4.7.0
* @return bool
*/
public static function is_automatewoo_screen() {
return in_array( self::get_current_screen_id(), self::screen_ids(), true );
}
/**
* Unhook all admin notices.
*
* @since 4.4.0
*/
public static function remove_admin_notices() {
remove_all_actions( 'admin_notices' );
}
/**
* Get marketplace subscriptions tab URL.
*
* @since 4.7.0
*
* @return string
*/
public static function get_marketplace_subscriptions_tab_url() {
return add_query_arg(
[
'page' => 'wc-addons',
'section' => 'helper',
],
admin_url( 'admin.php' )
);
}
/**
* Flush group caches for specific post types.
*
* @since 6.1.6
*
* @param int $post_id
*/
public static function flush_group_caches( int $post_id ) {
$post_type = get_post_type( $post_id );
switch ( $post_type ) {
case 'shop_coupon':
Cache::flush_group( 'coupons' );
break;
case 'aw_workflow':
Cache::flush_group( 'workflows' );
break;
}
}
}