' ); if ( $wordpress_includes_gutenberg ) { $message = sprintf( /* translators: URL of WooCommerce plugin */ __( 'The WooCommerce Admin feature plugin requires WooCommerce 3.5 or greater to be installed and active.', 'woocommerce-admin' ), 'https://wordpress.org/plugins/woocommerce/' ); } else { $message = sprintf( /* translators: 1: URL of WordPress.org, 2: URL of WooCommerce plugin */ __( 'The WooCommerce Admin feature plugin requires both WordPress 5.0 or greater and WooCommerce 3.5 or greater to be installed and active.', 'woocommerce-admin' ), 'https://wordpress.org/', 'https://wordpress.org/plugins/woocommerce/' ); } printf( '

%s

', $message ); /* WPCS: xss ok. */ } /** * Notify users that the plugin needs to be built. */ function wc_admin_build_notice() { $message_one = __( 'You have installed a development version of WooCommerce Admin which requires files to be built. From the plugin directory, run npm install to install dependencies, npm run build to build the files.', 'woocommerce-admin' ); $message_two = sprintf( /* translators: 1: URL of GitHub Repository build page */ __( 'Or you can download a pre-built version of the plugin by visiting the releases page in the repository.', 'woocommerce-admin' ), 'https://github.com/woocommerce/woocommerce-admin/releases' ); printf( '

%s %s

', $message_one, $message_two ); /* WPCS: xss ok. */ } /** * Returns true if all dependencies for the wc-admin plugin are loaded. * * @return bool */ function wc_admin_dependencies_satisfied() { $woocommerce_minimum_met = class_exists( 'WooCommerce' ) && version_compare( WC_VERSION, '3.5', '>' ); if ( ! $woocommerce_minimum_met ) { return false; } $wordpress_version = get_bloginfo( 'version' ); return version_compare( $wordpress_version, '4.9.9', '>' ); } /** * Returns true if build file exists. * * @return bool */ function wc_admin_build_file_exists() { return file_exists( plugin_dir_path( __FILE__ ) . '/dist/app/index.js' ); } /** * Adds a menu item for the wc-admin devdocs. */ function wc_admin_devdocs() { if ( WC_Admin_Loader::is_feature_enabled( 'devdocs' ) && defined( 'WP_DEBUG' ) && WP_DEBUG && defined( 'SCRIPT_DEBUG' ) && SCRIPT_DEBUG ) { wc_admin_register_page( array( 'title' => 'DevDocs', 'parent' => 'woocommerce', 'path' => '/devdocs', ) ); } } add_action( 'admin_menu', 'wc_admin_devdocs' ); /** * Daily events to run. * * Note: WC_Admin_Notes_Order_Milestones::other_milestones is hooked to this as well. */ function wc_admin_do_wc_admin_daily() { WC_Admin_Notes_New_Sales_Record::possibly_add_sales_record_note(); WC_Admin_Notes_Giving_Feedback_Notes::add_notes_for_admin_giving_feedback(); WC_Admin_Notes_Mobile_App::possibly_add_mobile_app_note(); } add_action( 'wc_admin_daily', 'wc_admin_do_wc_admin_daily' ); /** * Initializes wc-admin daily action when plugin activated. */ function wc_admin_activate_wc_admin_plugin() { if ( ! wc_admin_dependencies_satisfied() ) { return; } if ( ! wp_next_scheduled( 'wc_admin_daily' ) ) { wp_schedule_event( time(), 'daily', 'wc_admin_daily' ); } } register_activation_hook( WC_ADMIN_PLUGIN_FILE, 'wc_admin_activate_wc_admin_plugin' ); /** * Deactivate wc-admin plugin if dependencies not satisfied. */ function wc_admin_possibly_deactivate_wc_admin_plugin() { if ( ! wc_admin_dependencies_satisfied() ) { deactivate_plugins( plugin_basename( WC_ADMIN_PLUGIN_FILE ) ); unset( $_GET['activate'] ); } } add_action( 'admin_init', 'wc_admin_possibly_deactivate_wc_admin_plugin' ); /** * On deactivating the wc-admin plugin. */ function wc_admin_deactivate_wc_admin_plugin() { if ( wc_admin_dependencies_satisfied() ) { wp_clear_scheduled_hook( 'wc_admin_daily' ); WC_Admin_Reports_Sync::clear_queued_actions(); } } register_deactivation_hook( WC_ADMIN_PLUGIN_FILE, 'wc_admin_deactivate_wc_admin_plugin' ); /** * Set up the plugin, only if we can detect both Gutenberg and WooCommerce */ function wc_admin_plugins_loaded() { if ( ! wc_admin_dependencies_satisfied() ) { add_action( 'admin_notices', 'wc_admin_plugins_notice' ); return; } // Initialize the WC API extensions. require_once WC_ADMIN_ABSPATH . 'includes/class-wc-admin-reports-sync.php'; require_once WC_ADMIN_ABSPATH . 'includes/class-wc-admin-install.php'; require_once WC_ADMIN_ABSPATH . 'includes/class-wc-admin-api-init.php'; // Admin note providers. // @todo These should be bundled in the features/ folder, but loading them from there currently has a load order issue. require_once WC_ADMIN_ABSPATH . 'includes/notes/class-wc-admin-notes-new-sales-record.php'; require_once WC_ADMIN_ABSPATH . 'includes/notes/class-wc-admin-notes-settings-notes.php'; require_once WC_ADMIN_ABSPATH . 'includes/notes/class-wc-admin-notes-giving-feedback-notes.php'; require_once WC_ADMIN_ABSPATH . 'includes/notes/class-wc-admin-notes-woo-subscriptions-notes.php'; require_once WC_ADMIN_ABSPATH . 'includes/notes/class-wc-admin-notes-historical-data.php'; require_once WC_ADMIN_ABSPATH . 'includes/notes/class-wc-admin-notes-order-milestones.php'; require_once WC_ADMIN_ABSPATH . 'includes/notes/class-wc-admin-notes-mobile-app.php'; require_once WC_ADMIN_ABSPATH . 'includes/notes/class-wc-admin-notes-welcome-message.php'; // Verify we have a proper build. if ( ! wc_admin_build_file_exists() ) { add_action( 'admin_notices', 'wc_admin_build_notice' ); return; } } add_action( 'plugins_loaded', 'wc_admin_plugins_loaded' ); /** * Overwrites the allowed features array using a local `feature-config.php` file. * * @param array $features Array of feature slugs. */ function wc_admin_overwrite_features( $features ) { if ( ! function_exists( 'wc_admin_get_feature_config' ) ) { require_once WC_ADMIN_ABSPATH . '/includes/feature-config.php'; } $feature_config = wc_admin_get_feature_config(); $features = array_keys( array_filter( $feature_config ) ); return $features; } add_filter( 'woocommerce_admin_features', 'wc_admin_overwrite_features' ); /* * Remove the emoji script as it always defaults to replacing emojis with Twemoji images. * Gutenberg has also disabled emojis. More on that here -> https://github.com/WordPress/gutenberg/pull/6151 */ remove_action( 'admin_print_scripts', 'print_emoji_detection_script' ); /** * Filter in our ActionScheduler Store class. * * @param string $store_class ActionScheduler Store class name. * @return string ActionScheduler Store class name. */ function wc_admin_set_actionscheduler_store_class( $store_class ) { // Don't override any other overrides. if ( 'ActionScheduler_wpPostStore' !== $store_class ) { return $store_class; } // Include our store class here instead of wc_admin_plugins_loaded() // because ActionScheduler is hooked into `plugins_loaded` at a // much higher priority. require_once WC_ADMIN_ABSPATH . '/includes/class-wc-admin-actionscheduler-wppoststore.php'; return 'WC_Admin_ActionScheduler_WPPostStore'; } // Hook up our modified ActionScheduler Store. add_filter( 'action_scheduler_store_class', 'wc_admin_set_actionscheduler_store_class' ); /** * Load plugin text domain for translations. */ function wc_admin_load_plugin_textdomain() { load_plugin_textdomain( 'woocommerce-admin', false, basename( dirname( __FILE__ ) ) . '/languages' ); } add_action( 'plugins_loaded', 'wc_admin_load_plugin_textdomain' ); /** * Format a number using the decimal and thousands separator settings in WooCommerce. * * @param mixed $number Number to be formatted. * @return string */ function wc_admin_number_format( $number ) { $currency_settings = WC_Admin_Loader::get_currency_settings(); return number_format( $number, 0, $currency_settings['decimal_separator'], $currency_settings['thousand_separator'] ); } /** * Retrieves a URL to relative path inside WooCommerce admin with * the provided query parameters. * * @param string $path Relative path of the desired page. * @param array $query Query parameters to append to the path. * * @return string Fully qualified URL pointing to the desired path. */ function wc_admin_url( $path, $query = array() ) { if ( ! empty( $query ) ) { $query_string = http_build_query( $query ); $path = $path . '?' . $query_string; } return admin_url( 'admin.php?page=wc-admin#' . $path, dirname( __FILE__ ) ); }