auto-patch 638-dev-dev01-2024-05-14T20_44_36
This commit is contained in:
@@ -51,7 +51,6 @@ class Init {
|
||||
add_filter( 'woocommerce_rest_prepare_shop_order_object', array( __CLASS__, 'add_currency_symbol_to_order_response' ) );
|
||||
|
||||
include_once WC_ABSPATH . 'includes/admin/class-wc-admin-upload-downloadable-product.php';
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -105,6 +104,10 @@ class Init {
|
||||
$product_form_controllers[] = 'Automattic\WooCommerce\Admin\API\ProductForm';
|
||||
}
|
||||
|
||||
if ( Features::is_enabled( 'launch-your-store' ) ) {
|
||||
$controllers[] = 'Automattic\WooCommerce\Admin\API\LaunchYourStore';
|
||||
}
|
||||
|
||||
if ( Features::is_enabled( 'analytics' ) ) {
|
||||
$analytics_controllers = array(
|
||||
'Automattic\WooCommerce\Admin\API\Customers',
|
||||
@@ -134,8 +137,7 @@ class Init {
|
||||
|
||||
// The performance indicators controller must be registered last, after other /stats endpoints have been registered.
|
||||
$analytics_controllers[] = 'Automattic\WooCommerce\Admin\API\Reports\PerformanceIndicators\Controller';
|
||||
|
||||
$controllers = array_merge( $controllers, $analytics_controllers, $product_form_controllers );
|
||||
$controllers = array_merge( $controllers, $analytics_controllers, $product_form_controllers );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -190,8 +192,8 @@ class Init {
|
||||
* object in REST API responses. For use in formatAmount().
|
||||
*
|
||||
* @internal
|
||||
* @param {WP_REST_Response} $response REST response object.
|
||||
* @returns {WP_REST_Response}
|
||||
* @param WP_REST_Response $response REST response object.
|
||||
* @returns WP_REST_Response
|
||||
*/
|
||||
public static function add_currency_symbol_to_order_response( $response ) {
|
||||
$response_data = $response->get_data();
|
||||
|
||||
@@ -0,0 +1,98 @@
|
||||
<?php
|
||||
/**
|
||||
* REST API Launch Your Store Controller
|
||||
*
|
||||
* Handles requests to /launch-your-store/*
|
||||
*/
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\API;
|
||||
|
||||
use Automattic\WooCommerce\Admin\WCAdminHelper;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Launch Your Store controller.
|
||||
*
|
||||
* @internal
|
||||
*/
|
||||
class LaunchYourStore {
|
||||
|
||||
/**
|
||||
* Endpoint namespace.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $namespace = 'wc-admin';
|
||||
|
||||
/**
|
||||
* Route base.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $rest_base = 'launch-your-store';
|
||||
|
||||
/**
|
||||
* Register routes.
|
||||
*/
|
||||
public function register_routes() {
|
||||
register_rest_route(
|
||||
$this->namespace,
|
||||
'/' . $this->rest_base . '/initialize-coming-soon',
|
||||
array(
|
||||
array(
|
||||
'methods' => 'POST',
|
||||
'callback' => array( $this, 'initialize_coming_soon' ),
|
||||
'permission_callback' => array( $this, 'must_be_shop_manager_or_admin' ),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* User must be either shop_manager or administrator.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function must_be_shop_manager_or_admin() {
|
||||
// phpcs:ignore
|
||||
if ( ! current_user_can( 'manage_woocommerce' ) && ! current_user_can( 'administrator' ) ) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Initializes options for coming soon. Does not override if options exist.
|
||||
*
|
||||
* @return bool|void
|
||||
*/
|
||||
public function initialize_coming_soon() {
|
||||
$current_user_id = get_current_user_id();
|
||||
// Abort if we don't have a user id for some reason.
|
||||
if ( ! $current_user_id ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$coming_soon = 'yes';
|
||||
$store_pages_only = WCAdminHelper::is_site_fresh() ? 'no' : 'yes';
|
||||
$private_link = 'no';
|
||||
$share_key = wp_generate_password( 32, false );
|
||||
|
||||
add_option( 'woocommerce_coming_soon', $coming_soon );
|
||||
add_option( 'woocommerce_store_pages_only', $store_pages_only );
|
||||
add_option( 'woocommerce_private_link', $private_link );
|
||||
add_option( 'woocommerce_share_key', $share_key );
|
||||
|
||||
wc_admin_record_tracks_event(
|
||||
'launch_your_store_initialize_coming_soon',
|
||||
array(
|
||||
'coming_soon' => $coming_soon,
|
||||
'store_pages_only' => $store_pages_only,
|
||||
'private_link' => $private_link,
|
||||
)
|
||||
);
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -132,6 +132,57 @@ class MarketingCampaigns extends WC_REST_Controller {
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get formatted price based on Price type.
|
||||
*
|
||||
* This uses plugins/woocommerce/i18n/currency-info.php and plugins/woocommerce/i18n/locale-info.php to get option object based on $price->currency.
|
||||
*
|
||||
* Example:
|
||||
*
|
||||
* - When $price->currency is 'USD' and $price->value is '1000', it should return '$1000.00'.
|
||||
* - When $price->currency is 'JPY' and $price->value is '1000', it should return '¥1,000'.
|
||||
* - When $price->currency is 'AED' and $price->value is '1000', it should return '5.000,00 د.إ'.
|
||||
*
|
||||
* @param Price $price Price object.
|
||||
* @return String formatted price.
|
||||
*/
|
||||
private function get_formatted_price( $price ) {
|
||||
// Get $num_decimals to be passed to wc_price.
|
||||
$locale_info_all = include WC()->plugin_path() . '/i18n/locale-info.php';
|
||||
$locale_index = array_search( $price->get_currency(), array_column( $locale_info_all, 'currency_code' ), true );
|
||||
$locale = array_values( $locale_info_all )[ $locale_index ];
|
||||
$num_decimals = $locale['num_decimals'];
|
||||
|
||||
// Get $currency_info based on user locale or default locale.
|
||||
$currency_locales = $locale['locales'];
|
||||
$user_locale = get_user_locale();
|
||||
$currency_info = $currency_locales[ $user_locale ] ?? $currency_locales['default'];
|
||||
|
||||
// Get $price_format to be passed to wc_price.
|
||||
$currency_pos = $currency_info['currency_pos'];
|
||||
$currency_formats = array(
|
||||
'left' => '%1$s%2$s',
|
||||
'right' => '%2$s%1$s',
|
||||
'left_space' => '%1$s %2$s',
|
||||
'right_space' => '%2$s %1$s',
|
||||
);
|
||||
$price_format = $currency_formats[ $currency_pos ] ?? $currency_formats['left'];
|
||||
|
||||
$price_value = wc_format_decimal( $price->get_value() );
|
||||
$price_formatted = wc_price(
|
||||
$price_value,
|
||||
array(
|
||||
'currency' => $price->get_currency(),
|
||||
'decimal_separator' => $currency_info['decimal_sep'],
|
||||
'thousand_separator' => $currency_info['thousand_sep'],
|
||||
'decimals' => $num_decimals,
|
||||
'price_format' => $price_format,
|
||||
)
|
||||
);
|
||||
|
||||
return html_entity_decode( wp_strip_all_tags( $price_formatted ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Prepares the item for the REST response.
|
||||
*
|
||||
@@ -150,15 +201,17 @@ class MarketingCampaigns extends WC_REST_Controller {
|
||||
|
||||
if ( $item->get_cost() instanceof Price ) {
|
||||
$data['cost'] = array(
|
||||
'value' => wc_format_decimal( $item->get_cost()->get_value() ),
|
||||
'currency' => $item->get_cost()->get_currency(),
|
||||
'value' => wc_format_decimal( $item->get_cost()->get_value() ),
|
||||
'currency' => $item->get_cost()->get_currency(),
|
||||
'formatted' => $this->get_formatted_price( $item->get_cost() ),
|
||||
);
|
||||
}
|
||||
|
||||
if ( $item->get_sales() instanceof Price ) {
|
||||
$data['sales'] = array(
|
||||
'value' => wc_format_decimal( $item->get_sales()->get_value() ),
|
||||
'currency' => $item->get_sales()->get_currency(),
|
||||
'value' => wc_format_decimal( $item->get_sales()->get_value() ),
|
||||
'currency' => $item->get_sales()->get_currency(),
|
||||
'formatted' => $this->get_formatted_price( $item->get_sales() ),
|
||||
);
|
||||
}
|
||||
|
||||
@@ -257,6 +310,4 @@ class MarketingCampaigns extends WC_REST_Controller {
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@@ -82,7 +82,7 @@ class OnboardingFreeExtensions extends WC_REST_Data_Controller {
|
||||
/**
|
||||
* Allows removing Jetpack suggestions from WooCommerce Admin when false.
|
||||
*
|
||||
* In this instance it is removed from the list of extensions suggested in the Onboarding Profiler. This list is first retrieved from the Woo.com API, then if a plugin with the 'jetpack' slug is found, it is removed.
|
||||
* In this instance it is removed from the list of extensions suggested in the Onboarding Profiler. This list is first retrieved from the WooCommerce.com API, then if a plugin with the 'jetpack' slug is found, it is removed.
|
||||
*
|
||||
* @since 7.8
|
||||
*/
|
||||
|
||||
@@ -409,14 +409,14 @@ class OnboardingProfile extends \WC_REST_Data_Controller {
|
||||
),
|
||||
'wccom_connected' => array(
|
||||
'type' => 'boolean',
|
||||
'description' => __( 'Whether or not the store was connected to Woo.com during the extension flow.', 'woocommerce' ),
|
||||
'description' => __( 'Whether or not the store was connected to WooCommerce.com during the extension flow.', 'woocommerce' ),
|
||||
'context' => array( 'view' ),
|
||||
'readonly' => true,
|
||||
'validate_callback' => 'rest_validate_request_arg',
|
||||
),
|
||||
'is_agree_marketing' => array(
|
||||
'type' => 'boolean',
|
||||
'description' => __( 'Whether or not this store agreed to receiving marketing contents from Woo.com.', 'woocommerce' ),
|
||||
'description' => __( 'Whether or not this store agreed to receiving marketing contents from WooCommerce.com.', 'woocommerce' ),
|
||||
'context' => array( 'view' ),
|
||||
'readonly' => true,
|
||||
'validate_callback' => 'rest_validate_request_arg',
|
||||
|
||||
@@ -740,14 +740,6 @@ class OnboardingTasks extends \WC_REST_Data_Controller {
|
||||
|
||||
$lists = is_array( $task_list_ids ) && count( $task_list_ids ) > 0 ? TaskLists::get_lists_by_ids( $task_list_ids ) : TaskLists::get_lists();
|
||||
|
||||
// We have no use for hidden lists, it's expensive to compute individual tasks completion.
|
||||
$lists = array_filter(
|
||||
$lists,
|
||||
function( $list ) {
|
||||
return ! $list->is_hidden();
|
||||
}
|
||||
);
|
||||
|
||||
$json = array_map(
|
||||
function( $list ) {
|
||||
return $list->sort_tasks()->get_json();
|
||||
|
||||
@@ -249,9 +249,135 @@ class OnboardingThemes extends \WC_REST_Data_Controller {
|
||||
);
|
||||
}
|
||||
|
||||
$in_app_purchase_params = \WC_Admin_Addons::get_in_app_purchase_url_params();
|
||||
$in_app_purchase_params['wccom-back'] = rawurlencode( '/wp-admin/admin.php?page=wc-admin&path=/customize-store' );
|
||||
|
||||
$core_themes = array(
|
||||
array(
|
||||
'name' => 'Twenty Twenty-Four',
|
||||
'price' => 'Free',
|
||||
'color_palettes' => array(
|
||||
array(
|
||||
'title' => 'Black and white',
|
||||
'primary' => '#FEFBF3',
|
||||
'secondary' => '#7F7E7A',
|
||||
),
|
||||
array(
|
||||
'title' => 'Brown Sugar',
|
||||
'primary' => '#EFEBE0',
|
||||
'secondary' => '#AC6239',
|
||||
),
|
||||
array(
|
||||
'title' => 'Midnight',
|
||||
'primary' => '#161514',
|
||||
'secondary' => '#AFADA7',
|
||||
),
|
||||
array(
|
||||
'title' => 'Olive',
|
||||
'primary' => '#FEFBF3',
|
||||
'secondary' => '#7F7E7A',
|
||||
),
|
||||
),
|
||||
'total_palettes' => 0,
|
||||
'slug' => 'twentytwentyfour',
|
||||
'thumbnail_url' => 'https://i0.wp.com/themes.svn.wordpress.org/twentytwentyfour/1.0/screenshot.png',
|
||||
'link_url' => 'https://wordpress.org/themes/twentytwentyfour/',
|
||||
),
|
||||
array(
|
||||
'name' => 'Highline',
|
||||
'price' => '$79/year',
|
||||
'color_palettes' => array(
|
||||
array(
|
||||
'title' => 'Primary',
|
||||
'primary' => '#211f1d',
|
||||
'secondary' => '#211f1d',
|
||||
),
|
||||
array(
|
||||
'title' => 'Additional color',
|
||||
'primary' => '#aaaaaa',
|
||||
'secondary' => '#aaaaaa',
|
||||
),
|
||||
array(
|
||||
'title' => 'Accent Background',
|
||||
'primary' => '#b04b3c',
|
||||
'secondary' => '#b04b3c',
|
||||
),
|
||||
array(
|
||||
'title' => 'Secondary Background',
|
||||
'primary' => '#dabfa1',
|
||||
'secondary' => '#dabfa1',
|
||||
),
|
||||
),
|
||||
'total_palettes' => 9,
|
||||
'slug' => 'highline',
|
||||
'thumbnail_url' => 'https://woocommerce.com/wp-content/uploads/2023/12/Featured-image-538x403-1.png',
|
||||
'link_url' => add_query_arg( $in_app_purchase_params, 'https://woocommerce.com/products/highline/' ),
|
||||
),
|
||||
array(
|
||||
'name' => 'Luminate',
|
||||
'price' => '$79/year',
|
||||
'color_palettes' => array(
|
||||
array(
|
||||
'title' => 'Primary',
|
||||
'primary' => '#242a2e',
|
||||
'secondary' => '#242a2e',
|
||||
),
|
||||
array(
|
||||
'title' => 'Lite',
|
||||
'primary' => '#f6f5f2',
|
||||
'secondary' => '#f6f5f2',
|
||||
),
|
||||
array(
|
||||
'title' => 'Grey',
|
||||
'primary' => '#a5a5a5',
|
||||
'secondary' => '#a5a5a5',
|
||||
),
|
||||
array(
|
||||
'title' => 'Lite Grey',
|
||||
'primary' => '#e4e4e1',
|
||||
'secondary' => '#e4e4e1',
|
||||
),
|
||||
),
|
||||
'total_palettes' => 5,
|
||||
'slug' => 'luminate',
|
||||
'thumbnail_url' => 'https://woocommerce.com/wp-content/uploads/2022/07/Featured-image-538x403-2.png',
|
||||
'link_url' => add_query_arg( $in_app_purchase_params, 'https://woocommerce.com/products/luminate/' ),
|
||||
),
|
||||
array(
|
||||
'name' => 'Nokul',
|
||||
'price' => '$79/year',
|
||||
'color_palettes' => array(
|
||||
array(
|
||||
'title' => 'Foreground and background',
|
||||
'primary' => '#000000',
|
||||
'secondary' => '#f1eee2',
|
||||
),
|
||||
array(
|
||||
'title' => 'Foreground and secondary',
|
||||
'primary' => '#000000',
|
||||
'secondary' => '#999999',
|
||||
),
|
||||
array(
|
||||
'title' => 'Foreground and accent',
|
||||
'primary' => '#000000',
|
||||
'secondary' => '#d82f16',
|
||||
),
|
||||
array(
|
||||
'title' => 'Primary and background',
|
||||
'primary' => '#d9d0bf',
|
||||
'secondary' => '#f1eee2',
|
||||
),
|
||||
),
|
||||
'total_palettes' => 6,
|
||||
'slug' => 'nokul',
|
||||
'thumbnail_url' => 'https://woocommerce.com/wp-content/uploads/2022/11/Product-logo.jpg',
|
||||
'link_url' => add_query_arg( $in_app_purchase_params, 'https://woocommerce.com/products/nokul/' ),
|
||||
),
|
||||
);
|
||||
|
||||
// To be implemented: 1. Fetch themes from the marketplace API. 2. Convert prices to the requested currency.
|
||||
// These are Dotcom themes.
|
||||
$themes = array(
|
||||
$default_themes = array(
|
||||
array(
|
||||
'name' => 'Tsubaki',
|
||||
'price' => 'Free',
|
||||
@@ -269,7 +395,6 @@ class OnboardingThemes extends \WC_REST_Data_Controller {
|
||||
'slug' => 'tazza',
|
||||
'thumbnail_url' => 'https://i0.wp.com/s2.wp.com/wp-content/themes/premium/tazza/screenshot.png',
|
||||
'link_url' => 'https://wordpress.com/theme/tazza/',
|
||||
'total_palettes' => 0,
|
||||
),
|
||||
array(
|
||||
'name' => 'Amulet',
|
||||
@@ -333,6 +458,9 @@ class OnboardingThemes extends \WC_REST_Data_Controller {
|
||||
),
|
||||
);
|
||||
|
||||
$ai_connection_enabled = get_option( 'woocommerce_blocks_allow_ai_connection' );
|
||||
$themes = $ai_connection_enabled ? $default_themes : $core_themes;
|
||||
|
||||
// To be implemented: Filter themes based on industry.
|
||||
if ( $industry ) {
|
||||
$filtered_themes = array_filter(
|
||||
|
||||
@@ -205,6 +205,7 @@ class Options extends \WC_REST_Data_Controller {
|
||||
'woocommerce_product_tour_modal_hidden',
|
||||
'woocommerce_block_product_tour_shown',
|
||||
'woocommerce_revenue_report_date_tour_shown',
|
||||
'woocommerce_show_prepublish_checks_enabled',
|
||||
'woocommerce_date_type',
|
||||
'date_format',
|
||||
'time_format',
|
||||
@@ -219,6 +220,12 @@ class Options extends \WC_REST_Data_Controller {
|
||||
'woocommerce_admin_customize_store_completed',
|
||||
'woocommerce_admin_customize_store_completed_theme_id',
|
||||
'woocommerce_admin_customize_store_survey_completed',
|
||||
'woocommerce_admin_launch_your_store_survey_completed',
|
||||
'woocommerce_coming_soon',
|
||||
'woocommerce_store_pages_only',
|
||||
'woocommerce_private_link',
|
||||
'woocommerce_share_key',
|
||||
'woocommerce_show_lys_tour',
|
||||
// WC Test helper options.
|
||||
'wc-admin-test-helper-rest-api-filters',
|
||||
'wc_admin_helper_feature_values',
|
||||
|
||||
@@ -420,12 +420,12 @@ class Plugins extends \WC_REST_Data_Controller {
|
||||
/**
|
||||
* Kicks off the WCCOM Connect process.
|
||||
*
|
||||
* @return WP_Error|array Connection URL for Woo.com
|
||||
* @return WP_Error|array Connection URL for WooCommerce.com
|
||||
*/
|
||||
public function request_wccom_connect() {
|
||||
include_once WC_ABSPATH . 'includes/admin/helper/class-wc-helper-api.php';
|
||||
if ( ! class_exists( 'WC_Helper_API' ) ) {
|
||||
return new \WP_Error( 'woocommerce_rest_helper_not_active', __( 'There was an error loading the Woo.com Helper API.', 'woocommerce' ), 404 );
|
||||
return new \WP_Error( 'woocommerce_rest_helper_not_active', __( 'There was an error loading the WooCommerce.com Helper API.', 'woocommerce' ), 404 );
|
||||
}
|
||||
|
||||
$redirect_uri = wc_admin_url( '&task=connect&wccom-connected=1' );
|
||||
@@ -442,12 +442,12 @@ class Plugins extends \WC_REST_Data_Controller {
|
||||
|
||||
$code = wp_remote_retrieve_response_code( $request );
|
||||
if ( 200 !== $code ) {
|
||||
return new \WP_Error( 'woocommerce_rest_helper_connect', __( 'There was an error connecting to Woo.com. Please try again.', 'woocommerce' ), 500 );
|
||||
return new \WP_Error( 'woocommerce_rest_helper_connect', __( 'There was an error connecting to WooCommerce.com. Please try again.', 'woocommerce' ), 500 );
|
||||
}
|
||||
|
||||
$secret = json_decode( wp_remote_retrieve_body( $request ) );
|
||||
if ( empty( $secret ) ) {
|
||||
return new \WP_Error( 'woocommerce_rest_helper_connect', __( 'There was an error connecting to Woo.com. Please try again.', 'woocommerce' ), 500 );
|
||||
return new \WP_Error( 'woocommerce_rest_helper_connect', __( 'There was an error connecting to WooCommerce.com. Please try again.', 'woocommerce' ), 500 );
|
||||
}
|
||||
|
||||
do_action( 'woocommerce_helper_connect_start' );
|
||||
@@ -477,7 +477,7 @@ class Plugins extends \WC_REST_Data_Controller {
|
||||
}
|
||||
|
||||
/**
|
||||
* Finishes connecting to Woo.com.
|
||||
* Finishes connecting to WooCommerce.com.
|
||||
*
|
||||
* @param object $rest_request Request details.
|
||||
* @return WP_Error|array Contains success status.
|
||||
@@ -488,7 +488,7 @@ class Plugins extends \WC_REST_Data_Controller {
|
||||
include_once WC_ABSPATH . 'includes/admin/helper/class-wc-helper-updater.php';
|
||||
include_once WC_ABSPATH . 'includes/admin/helper/class-wc-helper-options.php';
|
||||
if ( ! class_exists( 'WC_Helper_API' ) ) {
|
||||
return new \WP_Error( 'woocommerce_rest_helper_not_active', __( 'There was an error loading the Woo.com Helper API.', 'woocommerce' ), 404 );
|
||||
return new \WP_Error( 'woocommerce_rest_helper_not_active', __( 'There was an error loading the WooCommerce.com Helper API.', 'woocommerce' ), 404 );
|
||||
}
|
||||
|
||||
// Obtain an access token.
|
||||
@@ -504,12 +504,12 @@ class Plugins extends \WC_REST_Data_Controller {
|
||||
|
||||
$code = wp_remote_retrieve_response_code( $request );
|
||||
if ( 200 !== $code ) {
|
||||
return new \WP_Error( 'woocommerce_rest_helper_connect', __( 'There was an error connecting to Woo.com. Please try again.', 'woocommerce' ), 500 );
|
||||
return new \WP_Error( 'woocommerce_rest_helper_connect', __( 'There was an error connecting to WooCommerce.com. Please try again.', 'woocommerce' ), 500 );
|
||||
}
|
||||
|
||||
$access_token = json_decode( wp_remote_retrieve_body( $request ), true );
|
||||
if ( ! $access_token ) {
|
||||
return new \WP_Error( 'woocommerce_rest_helper_connect', __( 'There was an error connecting to Woo.com. Please try again.', 'woocommerce' ), 500 );
|
||||
return new \WP_Error( 'woocommerce_rest_helper_connect', __( 'There was an error connecting to WooCommerce.com. Please try again.', 'woocommerce' ), 500 );
|
||||
}
|
||||
|
||||
\WC_Helper_Options::update(
|
||||
@@ -525,7 +525,7 @@ class Plugins extends \WC_REST_Data_Controller {
|
||||
|
||||
if ( ! \WC_Helper::_flush_authentication_cache() ) {
|
||||
\WC_Helper_Options::update( 'auth', array() );
|
||||
return new \WP_Error( 'woocommerce_rest_helper_connect', __( 'There was an error connecting to Woo.com. Please try again.', 'woocommerce' ), 500 );
|
||||
return new \WP_Error( 'woocommerce_rest_helper_connect', __( 'There was an error connecting to WooCommerce.com. Please try again.', 'woocommerce' ), 500 );
|
||||
}
|
||||
|
||||
delete_transient( '_woocommerce_helper_subscriptions' );
|
||||
@@ -592,25 +592,22 @@ class Plugins extends \WC_REST_Data_Controller {
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns a URL that can be used to by WCPay to verify business details with Stripe.
|
||||
* Returns a URL that can be used to by WCPay to verify business details.
|
||||
*
|
||||
* @return WP_Error|array Connect URL.
|
||||
*/
|
||||
public function connect_wcpay() {
|
||||
if ( ! class_exists( 'WC_Payments_Account' ) ) {
|
||||
if ( ! class_exists( 'WC_Payments' ) ) {
|
||||
return new \WP_Error( 'woocommerce_rest_helper_connect', __( 'There was an error communicating with the WooPayments plugin.', 'woocommerce' ), 500 );
|
||||
}
|
||||
|
||||
$args = WooCommercePayments::is_account_partially_onboarded() ? [
|
||||
'wcpay-login' => '1',
|
||||
'_wpnonce' => wp_create_nonce( 'wcpay-login' ),
|
||||
] : [
|
||||
'wcpay-connect' => 'WCADMIN_PAYMENT_TASK',
|
||||
'_wpnonce' => wp_create_nonce( 'wcpay-connect' ),
|
||||
];
|
||||
// Redirect to the WooPayments overview page if the merchant started onboarding (aka WooPayments is already connected).
|
||||
// Redirect to the WooPayments connect page if they haven't started onboarding.
|
||||
$path = WooCommercePayments::is_connected() ? '/payments/overview' : '/payments/connect';
|
||||
|
||||
// Point to the WooPayments Connect page rather than straight to the onboarding flow.
|
||||
return( array(
|
||||
'connectUrl' => add_query_arg( $args, admin_url() ),
|
||||
'connectUrl' => add_query_arg( 'from', 'WCADMIN_PAYMENT_TASK', admin_url( 'admin.php?page=wc-admin&path=' . $path ) ),
|
||||
) );
|
||||
}
|
||||
|
||||
|
||||
@@ -1345,6 +1345,7 @@ class DataStore extends SqlQuery {
|
||||
continue;
|
||||
}
|
||||
|
||||
$term_id = '';
|
||||
// If the tuple is numeric, assume these are IDs.
|
||||
if ( is_numeric( $attribute_term[0] ) && is_numeric( $attribute_term[1] ) ) {
|
||||
$attribute_id = intval( $attribute_term[0] );
|
||||
@@ -1374,6 +1375,10 @@ class DataStore extends SqlQuery {
|
||||
// Assume these are a custom attribute slug/value pair.
|
||||
$meta_key = esc_sql( $attribute_term[0] );
|
||||
$meta_value = esc_sql( $attribute_term[1] );
|
||||
$attr_term = get_term_by( 'slug', $meta_value, $meta_key );
|
||||
if ( false !== $attr_term ) {
|
||||
$term_id = $attr_term->term_id;
|
||||
}
|
||||
}
|
||||
|
||||
$join_alias = 'orderitemmeta1';
|
||||
@@ -1391,8 +1396,23 @@ class DataStore extends SqlQuery {
|
||||
$sql_clauses['join'][] = "JOIN {$wpdb->prefix}woocommerce_order_itemmeta as {$join_alias} ON {$join_alias}.order_item_id = {$table_to_join_on}.order_item_id";
|
||||
}
|
||||
|
||||
// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
$sql_clauses['where'][] = $wpdb->prepare( "( {$join_alias}.meta_key = %s AND {$join_alias}.meta_value {$comparator} %s )", $meta_key, $meta_value );
|
||||
$in_comparator = '=' === $comparator ? 'in' : 'not in';
|
||||
|
||||
// Add subquery for products ordered using attributes not used in variations.
|
||||
$term_attribute_subquery = "select product_id from {$wpdb->prefix}wc_product_attributes_lookup where is_variation_attribute=0 and term_id = %s";
|
||||
// phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
// phpcs:disable WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber
|
||||
$sql_clauses['where'][] = $wpdb->prepare(
|
||||
"
|
||||
( ( {$join_alias}.meta_key = %s AND {$join_alias}.meta_value {$comparator} %s ) or (
|
||||
{$wpdb->prefix}wc_order_product_lookup.variation_id = 0 and {$wpdb->prefix}wc_order_product_lookup.product_id {$in_comparator} ({$term_attribute_subquery})
|
||||
) )",
|
||||
$meta_key,
|
||||
$meta_value,
|
||||
$term_id,
|
||||
);
|
||||
// phpcs:enable WordPress.DB.PreparedSQL.InterpolatedNotPrepared
|
||||
// phpcs:enable WordPress.DB.PreparedSQLPlaceholders.ReplacementsWrongNumber
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -211,24 +211,30 @@ class Controller extends ReportsController implements ExportableInterface {
|
||||
'readonly' => true,
|
||||
),
|
||||
'extended_info' => array(
|
||||
'products' => array(
|
||||
'products' => array(
|
||||
'type' => 'array',
|
||||
'readonly' => true,
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'description' => __( 'List of order product IDs, names, quantities.', 'woocommerce' ),
|
||||
),
|
||||
'coupons' => array(
|
||||
'coupons' => array(
|
||||
'type' => 'array',
|
||||
'readonly' => true,
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'description' => __( 'List of order coupons.', 'woocommerce' ),
|
||||
),
|
||||
'customer' => array(
|
||||
'customer' => array(
|
||||
'type' => 'object',
|
||||
'readonly' => true,
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'description' => __( 'Order customer information.', 'woocommerce' ),
|
||||
),
|
||||
'attribution' => array(
|
||||
'type' => 'object',
|
||||
'readonly' => true,
|
||||
'context' => array( 'view', 'edit' ),
|
||||
'description' => __( 'Order attribution information.', 'woocommerce' ),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
@@ -526,6 +532,7 @@ class Controller extends ReportsController implements ExportableInterface {
|
||||
'num_items_sold' => __( 'Items sold', 'woocommerce' ),
|
||||
'coupons' => __( 'Coupon(s)', 'woocommerce' ),
|
||||
'net_total' => __( 'N. Revenue', 'woocommerce' ),
|
||||
'attribution' => __( 'Attribution', 'woocommerce' ),
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -558,6 +565,7 @@ class Controller extends ReportsController implements ExportableInterface {
|
||||
'num_items_sold' => $item['num_items_sold'],
|
||||
'coupons' => isset( $item['extended_info']['coupons'] ) ? $this->get_coupons( $item['extended_info']['coupons'] ) : null,
|
||||
'net_total' => $item['net_total'],
|
||||
'attribution' => $item['extended_info']['attribution']['origin'],
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@@ -7,6 +7,9 @@ namespace Automattic\WooCommerce\Admin\API\Reports\Orders;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use Automattic\WooCommerce\Internal\Traits\OrderAttributionMeta;
|
||||
use Automattic\WooCommerce\Internal\DataStores\Orders\OrdersTableDataStore;
|
||||
use Automattic\WooCommerce\Utilities\OrderUtil;
|
||||
use Automattic\WooCommerce\Admin\API\Reports\DataStore as ReportsDataStore;
|
||||
use Automattic\WooCommerce\Admin\API\Reports\DataStoreInterface;
|
||||
use Automattic\WooCommerce\Admin\API\Reports\SqlQuery;
|
||||
@@ -18,6 +21,7 @@ use Automattic\WooCommerce\Admin\API\Reports\TimeInterval;
|
||||
* API\Reports\Orders\DataStore.
|
||||
*/
|
||||
class DataStore extends ReportsDataStore implements DataStoreInterface {
|
||||
use OrderAttributionMeta;
|
||||
|
||||
/**
|
||||
* Dynamically sets the date column name based on configuration
|
||||
@@ -338,13 +342,14 @@ class DataStore extends ReportsDataStore implements DataStoreInterface {
|
||||
* @param array $query_args Query parameters.
|
||||
*/
|
||||
protected function include_extended_info( &$orders_data, $query_args ) {
|
||||
$mapped_orders = $this->map_array_by_key( $orders_data, 'order_id' );
|
||||
$related_orders = $this->get_orders_with_parent_id( $mapped_orders );
|
||||
$order_ids = array_merge( array_keys( $mapped_orders ), array_keys( $related_orders ) );
|
||||
$products = $this->get_products_by_order_ids( $order_ids );
|
||||
$coupons = $this->get_coupons_by_order_ids( array_keys( $mapped_orders ) );
|
||||
$customers = $this->get_customers_by_orders( $orders_data );
|
||||
$mapped_customers = $this->map_array_by_key( $customers, 'customer_id' );
|
||||
$mapped_orders = $this->map_array_by_key( $orders_data, 'order_id' );
|
||||
$related_orders = $this->get_orders_with_parent_id( $mapped_orders );
|
||||
$order_ids = array_merge( array_keys( $mapped_orders ), array_keys( $related_orders ) );
|
||||
$products = $this->get_products_by_order_ids( $order_ids );
|
||||
$coupons = $this->get_coupons_by_order_ids( array_keys( $mapped_orders ) );
|
||||
$order_attributions = $this->get_order_attributions_by_order_ids( array_keys( $mapped_orders ) );
|
||||
$customers = $this->get_customers_by_orders( $orders_data );
|
||||
$mapped_customers = $this->map_array_by_key( $customers, 'customer_id' );
|
||||
|
||||
$mapped_data = array();
|
||||
foreach ( $products as $product ) {
|
||||
@@ -384,7 +389,7 @@ class DataStore extends ReportsDataStore implements DataStoreInterface {
|
||||
|
||||
foreach ( $coupons as $coupon ) {
|
||||
if ( ! isset( $mapped_data[ $coupon['order_id'] ] ) ) {
|
||||
$mapped_data[ $product['order_id'] ]['coupons'] = array();
|
||||
$mapped_data[ $coupon['order_id'] ]['coupons'] = array();
|
||||
}
|
||||
|
||||
$mapped_data[ $coupon['order_id'] ]['coupons'][] = array(
|
||||
@@ -394,15 +399,22 @@ class DataStore extends ReportsDataStore implements DataStoreInterface {
|
||||
}
|
||||
|
||||
foreach ( $orders_data as $key => $order_data ) {
|
||||
$defaults = array(
|
||||
'products' => array(),
|
||||
'coupons' => array(),
|
||||
'customer' => array(),
|
||||
$defaults = array(
|
||||
'products' => array(),
|
||||
'coupons' => array(),
|
||||
'customer' => array(),
|
||||
'attribution' => array(),
|
||||
);
|
||||
$orders_data[ $key ]['extended_info'] = isset( $mapped_data[ $order_data['order_id'] ] ) ? array_merge( $defaults, $mapped_data[ $order_data['order_id'] ] ) : $defaults;
|
||||
$order_id = $order_data['order_id'];
|
||||
|
||||
$orders_data[ $key ]['extended_info'] = isset( $mapped_data[ $order_id ] ) ? array_merge( $defaults, $mapped_data[ $order_id ] ) : $defaults;
|
||||
if ( $order_data['customer_id'] && isset( $mapped_customers[ $order_data['customer_id'] ] ) ) {
|
||||
$orders_data[ $key ]['extended_info']['customer'] = $mapped_customers[ $order_data['customer_id'] ];
|
||||
}
|
||||
|
||||
$source_type = $order_attributions[ $order_id ]['_wc_order_attribution_source_type'] ?? '';
|
||||
$utm_source = $order_attributions[ $order_id ]['_wc_order_attribution_utm_source'] ?? '';
|
||||
$orders_data[ $key ]['extended_info']['attribution']['origin'] = $this->get_origin_label( $source_type, $utm_source );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -534,6 +546,52 @@ class DataStore extends ReportsDataStore implements DataStoreInterface {
|
||||
return $coupons;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get order attributions data from order IDs.
|
||||
*
|
||||
* @param array $order_ids Array of order IDs.
|
||||
* @return array
|
||||
*/
|
||||
protected function get_order_attributions_by_order_ids( $order_ids ) {
|
||||
global $wpdb;
|
||||
$order_meta_table = OrdersTableDataStore::get_meta_table_name();
|
||||
$included_order_ids = implode( ',', array_map( 'absint', $order_ids ) );
|
||||
|
||||
if ( OrderUtil::custom_orders_table_usage_is_enabled() ) {
|
||||
/* phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared */
|
||||
$order_attributions_meta = $wpdb->get_results(
|
||||
"SELECT order_id, meta_key, meta_value
|
||||
FROM $order_meta_table
|
||||
WHERE order_id IN ({$included_order_ids})
|
||||
AND meta_key IN ( '_wc_order_attribution_source_type', '_wc_order_attribution_utm_source' )
|
||||
",
|
||||
ARRAY_A
|
||||
);
|
||||
/* phpcs:enable */
|
||||
} else {
|
||||
/* phpcs:disable WordPress.DB.PreparedSQL.InterpolatedNotPrepared */
|
||||
$order_attributions_meta = $wpdb->get_results(
|
||||
"SELECT post_id as order_id, meta_key, meta_value
|
||||
FROM $wpdb->postmeta
|
||||
WHERE post_id IN ({$included_order_ids})
|
||||
AND meta_key IN ( '_wc_order_attribution_source_type', '_wc_order_attribution_utm_source' )
|
||||
",
|
||||
ARRAY_A
|
||||
);
|
||||
/* phpcs:enable */
|
||||
}
|
||||
|
||||
$order_attributions = array();
|
||||
foreach ( $order_attributions_meta as $meta ) {
|
||||
if ( ! isset( $order_attributions[ $meta['order_id'] ] ) ) {
|
||||
$order_attributions[ $meta['order_id'] ] = array();
|
||||
}
|
||||
$order_attributions[ $meta['order_id'] ][ $meta['meta_key'] ] = $meta['meta_value'];
|
||||
}
|
||||
|
||||
return $order_attributions;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get all statuses that have been synced.
|
||||
*
|
||||
|
||||
@@ -165,7 +165,7 @@ class Segmenter extends ReportsSegmenter {
|
||||
|
||||
$segments = $this->get_product_related_segments( $type, $segmenting_selections, $segmenting_from, $segmenting_where, $segmenting_groupby, $segmenting_dimension_name, $table_name, $query_params, $unique_orders_table );
|
||||
} elseif ( 'variation' === $this->query_args['segmentby'] ) {
|
||||
if ( ! isset( $this->query_args['product_includes'] ) || ! is_array( count( $this->query_args['product_includes'] ) ) || count( $this->query_args['product_includes'] ) !== 1 ) {
|
||||
if ( ! isset( $this->query_args['product_includes'] ) || ! is_array( $this->query_args['product_includes'] ) || count( $this->query_args['product_includes'] ) !== 1 ) {
|
||||
throw new ParameterException( 'wc_admin_reports_invalid_segmenting_variation', __( 'product_includes parameter need to specify exactly one product when segmenting by variation.', 'woocommerce' ) );
|
||||
}
|
||||
|
||||
|
||||
@@ -70,6 +70,14 @@ interface BlockInterface {
|
||||
*/
|
||||
public function set_attributes( array $attributes );
|
||||
|
||||
/**
|
||||
* Set a block attribute value without replacing the entire attributes object.
|
||||
*
|
||||
* @param string $key The attribute key.
|
||||
* @param mixed $value The attribute value.
|
||||
*/
|
||||
public function set_attribute( string $key, $value );
|
||||
|
||||
/**
|
||||
* Get the parent container that the block belongs to.
|
||||
*/
|
||||
|
||||
@@ -2,55 +2,26 @@
|
||||
|
||||
namespace Automattic\WooCommerce\Admin;
|
||||
|
||||
use Automattic\WooCommerce\Admin\RemoteSpecs\DataSourcePoller as RemoteSpecsDataSourcePoller;
|
||||
|
||||
/**
|
||||
* Specs data source poller class.
|
||||
* This handles polling specs from JSON endpoints, and
|
||||
* stores the specs in to the database as an option.
|
||||
*
|
||||
* @deprecated since 8.8.0
|
||||
*/
|
||||
abstract class DataSourcePoller {
|
||||
|
||||
abstract class DataSourcePoller extends RemoteSpecsDataSourcePoller {
|
||||
/**
|
||||
* Get class instance.
|
||||
* Log a deprecation to the error log.
|
||||
*/
|
||||
abstract public static function get_instance();
|
||||
|
||||
/**
|
||||
* Name of data sources filter.
|
||||
*/
|
||||
const FILTER_NAME = 'data_source_poller_data_sources';
|
||||
|
||||
/**
|
||||
* Name of data source specs filter.
|
||||
*/
|
||||
const FILTER_NAME_SPECS = 'data_source_poller_specs';
|
||||
|
||||
/**
|
||||
* Id of DataSourcePoller.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $id = array();
|
||||
|
||||
/**
|
||||
* Default data sources array.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $data_sources = array();
|
||||
|
||||
/**
|
||||
* Default args.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $args = array();
|
||||
|
||||
/**
|
||||
* The logger instance.
|
||||
*
|
||||
* @var WC_Logger|null
|
||||
*/
|
||||
protected static $logger = null;
|
||||
private static function log_deprecation() {
|
||||
/**
|
||||
* Note: Deprecation messages have been temporarily disabled due to upgrade issues.
|
||||
* For more details, see the discussion in the WooCommerce GitHub repository:
|
||||
* https://github.com/woocommerce/woocommerce/pull/45892.
|
||||
*/
|
||||
}
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
@@ -60,98 +31,41 @@ abstract class DataSourcePoller {
|
||||
* @param array $args Options for DataSourcePoller.
|
||||
*/
|
||||
public function __construct( $id, $data_sources = array(), $args = array() ) {
|
||||
$this->data_sources = $data_sources;
|
||||
$this->id = $id;
|
||||
|
||||
$arg_defaults = array(
|
||||
'spec_key' => 'id',
|
||||
'transient_name' => 'woocommerce_admin_' . $id . '_specs',
|
||||
'transient_expiry' => 7 * DAY_IN_SECONDS,
|
||||
);
|
||||
$this->args = wp_parse_args( $args, $arg_defaults );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the logger instance.
|
||||
*
|
||||
* @return WC_Logger
|
||||
*/
|
||||
protected static function get_logger() {
|
||||
if ( is_null( self::$logger ) ) {
|
||||
self::$logger = wc_get_logger();
|
||||
}
|
||||
|
||||
return self::$logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the key identifier of spec, this can easily be overwritten. Defaults to id.
|
||||
*
|
||||
* @param mixed $spec a JSON parsed spec coming from the JSON feed.
|
||||
* @return string|boolean
|
||||
*/
|
||||
protected function get_spec_key( $spec ) {
|
||||
$key = $this->args['spec_key'];
|
||||
if ( isset( $spec->$key ) ) {
|
||||
return $spec->$key;
|
||||
}
|
||||
return false;
|
||||
self::log_deprecation();
|
||||
parent::__construct( $id, $data_sources, $args );
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the data sources for specs and persists those specs.
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
* @return array list of specs.
|
||||
*/
|
||||
public function get_specs_from_data_sources() {
|
||||
$locale = get_user_locale();
|
||||
$specs_group = get_transient( $this->args['transient_name'] ) ?? array();
|
||||
$specs = isset( $specs_group[ $locale ] ) ? $specs_group[ $locale ] : array();
|
||||
|
||||
if ( ! is_array( $specs ) || empty( $specs ) ) {
|
||||
$this->read_specs_from_data_sources();
|
||||
$specs_group = get_transient( $this->args['transient_name'] );
|
||||
$specs = isset( $specs_group[ $locale ] ) ? $specs_group[ $locale ] : array();
|
||||
}
|
||||
$specs = apply_filters( self::FILTER_NAME_SPECS, $specs, $this->id );
|
||||
return $specs !== false ? $specs : array();
|
||||
self::log_deprecation();
|
||||
return parent::get_specs_from_data_sources();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the data sources for specs and persists those specs.
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
* @return bool Whether any specs were read.
|
||||
*/
|
||||
public function read_specs_from_data_sources() {
|
||||
$specs = array();
|
||||
$data_sources = apply_filters( self::FILTER_NAME, $this->data_sources, $this->id );
|
||||
|
||||
// Note that this merges the specs from the data sources based on the
|
||||
// id - last one wins.
|
||||
foreach ( $data_sources as $url ) {
|
||||
$specs_from_data_source = self::read_data_source( $url );
|
||||
$this->merge_specs( $specs_from_data_source, $specs, $url );
|
||||
}
|
||||
|
||||
$specs_group = get_transient( $this->args['transient_name'] );
|
||||
$specs_group = is_array( $specs_group ) ? $specs_group : array();
|
||||
$locale = get_user_locale();
|
||||
$specs_group[ $locale ] = $specs;
|
||||
// Persist the specs as a transient.
|
||||
$this->set_specs_transient(
|
||||
$specs_group,
|
||||
$this->args['transient_expiry']
|
||||
);
|
||||
return count( $specs ) !== 0;
|
||||
self::log_deprecation();
|
||||
return parent::read_specs_from_data_sources();
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the specs transient.
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
* @return bool success of failure of transient deletion.
|
||||
*/
|
||||
public function delete_specs_transient() {
|
||||
return delete_transient( $this->args['transient_name'] );
|
||||
self::log_deprecation();
|
||||
return parent::delete_specs_transient();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -159,112 +73,11 @@ abstract class DataSourcePoller {
|
||||
*
|
||||
* @param array $specs The specs to set in the transient.
|
||||
* @param int $expiration The expiration time for the transient.
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
public function set_specs_transient( $specs, $expiration = 0 ) {
|
||||
set_transient(
|
||||
$this->args['transient_name'],
|
||||
$specs,
|
||||
$expiration,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a single data source and return the read specs
|
||||
*
|
||||
* @param string $url The URL to read the specs from.
|
||||
*
|
||||
* @return array The specs that have been read from the data source.
|
||||
*/
|
||||
protected static function read_data_source( $url ) {
|
||||
$logger_context = array( 'source' => $url );
|
||||
$logger = self::get_logger();
|
||||
$response = wp_remote_get(
|
||||
add_query_arg(
|
||||
'locale',
|
||||
get_user_locale(),
|
||||
$url
|
||||
),
|
||||
array(
|
||||
'user-agent' => 'WooCommerce/' . WC_VERSION . '; ' . home_url( '/' ),
|
||||
)
|
||||
);
|
||||
|
||||
if ( is_wp_error( $response ) || ! isset( $response['body'] ) ) {
|
||||
$logger->error(
|
||||
'Error getting data feed',
|
||||
$logger_context
|
||||
);
|
||||
// phpcs:ignore
|
||||
$logger->error( print_r( $response, true ), $logger_context );
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
$body = $response['body'];
|
||||
$specs = json_decode( $body );
|
||||
|
||||
if ( $specs === null ) {
|
||||
$logger->error(
|
||||
'Empty response in data feed',
|
||||
$logger_context
|
||||
);
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
if ( ! is_array( $specs ) ) {
|
||||
$logger->error(
|
||||
'Data feed is not an array',
|
||||
$logger_context
|
||||
);
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
return $specs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge the specs.
|
||||
*
|
||||
* @param Array $specs_to_merge_in The specs to merge in to $specs.
|
||||
* @param Array $specs The list of specs being merged into.
|
||||
* @param string $url The url of the feed being merged in (for error reporting).
|
||||
*/
|
||||
protected function merge_specs( $specs_to_merge_in, &$specs, $url ) {
|
||||
foreach ( $specs_to_merge_in as $spec ) {
|
||||
if ( ! $this->validate_spec( $spec, $url ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$id = $this->get_spec_key( $spec );
|
||||
$specs[ $id ] = $spec;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the spec.
|
||||
*
|
||||
* @param object $spec The spec to validate.
|
||||
* @param string $url The url of the feed that provided the spec.
|
||||
*
|
||||
* @return bool The result of the validation.
|
||||
*/
|
||||
protected function validate_spec( $spec, $url ) {
|
||||
$logger = self::get_logger();
|
||||
$logger_context = array( 'source' => $url );
|
||||
|
||||
if ( ! $this->get_spec_key( $spec ) ) {
|
||||
$logger->error(
|
||||
'Spec is invalid because the id is missing in feed',
|
||||
$logger_context
|
||||
);
|
||||
// phpcs:ignore
|
||||
$logger->error( print_r( $spec, true ), $logger_context );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
self::log_deprecation();
|
||||
return parent::set_specs_transient( $specs, $expiration );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -47,6 +47,12 @@ class DeprecatedClassFacade {
|
||||
*/
|
||||
protected static $deprecated_in_version = '';
|
||||
|
||||
/**
|
||||
* Static array of logged messages.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private static $logged_messages = array();
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
@@ -61,14 +67,18 @@ class DeprecatedClassFacade {
|
||||
* @param string $function The name of the deprecated function being called.
|
||||
*/
|
||||
private static function log_deprecation( $function ) {
|
||||
error_log( // phpcs:ignore
|
||||
sprintf(
|
||||
'%1$s is deprecated since version %2$s! Use %3$s instead.',
|
||||
static::class . '::' . $function,
|
||||
static::$deprecated_in_version,
|
||||
static::$facade_over_classname . '::' . $function
|
||||
)
|
||||
$message = sprintf(
|
||||
'%1$s is deprecated since version %2$s! Use %3$s instead.',
|
||||
static::class . '::' . $function,
|
||||
static::$deprecated_in_version,
|
||||
static::$facade_over_classname . '::' . $function
|
||||
);
|
||||
|
||||
// Only log when the message has not been logged before.
|
||||
if ( ! in_array( $message, self::$logged_messages, true ) ) {
|
||||
error_log( $message ); // phpcs:ignore
|
||||
self::$logged_messages[] = $message;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -81,7 +81,7 @@ class Features {
|
||||
* @return array
|
||||
*/
|
||||
public static function get_optional_feature_options() {
|
||||
$features = [];
|
||||
$features = array();
|
||||
|
||||
foreach ( array_keys( self::$optional_features ) as $optional_feature_key ) {
|
||||
$feature_class = self::get_feature_class( $optional_feature_key );
|
||||
@@ -148,7 +148,7 @@ class Features {
|
||||
public static function get_available_features() {
|
||||
$features = self::get_features();
|
||||
$optional_feature_keys = array_keys( self::$optional_features );
|
||||
$optional_features_unavailable = [];
|
||||
$optional_features_unavailable = array();
|
||||
|
||||
/**
|
||||
* Filter allowing WooCommerce Admin optional features to be disabled.
|
||||
@@ -292,22 +292,8 @@ class Features {
|
||||
return;
|
||||
}
|
||||
|
||||
$rtl = is_rtl() ? '.rtl' : '';
|
||||
|
||||
wp_enqueue_style(
|
||||
'wc-admin-beta-features-tracking-modal',
|
||||
WCAdminAssets::get_url( "beta-features-tracking-modal/style{$rtl}", 'css' ),
|
||||
array( 'wp-components' ),
|
||||
WCAdminAssets::get_file_version( 'css' )
|
||||
);
|
||||
|
||||
wp_enqueue_script(
|
||||
'wc-admin-beta-features-tracking-modal',
|
||||
WCAdminAssets::get_url( 'wp-admin-scripts/beta-features-tracking-modal', 'js' ),
|
||||
array( 'wp-i18n', 'wp-element', WC_ADMIN_APP ),
|
||||
WCAdminAssets::get_file_version( 'js' ),
|
||||
true
|
||||
);
|
||||
WCAdminAssets::register_style( 'beta-features-tracking-modal', 'style', array( 'wp-components' ) );
|
||||
WCAdminAssets::register_script( 'wp-admin-scripts', 'beta-features-tracking-modal', array( 'wp-i18n', 'wp-element', WC_ADMIN_APP ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,201 @@
|
||||
<?php
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\Features;
|
||||
|
||||
use Automattic\WooCommerce\Admin\PageController;
|
||||
use Automattic\WooCommerce\Blocks\Utils\BlockTemplateUtils;
|
||||
use Automattic\WooCommerce\Admin\WCAdminHelper;
|
||||
|
||||
/**
|
||||
* Takes care of Launch Your Store related actions.
|
||||
*/
|
||||
class LaunchYourStore {
|
||||
const BANNER_DISMISS_USER_META_KEY = 'woocommerce_coming_soon_banner_dismissed';
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'woocommerce_update_options_site-visibility', array( $this, 'save_site_visibility_options' ) );
|
||||
add_filter( 'woocommerce_admin_shared_settings', array( $this, 'preload_settings' ) );
|
||||
add_action( 'wp_footer', array( $this, 'maybe_add_coming_soon_banner_on_frontend' ) );
|
||||
add_action( 'init', array( $this, 'register_launch_your_store_user_meta_fields' ) );
|
||||
add_action( 'wp_login', array( $this, 'reset_woocommerce_coming_soon_banner_dismissed' ), 10, 2 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Save values submitted from WooCommerce -> Settings -> General.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function save_site_visibility_options() {
|
||||
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
if ( empty( $_REQUEST['_wpnonce'] ) || ! wp_verify_nonce( wp_unslash( $_REQUEST['_wpnonce'] ), 'woocommerce-settings' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$options = array(
|
||||
'woocommerce_coming_soon' => array( 'yes', 'no' ),
|
||||
'woocommerce_store_pages_only' => array( 'yes', 'no' ),
|
||||
'woocommerce_private_link' => array( 'yes', 'no' ),
|
||||
);
|
||||
|
||||
$at_least_one_saved = false;
|
||||
foreach ( $options as $name => $option ) {
|
||||
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
if ( isset( $_POST[ $name ] ) && in_array( $_POST[ $name ], $option, true ) ) {
|
||||
// phpcs:ignore WordPress.Security.ValidatedSanitizedInput.InputNotSanitized
|
||||
update_option( $name, wp_unslash( $_POST[ $name ] ) );
|
||||
$at_least_one_saved = true;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $at_least_one_saved ) {
|
||||
wc_admin_record_tracks_event( 'site_visibility_saved' );
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Preload settings for Site Visibility.
|
||||
*
|
||||
* @param array $settings settings array.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function preload_settings( $settings ) {
|
||||
if ( ! is_admin() ) {
|
||||
return $settings;
|
||||
}
|
||||
|
||||
$current_screen = get_current_screen();
|
||||
$is_setting_page = $current_screen && 'woocommerce_page_wc-settings' === $current_screen->id;
|
||||
|
||||
if ( $is_setting_page ) {
|
||||
// Regnerate the share key if it's not set.
|
||||
add_option( 'woocommerce_share_key', wp_generate_password( 32, false ) );
|
||||
|
||||
$settings['siteVisibilitySettings'] = array(
|
||||
'shop_permalink' => get_permalink( wc_get_page_id( 'shop' ) ),
|
||||
'woocommerce_coming_soon' => get_option( 'woocommerce_coming_soon' ),
|
||||
'woocommerce_store_pages_only' => get_option( 'woocommerce_store_pages_only' ),
|
||||
'woocommerce_private_link' => get_option( 'woocommerce_private_link' ),
|
||||
'woocommerce_share_key' => get_option( 'woocommerce_share_key' ),
|
||||
);
|
||||
}
|
||||
|
||||
return $settings;
|
||||
}
|
||||
|
||||
/**
|
||||
* User must be an admin or editor.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private function is_manager_or_admin() {
|
||||
// phpcs:ignore
|
||||
if ( ! current_user_can( 'shop_manager' ) && ! current_user_can( 'administrator' ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add 'coming soon' banner on the frontend when the following conditions met.
|
||||
*
|
||||
* - User must be either an admin or store editor (must be logged in).
|
||||
* - 'woocommerce_coming_soon' option value must be 'yes'
|
||||
* - The page must not be the Coming soon page itself.
|
||||
*/
|
||||
public function maybe_add_coming_soon_banner_on_frontend() {
|
||||
// Do not show the banner if the site is being previewed.
|
||||
if ( isset( $_GET['site-preview'] ) ) { // @phpcs:ignore
|
||||
return false;
|
||||
}
|
||||
|
||||
$current_user_id = get_current_user_id();
|
||||
if ( ! $current_user_id ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( get_user_meta( $current_user_id, self::BANNER_DISMISS_USER_META_KEY, true ) === 'yes' ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! $this->is_manager_or_admin() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
// 'woocommerce_coming_soon' must be 'yes'
|
||||
if ( get_option( 'woocommerce_coming_soon', 'no' ) !== 'yes' ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$store_pages_only = get_option( 'woocommerce_store_pages_only' ) === 'yes';
|
||||
if ( $store_pages_only && ! WCAdminHelper::is_store_page() ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$link = admin_url( 'admin.php?page=wc-settings&tab=site-visibility' );
|
||||
$rest_url = rest_url( 'wp/v2/users/' . $current_user_id );
|
||||
$rest_nonce = wp_create_nonce( 'wp_rest' );
|
||||
|
||||
$text = sprintf(
|
||||
// translators: no need to translate it. It's a link.
|
||||
__(
|
||||
"
|
||||
This page is in \"Coming soon\" mode and is only visible to you and those who have permission. To make it public to everyone, <a href='%s'>change visibility settings</a>
|
||||
",
|
||||
'woocommerce'
|
||||
),
|
||||
$link
|
||||
);
|
||||
// phpcs:ignore
|
||||
echo "<div id='coming-soon-footer-banner'>$text<a class='coming-soon-footer-banner-dismiss' data-rest-url='$rest_url' data-rest-nonce='$rest_nonce'></a></div>";
|
||||
}
|
||||
|
||||
/**
|
||||
* Register user meta fields for Launch Your Store.
|
||||
*/
|
||||
public function register_launch_your_store_user_meta_fields() {
|
||||
if ( ! $this->is_manager_or_admin() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
register_meta(
|
||||
'user',
|
||||
'woocommerce_launch_your_store_tour_hidden',
|
||||
array(
|
||||
'type' => 'string',
|
||||
'description' => 'Indicate whether the user has dismissed the site visibility tour on the home screen.',
|
||||
'single' => true,
|
||||
'show_in_rest' => true,
|
||||
)
|
||||
);
|
||||
|
||||
register_meta(
|
||||
'user',
|
||||
self::BANNER_DISMISS_USER_META_KEY,
|
||||
array(
|
||||
'type' => 'string',
|
||||
'description' => 'Indicate whether the user has dismissed the coming soon notice or not.',
|
||||
'single' => true,
|
||||
'show_in_rest' => true,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Reset 'woocommerce_coming_soon_banner_dismissed' user meta to 'no'.
|
||||
*
|
||||
* Runs when a user logs-in successfully.
|
||||
*
|
||||
* @param string $user_login user login.
|
||||
* @param object $user user object.
|
||||
*/
|
||||
public function reset_woocommerce_coming_soon_banner_dismissed( $user_login, $user ) {
|
||||
$existing_meta = get_user_meta( $user->ID, self::BANNER_DISMISS_USER_META_KEY, true );
|
||||
if ( 'yes' === $existing_meta ) {
|
||||
update_user_meta( $user->ID, self::BANNER_DISMISS_USER_META_KEY, 'no' );
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -58,7 +58,7 @@ class DefaultMarketingRecommendations {
|
||||
array(
|
||||
'title' => 'Google Listings and Ads',
|
||||
'description' => __( 'Get in front of shoppers and drive traffic so you can grow your business with Smart Shopping Campaigns and free listings.', 'woocommerce' ),
|
||||
'url' => "https://woo.com/products/google-listings-and-ads/{$utm_string}",
|
||||
'url' => "https://woocommerce.com/products/google-listings-and-ads/{$utm_string}",
|
||||
'direct_install' => true,
|
||||
'icon' => "{$icon_dir_url}/google.svg",
|
||||
'product' => 'google-listings-and-ads',
|
||||
@@ -76,7 +76,7 @@ class DefaultMarketingRecommendations {
|
||||
array(
|
||||
'title' => 'Pinterest for WooCommerce',
|
||||
'description' => __( 'Grow your business on Pinterest! Use this official plugin to allow shoppers to Pin products while browsing your store, track conversions, and advertise on Pinterest.', 'woocommerce' ),
|
||||
'url' => "https://woo.com/products/pinterest-for-woocommerce/{$utm_string}",
|
||||
'url' => "https://woocommerce.com/products/pinterest-for-woocommerce/{$utm_string}",
|
||||
'direct_install' => true,
|
||||
'icon' => "{$icon_dir_url}/pinterest.svg",
|
||||
'product' => 'pinterest-for-woocommerce',
|
||||
@@ -94,7 +94,7 @@ class DefaultMarketingRecommendations {
|
||||
array(
|
||||
'title' => 'TikTok for WooCommerce',
|
||||
'description' => __( 'Create advertising campaigns and reach one billion global users with TikTok for WooCommerce.', 'woocommerce' ),
|
||||
'url' => "https://woo.com/products/tiktok-for-woocommerce/{$utm_string}",
|
||||
'url' => "https://woocommerce.com/products/tiktok-for-woocommerce/{$utm_string}",
|
||||
'direct_install' => true,
|
||||
'icon' => "{$icon_dir_url}/tiktok.jpg",
|
||||
'product' => 'tiktok-for-business',
|
||||
@@ -110,7 +110,7 @@ class DefaultMarketingRecommendations {
|
||||
array(
|
||||
'title' => 'MailPoet',
|
||||
'description' => __( 'Create and send purchase follow-up emails, newsletters, and promotional campaigns straight from your dashboard.', 'woocommerce' ),
|
||||
'url' => "https://woo.com/products/mailpoet/{$utm_string}",
|
||||
'url' => "https://woocommerce.com/products/mailpoet/{$utm_string}",
|
||||
'direct_install' => true,
|
||||
'icon' => "{$icon_dir_url}/mailpoet.svg",
|
||||
'product' => 'mailpoet',
|
||||
@@ -128,7 +128,7 @@ class DefaultMarketingRecommendations {
|
||||
array(
|
||||
'title' => 'Mailchimp for WooCommerce',
|
||||
'description' => __( 'Send targeted campaigns, recover abandoned carts and more with Mailchimp.', 'woocommerce' ),
|
||||
'url' => "https://woo.com/products/mailchimp-for-woocommerce/{$utm_string}",
|
||||
'url' => "https://woocommerce.com/products/mailchimp-for-woocommerce/{$utm_string}",
|
||||
'direct_install' => true,
|
||||
'icon' => "{$icon_dir_url}/mailchimp.svg",
|
||||
'product' => 'mailchimp-for-woocommerce',
|
||||
@@ -144,7 +144,7 @@ class DefaultMarketingRecommendations {
|
||||
array(
|
||||
'title' => 'Klaviyo for WooCommerce',
|
||||
'description' => __( 'Grow and retain customers with intelligent, impactful email and SMS marketing automation and a consolidated view of customer interactions.', 'woocommerce' ),
|
||||
'url' => "https://woo.com/products/klaviyo-for-woocommerce/{$utm_string}",
|
||||
'url' => "https://woocommerce.com/products/klaviyo-for-woocommerce/{$utm_string}",
|
||||
'direct_install' => true,
|
||||
'icon' => "{$icon_dir_url}/klaviyo.png",
|
||||
'product' => 'klaviyo',
|
||||
@@ -160,7 +160,7 @@ class DefaultMarketingRecommendations {
|
||||
array(
|
||||
'title' => 'AutomateWoo',
|
||||
'description' => __( 'Convert and retain customers with automated marketing that does the hard work for you.', 'woocommerce' ),
|
||||
'url' => "https://woo.com/products/automatewoo/{$utm_string}",
|
||||
'url' => "https://woocommerce.com/products/automatewoo/{$utm_string}",
|
||||
'direct_install' => false,
|
||||
'icon' => "{$icon_dir_url}/automatewoo.svg",
|
||||
'product' => 'automatewoo',
|
||||
@@ -178,7 +178,7 @@ class DefaultMarketingRecommendations {
|
||||
array(
|
||||
'title' => 'AutomateWoo Refer a Friend',
|
||||
'description' => __( 'Boost your organic sales by adding a customer referral program to your WooCommerce store.', 'woocommerce' ),
|
||||
'url' => "https://woo.com/products/automatewoo-refer-a-friend/{$utm_string}",
|
||||
'url' => "https://woocommerce.com/products/automatewoo-refer-a-friend/{$utm_string}",
|
||||
'direct_install' => false,
|
||||
'icon' => "{$icon_dir_url}/automatewoo.svg",
|
||||
'product' => 'automatewoo-referrals',
|
||||
@@ -196,7 +196,7 @@ class DefaultMarketingRecommendations {
|
||||
array(
|
||||
'title' => 'AutomateWoo Birthdays',
|
||||
'description' => __( 'Delight customers and boost organic sales with a special WooCommerce birthday email (and coupon!) on their special day.', 'woocommerce' ),
|
||||
'url' => "https://woo.com/products/automatewoo-birthdays/{$utm_string}",
|
||||
'url' => "https://woocommerce.com/products/automatewoo-birthdays/{$utm_string}",
|
||||
'direct_install' => false,
|
||||
'icon' => "{$icon_dir_url}/automatewoo.svg",
|
||||
'product' => 'automatewoo-birthdays',
|
||||
@@ -214,7 +214,7 @@ class DefaultMarketingRecommendations {
|
||||
array(
|
||||
'title' => 'Trustpilot Reviews',
|
||||
'description' => __( 'Collect and showcase verified reviews that consumers trust.', 'woocommerce' ),
|
||||
'url' => "https://woo.com/products/trustpilot-reviews/{$utm_string}",
|
||||
'url' => "https://woocommerce.com/products/trustpilot-reviews/{$utm_string}",
|
||||
'direct_install' => true,
|
||||
'icon' => "{$icon_dir_url}/trustpilot.png",
|
||||
'product' => 'trustpilot-reviews',
|
||||
@@ -230,7 +230,7 @@ class DefaultMarketingRecommendations {
|
||||
array(
|
||||
'title' => 'Vimeo for WooCommerce',
|
||||
'description' => __( 'Turn your product images into stunning videos that engage and convert audiences - no video experience required.', 'woocommerce' ),
|
||||
'url' => "https://woo.com/products/vimeo/{$utm_string}",
|
||||
'url' => "https://woocommerce.com/products/vimeo/{$utm_string}",
|
||||
'direct_install' => true,
|
||||
'icon' => "{$icon_dir_url}/vimeo.png",
|
||||
'product' => 'vimeo',
|
||||
@@ -246,7 +246,7 @@ class DefaultMarketingRecommendations {
|
||||
array(
|
||||
'title' => 'Jetpack CRM for WooCommerce',
|
||||
'description' => __( 'Harness data from WooCommerce to grow your business. Manage leads, customers, and segments, through automation, quotes, invoicing, billing, and email marketing. Power up your store with CRM.', 'woocommerce' ),
|
||||
'url' => "https://woo.com/products/jetpack-crm/{$utm_string}",
|
||||
'url' => "https://woocommerce.com/products/jetpack-crm/{$utm_string}",
|
||||
'direct_install' => true,
|
||||
'icon' => "{$icon_dir_url}/jetpack-crm.svg",
|
||||
'product' => 'zero-bs-crm',
|
||||
@@ -262,7 +262,7 @@ class DefaultMarketingRecommendations {
|
||||
array(
|
||||
'title' => 'WooCommerce Zapier',
|
||||
'description' => __( 'Integrate your WooCommerce store with 5000+ cloud apps and services today. Trusted by 11,000+ users.', 'woocommerce' ),
|
||||
'url' => "https://woo.com/products/woocommerce-zapier/{$utm_string}",
|
||||
'url' => "https://woocommerce.com/products/woocommerce-zapier/{$utm_string}",
|
||||
'direct_install' => false,
|
||||
'icon' => "{$icon_dir_url}/zapier.png",
|
||||
'product' => 'woocommerce-zapier',
|
||||
@@ -278,7 +278,7 @@ class DefaultMarketingRecommendations {
|
||||
array(
|
||||
'title' => 'Salesforce',
|
||||
'description' => __( 'Sync your website\'s data like contacts, products, and orders over Salesforce CRM with Salesforce Integration for WooCommerce.', 'woocommerce' ),
|
||||
'url' => "https://woo.com/products/integration-with-salesforce-for-woocommerce/{$utm_string}",
|
||||
'url' => "https://woocommerce.com/products/integration-with-salesforce-for-woocommerce/{$utm_string}",
|
||||
'direct_install' => false,
|
||||
'icon' => "{$icon_dir_url}/salesforce.jpg",
|
||||
'product' => 'integration-with-salesforce',
|
||||
@@ -294,7 +294,7 @@ class DefaultMarketingRecommendations {
|
||||
array(
|
||||
'title' => 'Personalized Coupons',
|
||||
'description' => __( 'Generate dynamic personalized coupons for your customers that increase purchase rates.', 'woocommerce' ),
|
||||
'url' => "https://woo.com/products/automatewoo/{$utm_string}",
|
||||
'url' => "https://woocommerce.com/products/automatewoo/{$utm_string}",
|
||||
'direct_install' => false,
|
||||
'icon' => "{$icon_dir_url}/automatewoo-personalized-coupons.svg",
|
||||
'product' => 'automatewoo',
|
||||
@@ -308,7 +308,7 @@ class DefaultMarketingRecommendations {
|
||||
array(
|
||||
'title' => 'Smart Coupons',
|
||||
'description' => __( 'Powerful, "all in one" solution for gift certificates, store credits, discount coupons and vouchers.', 'woocommerce' ),
|
||||
'url' => "https://woo.com/products/smart-coupons/{$utm_string}",
|
||||
'url' => "https://woocommerce.com/products/smart-coupons/{$utm_string}",
|
||||
'direct_install' => false,
|
||||
'icon' => "{$icon_dir_url}/woocommerce-smart-coupons.svg",
|
||||
'product' => 'woocommerce-smart-coupons',
|
||||
@@ -322,7 +322,7 @@ class DefaultMarketingRecommendations {
|
||||
array(
|
||||
'title' => 'URL Coupons',
|
||||
'description' => __( 'Create a unique URL that applies a discount and optionally adds one or more products to the customer\'s cart.', 'woocommerce' ),
|
||||
'url' => "https://woo.com/products/url-coupons/{$utm_string}",
|
||||
'url' => "https://woocommerce.com/products/url-coupons/{$utm_string}",
|
||||
'direct_install' => false,
|
||||
'icon' => "{$icon_dir_url}/woocommerce-url-coupons.svg",
|
||||
'product' => 'woocommerce-url-coupons',
|
||||
@@ -336,7 +336,7 @@ class DefaultMarketingRecommendations {
|
||||
array(
|
||||
'title' => 'WooCommerce Store Credit',
|
||||
'description' => __( 'Create "store credit" coupons for customers which are redeemable at checkout.', 'woocommerce' ),
|
||||
'url' => "https://woo.com/products/store-credit/{$utm_string}",
|
||||
'url' => "https://woocommerce.com/products/store-credit/{$utm_string}",
|
||||
'direct_install' => false,
|
||||
'icon' => "{$icon_dir_url}/woocommerce-store-credit.svg",
|
||||
'product' => 'woocommerce-store-credit',
|
||||
@@ -350,7 +350,7 @@ class DefaultMarketingRecommendations {
|
||||
array(
|
||||
'title' => 'Free Gift Coupons',
|
||||
'description' => __( 'Give away a free item to any customer with the coupon code.', 'woocommerce' ),
|
||||
'url' => "https://woo.com/products/free-gift-coupons/{$utm_string}",
|
||||
'url' => "https://woocommerce.com/products/free-gift-coupons/{$utm_string}",
|
||||
'direct_install' => false,
|
||||
'icon' => "{$icon_dir_url}/woocommerce-free-gift-coupons.svg",
|
||||
'product' => 'woocommerce-free-gift-coupons',
|
||||
@@ -364,7 +364,7 @@ class DefaultMarketingRecommendations {
|
||||
array(
|
||||
'title' => 'Group Coupons',
|
||||
'description' => __( 'Coupons for groups. Provides the option to have coupons that are restricted to group members or roles. Works with the free Groups plugin.', 'woocommerce' ),
|
||||
'url' => "https://woo.com/products/group-coupons/{$utm_string}",
|
||||
'url' => "https://woocommerce.com/products/group-coupons/{$utm_string}",
|
||||
'direct_install' => false,
|
||||
'icon' => "{$icon_dir_url}/woocommerce-group-coupons.svg",
|
||||
'product' => 'woocommerce-group-coupons',
|
||||
|
||||
@@ -12,14 +12,14 @@ defined( 'ABSPATH' ) || exit;
|
||||
*/
|
||||
class Init extends RemoteSpecsEngine {
|
||||
/**
|
||||
* Slug of the category specifying marketing extensions on the Woo.com store.
|
||||
* Slug of the category specifying marketing extensions on the WooCommerce.com store.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const MARKETING_EXTENSION_CATEGORY_SLUG = 'marketing';
|
||||
|
||||
/**
|
||||
* Slug of the subcategory specifying marketing channels on the Woo.com store.
|
||||
* Slug of the subcategory specifying marketing channels on the WooCommerce.com store.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
@@ -81,7 +81,7 @@ class Init extends RemoteSpecsEngine {
|
||||
}
|
||||
|
||||
/**
|
||||
* Load recommended plugins from Woo.com
|
||||
* Load recommended plugins from WooCommerce.com
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -113,7 +113,7 @@ class Init extends RemoteSpecsEngine {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return only the recommended marketing channels from Woo.com.
|
||||
* Return only the recommended marketing channels from WooCommerce.com.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -127,7 +127,7 @@ class Init extends RemoteSpecsEngine {
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all recommended marketing extensions EXCEPT the marketing channels from Woo.com.
|
||||
* Return all recommended marketing extensions EXCEPT the marketing channels from WooCommerce.com.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\Features\MarketingRecommendations;
|
||||
|
||||
use Automattic\WooCommerce\Admin\DataSourcePoller;
|
||||
use Automattic\WooCommerce\Admin\RemoteSpecs\DataSourcePoller;
|
||||
|
||||
/**
|
||||
* Specs data source poller class for marketing recommendations.
|
||||
|
||||
@@ -123,14 +123,7 @@ class Init {
|
||||
return;
|
||||
}
|
||||
|
||||
$rtl = is_rtl() ? '.rtl' : '';
|
||||
wp_enqueue_style(
|
||||
'wc-admin-navigation-opt-out',
|
||||
WCAdminAssets::get_url( "navigation-opt-out/style{$rtl}", 'css' ),
|
||||
array( 'wp-components' ),
|
||||
WCAdminAssets::get_file_version( 'css' )
|
||||
);
|
||||
|
||||
WCAdminAssets::register_style( 'navigation-opt-out', 'style', array( 'wp-components' ) );
|
||||
WCAdminAssets::register_script( 'wp-admin-scripts', 'navigation-opt-out', true );
|
||||
wp_localize_script(
|
||||
'wc-admin-navigation-opt-out',
|
||||
|
||||
@@ -394,11 +394,12 @@ abstract class Task {
|
||||
* Track task completion if task is viewable.
|
||||
*/
|
||||
public function possibly_track_completion() {
|
||||
if ( ! $this->is_complete() ) {
|
||||
if ( $this->has_previously_completed() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
if ( $this->has_previously_completed() ) {
|
||||
// Expensive check.
|
||||
if ( ! $this->is_complete() ) {
|
||||
return;
|
||||
}
|
||||
|
||||
|
||||
@@ -414,10 +414,14 @@ class TaskList {
|
||||
public function get_json() {
|
||||
$this->possibly_track_completion();
|
||||
$tasks_json = array();
|
||||
foreach ( $this->tasks as $task ) {
|
||||
$json = $task->get_json();
|
||||
if ( $json['canView'] ) {
|
||||
$tasks_json[] = $json;
|
||||
|
||||
// We have no use for hidden lists, it's expensive to compute individual tasks completion.
|
||||
if ( $this->is_visible() ) {
|
||||
foreach ( $this->tasks as $task ) {
|
||||
$json = $task->get_json();
|
||||
if ( $json['canView'] ) {
|
||||
$tasks_json[] = $json;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -118,6 +118,7 @@ class TaskLists {
|
||||
'Tax',
|
||||
'Shipping',
|
||||
'Marketing',
|
||||
'LaunchYourStore',
|
||||
);
|
||||
|
||||
if ( Features::is_enabled( 'core-profiler' ) ) {
|
||||
@@ -164,6 +165,7 @@ class TaskLists {
|
||||
),
|
||||
),
|
||||
'tasks' => array(
|
||||
'StoreConnect',
|
||||
'AdditionalPayments',
|
||||
'GetMobileApp',
|
||||
),
|
||||
|
||||
@@ -115,6 +115,14 @@ class AdditionalPayments extends Payments {
|
||||
return $this->can_view_result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Action URL.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_action_url() {
|
||||
return admin_url( 'admin.php?page=wc-admin&task=payments' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the store has any enabled gateways in other category.
|
||||
|
||||
@@ -21,15 +21,31 @@ class CustomizeStore extends Task {
|
||||
|
||||
add_action( 'show_admin_bar', array( $this, 'possibly_hide_wp_admin_bar' ) );
|
||||
|
||||
// Use "switch_theme" instead of "after_switch_theme" because the latter is fired after the next WP load and we don't want to trigger action when switching theme to TT3 via onboarding theme API.
|
||||
global $_GET;
|
||||
$theme_switch_via_cys_ai_loader = isset( $_GET['theme_switch_via_cys_ai_loader'] ) ? 1 === absint( $_GET['theme_switch_via_cys_ai_loader'] ) : false;
|
||||
if ( ! $theme_switch_via_cys_ai_loader ) {
|
||||
add_action( 'switch_theme', array( $this, 'mark_task_as_complete' ) );
|
||||
}
|
||||
|
||||
// Hook to remove unwanted UI elements when users are viewing with ?cys-hide-admin-bar=true.
|
||||
add_action( 'wp_head', array( $this, 'possibly_remove_unwanted_ui_elements' ) );
|
||||
|
||||
add_action( 'save_post_wp_global_styles', array( $this, 'mark_task_as_complete' ), 10, 3 );
|
||||
add_action( 'save_post_wp_template', array( $this, 'mark_task_as_complete' ), 10, 3 );
|
||||
add_action( 'save_post_wp_template_part', array( $this, 'mark_task_as_complete' ), 10, 3 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark the CYS task as complete whenever the user updates their global styles.
|
||||
*
|
||||
* @param int $post_id Post ID.
|
||||
* @param \WP_Post $post Post object.
|
||||
* @param bool $update Whether this is an existing post being updated.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function mark_task_as_complete( $post_id, $post, $update ) {
|
||||
if ( $post instanceof \WP_Post ) {
|
||||
$is_cys_complete = '{"version": 2, "isGlobalStylesUserThemeJSON": true }' !== $post->post_content || in_array( $post->post_type, array( 'wp_template', 'wp_template_part' ), true );
|
||||
|
||||
if ( $is_cys_complete ) {
|
||||
update_option( 'woocommerce_admin_customize_store_completed', 'yes' );
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -128,7 +144,7 @@ class CustomizeStore extends Task {
|
||||
// Default to is-fullscreen-mode to avoid jumps in the UI.
|
||||
add_filter(
|
||||
'admin_body_class',
|
||||
static function( $classes ) {
|
||||
static function ( $classes ) {
|
||||
return "$classes is-fullscreen-mode";
|
||||
}
|
||||
);
|
||||
@@ -218,13 +234,6 @@ class CustomizeStore extends Task {
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Mark task as complete.
|
||||
*/
|
||||
public function mark_task_as_complete() {
|
||||
update_option( 'woocommerce_admin_customize_store_completed', 'yes' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a small style to hide admin bar
|
||||
*
|
||||
|
||||
@@ -26,7 +26,7 @@ class ExperimentalShippingRecommendation extends Task {
|
||||
* @return string
|
||||
*/
|
||||
public function get_title() {
|
||||
return __( 'Set up shipping', 'woocommerce' );
|
||||
return __( 'Get your products shipped', 'woocommerce' );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,124 @@
|
||||
<?php
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\Features\OnboardingTasks\Tasks;
|
||||
|
||||
use Automattic\WooCommerce\Admin\Features\Features;
|
||||
use Automattic\WooCommerce\Admin\Features\OnboardingTasks\Task;
|
||||
|
||||
/**
|
||||
* Launch Your Store Task
|
||||
*/
|
||||
class LaunchYourStore extends Task {
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param TaskList $task_list Parent task list.
|
||||
*/
|
||||
public function __construct( $task_list ) {
|
||||
parent::__construct( $task_list );
|
||||
|
||||
add_action( 'show_admin_bar', array( $this, 'possibly_hide_wp_admin_bar' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* ID.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_id() {
|
||||
return 'launch-your-store';
|
||||
}
|
||||
|
||||
/**
|
||||
* Title.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_title() {
|
||||
return __( 'Launch your store', 'woocommerce' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Content.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_content() {
|
||||
return __(
|
||||
"It's time to celebrate – you're ready to launch your store! Woo! Hit the button to preview your store and make it public.",
|
||||
'woocommerce'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Time.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_time() {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Action URL.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_action_url() {
|
||||
return admin_url( 'wp-admin/admin.php?page=wc-admin&path=%2Flaunch-your-store' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Task completion.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_complete() {
|
||||
return 'yes' !== get_option( 'woocommerce_coming_soon' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Task visibility.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function can_view() {
|
||||
return Features::is_enabled( 'launch-your-store' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Hide the WP admin bar when the user is previewing the site.
|
||||
*
|
||||
* @param bool $show Whether to show the admin bar.
|
||||
*/
|
||||
public function possibly_hide_wp_admin_bar( $show ) {
|
||||
if ( isset( $_GET['site-preview'] ) ) { // @phpcs:ignore
|
||||
return false;
|
||||
}
|
||||
|
||||
global $wp;
|
||||
$http_referer = wp_get_referer() ?? '';
|
||||
$parsed_url = wp_parse_url( $http_referer, PHP_URL_QUERY );
|
||||
$query_string = is_string( $parsed_url ) ? $parsed_url : '';
|
||||
|
||||
// Check if the user is coming from the site preview link.
|
||||
if ( strpos( $query_string, 'site-preview' ) !== false ) {
|
||||
if ( ! isset( $_SERVER['REQUEST_URI'] ) ) {
|
||||
return $show;
|
||||
}
|
||||
|
||||
// Redirect to the current URL with the site-preview query string.
|
||||
$current_url =
|
||||
add_query_arg(
|
||||
array(
|
||||
'site-preview' => 1,
|
||||
),
|
||||
esc_url_raw( wp_unslash( $_SERVER['REQUEST_URI'] ) )
|
||||
);
|
||||
wp_safe_redirect( $current_url );
|
||||
exit;
|
||||
}
|
||||
|
||||
return $show;
|
||||
}
|
||||
}
|
||||
@@ -10,6 +10,13 @@ use Automattic\WooCommerce\Internal\Admin\RemoteFreeExtensions\Init as RemoteFre
|
||||
* Marketing Task
|
||||
*/
|
||||
class Marketing extends Task {
|
||||
/**
|
||||
* Used to cache is_complete() method result.
|
||||
*
|
||||
* @var null
|
||||
*/
|
||||
private $is_complete_result = null;
|
||||
|
||||
/**
|
||||
* ID.
|
||||
*
|
||||
@@ -25,13 +32,7 @@ class Marketing extends Task {
|
||||
* @return string
|
||||
*/
|
||||
public function get_title() {
|
||||
if ( true === $this->get_parent_option( 'use_completed_title' ) ) {
|
||||
if ( $this->is_complete() ) {
|
||||
return __( 'You added sales channels', 'woocommerce' );
|
||||
}
|
||||
return __( 'Get more sales', 'woocommerce' );
|
||||
}
|
||||
return __( 'Set up marketing tools', 'woocommerce' );
|
||||
return __( 'Grow your business', 'woocommerce' );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -61,7 +62,11 @@ class Marketing extends Task {
|
||||
* @return bool
|
||||
*/
|
||||
public function is_complete() {
|
||||
return self::has_installed_extensions();
|
||||
if ( null === $this->is_complete_result ) {
|
||||
$this->is_complete_result = self::has_installed_extensions();
|
||||
}
|
||||
|
||||
return $this->is_complete_result;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -4,6 +4,7 @@ namespace Automattic\WooCommerce\Admin\Features\OnboardingTasks\Tasks;
|
||||
|
||||
use Automattic\WooCommerce\Admin\Features\Features;
|
||||
use Automattic\WooCommerce\Admin\Features\OnboardingTasks\Task;
|
||||
use Automattic\WooCommerce\Internal\Admin\WcPayWelcomePage;
|
||||
|
||||
/**
|
||||
* Payments Task
|
||||
@@ -12,6 +13,7 @@ class Payments extends Task {
|
||||
|
||||
/**
|
||||
* Used to cache is_complete() method result.
|
||||
*
|
||||
* @var null
|
||||
*/
|
||||
private $is_complete_result = null;
|
||||
@@ -31,13 +33,7 @@ class Payments extends Task {
|
||||
* @return string
|
||||
*/
|
||||
public function get_title() {
|
||||
if ( true === $this->get_parent_option( 'use_completed_title' ) ) {
|
||||
if ( $this->is_complete() ) {
|
||||
return __( 'You set up payments', 'woocommerce' );
|
||||
}
|
||||
return __( 'Set up payments', 'woocommerce' );
|
||||
}
|
||||
return __( 'Set up payments', 'woocommerce' );
|
||||
return __( 'Get paid', 'woocommerce' );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -100,4 +96,30 @@ class Payments extends Task {
|
||||
|
||||
return ! empty( $enabled_gateways );
|
||||
}
|
||||
|
||||
/**
|
||||
* Action URL.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_action_url() {
|
||||
// Check if the WooPayments plugin is active and the store is supported.
|
||||
if ( WooCommercePayments::is_supported() && WooCommercePayments::is_wcpay_active() ) {
|
||||
// If WooPayments is connected, point to the WooPayments overview page.
|
||||
if ( WooCommercePayments::is_connected() ) {
|
||||
return add_query_arg( 'from', 'WCADMIN_PAYMENT_TASK', admin_url( 'admin.php?page=wc-admin&path=/payments/overview' ) );
|
||||
}
|
||||
|
||||
// Point to the WooPayments Connect page.
|
||||
return add_query_arg( 'from', 'WCADMIN_PAYMENT_TASK', admin_url( 'admin.php?page=wc-admin&path=/payments/connect' ) );
|
||||
}
|
||||
|
||||
// Check if there is an active WooPayments incentive via the welcome page.
|
||||
if ( WcPayWelcomePage::instance()->must_be_visible() ) {
|
||||
// Point to the WooPayments welcome page.
|
||||
return add_query_arg( 'from', 'WCADMIN_PAYMENT_TASK', admin_url( 'admin.php?page=wc-admin&path=/wc-pay-welcome-page' ) );
|
||||
}
|
||||
|
||||
return admin_url( 'admin.php?page=wc-admin&task=payments' );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -9,6 +9,7 @@ use Automattic\WooCommerce\Internal\Admin\WCAdminAssets;
|
||||
* Products Task
|
||||
*/
|
||||
class Products extends Task {
|
||||
const PRODUCT_COUNT_TRANSIENT_NAME = 'woocommerce_product_task_product_count_transient';
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
@@ -20,6 +21,11 @@ class Products extends Task {
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'possibly_add_manual_return_notice_script' ) );
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'possibly_add_import_return_notice_script' ) );
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'possibly_add_load_sample_return_notice_script' ) );
|
||||
|
||||
add_action( 'woocommerce_update_product', array( $this, 'delete_product_count_cache' ) );
|
||||
add_action( 'woocommerce_new_product', array( $this, 'delete_product_count_cache' ) );
|
||||
add_action( 'wp_trash_post', array( $this, 'delete_product_count_cache' ) );
|
||||
add_action( 'untrashed_post', array( $this, 'delete_product_count_cache' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -37,13 +43,7 @@ class Products extends Task {
|
||||
* @return string
|
||||
*/
|
||||
public function get_title() {
|
||||
if ( $this->get_parent_option( 'use_completed_title' ) === true ) {
|
||||
if ( $this->is_complete() ) {
|
||||
return __( 'You added products', 'woocommerce' );
|
||||
}
|
||||
return __( 'Add products', 'woocommerce' );
|
||||
}
|
||||
return __( 'Add my products', 'woocommerce' );
|
||||
return __( 'Add your products', 'woocommerce' );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -77,7 +77,7 @@ class Products extends Task {
|
||||
}
|
||||
|
||||
/**
|
||||
* Addtional data.
|
||||
* Additional data.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
@@ -156,12 +156,56 @@ class Products extends Task {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the store has any published products.
|
||||
* Delete the product count transient used in has_products() method to refresh the cache.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function delete_product_count_cache() {
|
||||
delete_transient( self::PRODUCT_COUNT_TRANSIENT_NAME );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the store has any user created published products.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function has_products() {
|
||||
$counts = wp_count_posts('product');
|
||||
return isset( $counts->publish ) && $counts->publish > 0;
|
||||
$product_counts = get_transient( self::PRODUCT_COUNT_TRANSIENT_NAME );
|
||||
if ( false !== $product_counts && is_numeric( $product_counts ) ) {
|
||||
return (int) $product_counts > 0;
|
||||
}
|
||||
|
||||
$product_counts = self::count_user_products();
|
||||
set_transient( self::PRODUCT_COUNT_TRANSIENT_NAME, $product_counts );
|
||||
return $product_counts > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Count the number of user created products.
|
||||
* Generated products have the _headstart_post meta key.
|
||||
*
|
||||
* @return int The number of user created products.
|
||||
*/
|
||||
private static function count_user_products() {
|
||||
$args = array(
|
||||
'post_type' => 'product',
|
||||
'post_status' => 'publish',
|
||||
'fields' => 'ids',
|
||||
'meta_query' => array( // phpcs:ignore WordPress.DB.SlowDBQuery.slow_db_query_meta_query
|
||||
'relation' => 'OR',
|
||||
array(
|
||||
'key' => '_headstart_post',
|
||||
'compare' => 'NOT EXISTS',
|
||||
),
|
||||
array(
|
||||
'key' => '_edit_last',
|
||||
'compare' => 'EXISTS',
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
$products_query = new \WP_Query( $args );
|
||||
|
||||
return $products_query->found_posts;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -45,13 +45,7 @@ class Shipping extends Task {
|
||||
* @return string
|
||||
*/
|
||||
public function get_title() {
|
||||
if ( true === $this->get_parent_option( 'use_completed_title' ) ) {
|
||||
if ( $this->is_complete() ) {
|
||||
return __( 'You added shipping costs', 'woocommerce' );
|
||||
}
|
||||
return __( 'Add shipping costs', 'woocommerce' );
|
||||
}
|
||||
return __( 'Set up shipping', 'woocommerce' );
|
||||
return __( 'Select your shipping options', 'woocommerce' );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -0,0 +1,73 @@
|
||||
<?php
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\Features\OnboardingTasks\Tasks;
|
||||
|
||||
use Automattic\WooCommerce\Admin\Features\OnboardingTasks\Task;
|
||||
|
||||
/**
|
||||
* Connect store to WooCommerce.com Task
|
||||
*/
|
||||
class StoreConnect extends Task {
|
||||
/**
|
||||
* ID.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_id() {
|
||||
return 'connect-store';
|
||||
}
|
||||
|
||||
/**
|
||||
* Title.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_title() {
|
||||
return __( 'Manage your WooCommerce.com Marketplace subscriptions', 'woocommerce' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Content.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_content() {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Time.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_time() {
|
||||
return '';
|
||||
}
|
||||
|
||||
/**
|
||||
* Task completion.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_complete() {
|
||||
return \WC_Helper::is_site_connected();
|
||||
}
|
||||
|
||||
/**
|
||||
* Always dismissable.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public function is_dismissable() {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Action URL.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_action_url() {
|
||||
return admin_url( 'admin.php?page=wc-admin&tab=my-subscriptions&path=/extensions' );
|
||||
}
|
||||
}
|
||||
@@ -62,13 +62,7 @@ class Tax extends Task {
|
||||
* @return string
|
||||
*/
|
||||
public function get_title() {
|
||||
if ( $this->get_parent_option( 'use_completed_title' ) === true ) {
|
||||
if ( $this->is_complete() ) {
|
||||
return __( 'You added tax rates', 'woocommerce' );
|
||||
}
|
||||
return __( 'Add tax rates', 'woocommerce' );
|
||||
}
|
||||
return __( 'Set up tax rates', 'woocommerce' );
|
||||
return __( 'Collect sales tax', 'woocommerce' );
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -34,7 +34,7 @@ class WooCommercePayments extends Task {
|
||||
* @return string
|
||||
*/
|
||||
public function get_title() {
|
||||
return __( 'Set up WooPayments', 'woocommerce' );
|
||||
return __( 'Get paid with WooPayments', 'woocommerce' );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -82,18 +82,6 @@ class WooCommercePayments extends Task {
|
||||
return __( 'Finish setup', 'woocommerce' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Additional info.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_additional_info() {
|
||||
return __(
|
||||
'Accept credit/debit cards and other popular payment methods with no setup or monthly fees — and manage payments right from your store dashboard.',
|
||||
'woocommerce'
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Task completion.
|
||||
*
|
||||
@@ -121,7 +109,7 @@ class WooCommercePayments extends Task {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the plugin was requested during onboarding.
|
||||
* Check if the WooPayments plugin was requested during onboarding.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@@ -135,7 +123,7 @@ class WooCommercePayments extends Task {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if the plugin is installed.
|
||||
* Check if the WooPayments plugin is installed.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@@ -145,7 +133,16 @@ class WooCommercePayments extends Task {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if WooCommerce Payments is connected.
|
||||
* Check if the WooPayments plugin is active.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
public static function is_wcpay_active() {
|
||||
return class_exists( '\WC_Payments' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if WooPayments is connected.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
@@ -161,7 +158,7 @@ class WooCommercePayments extends Task {
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if WooCommerce Payments needs setup.
|
||||
* Check if WooPayments needs setup.
|
||||
* Errored data or payments not enabled.
|
||||
*
|
||||
* @return bool
|
||||
|
||||
@@ -57,7 +57,7 @@ class DefaultPaymentGateways {
|
||||
'image' => WC_ADMIN_IMAGES_FOLDER_URL . '/payment_methods/72x72/affirm.png',
|
||||
'image_72x72' => WC_ADMIN_IMAGES_FOLDER_URL . '/payment_methods/72x72/affirm.png',
|
||||
'plugins' => array(),
|
||||
'external_link' => 'https://woo.com/products/woocommerce-gateway-affirm',
|
||||
'external_link' => 'https://woocommerce.com/products/woocommerce-gateway-affirm',
|
||||
'is_visible' => array(
|
||||
self::get_rules_for_countries(
|
||||
array(
|
||||
@@ -718,8 +718,8 @@ class DefaultPaymentGateways {
|
||||
),
|
||||
array(
|
||||
'id' => 'woo-mercado-pago-custom',
|
||||
'title' => __( 'Mercado Pago Checkout Pro & Custom', 'woocommerce' ),
|
||||
'content' => __( 'Accept credit and debit cards, offline (cash or bank transfer) and logged-in payments with money in Mercado Pago. Safe and secure payments with the leading payment processor in LATAM.', 'woocommerce' ),
|
||||
'title' => __( 'Mercado Pago', 'woocommerce' ),
|
||||
'content' => __( 'Set up your payment methods and accept credit and debit cards, cash, bank transfers and money from your Mercado Pago account. Offer safe and secure payments with Latin America’s leading processor.', 'woocommerce' ),
|
||||
'image' => WC_ADMIN_IMAGES_FOLDER_URL . '/onboarding/mercadopago.png',
|
||||
'image_72x72' => WC_ADMIN_IMAGES_FOLDER_URL . '/payment_methods/72x72/mercadopago.png',
|
||||
'plugins' => array( 'woocommerce-mercadopago' ),
|
||||
@@ -1049,8 +1049,8 @@ class DefaultPaymentGateways {
|
||||
'klarna_payments',
|
||||
'amazon_payments_advanced',
|
||||
),
|
||||
'BG' => array( 'stripe', 'ppcp-gateway' ),
|
||||
'HR' => array( 'ppcp-gateway' ),
|
||||
'BG' => array( 'woocommerce_payments', 'stripe', 'ppcp-gateway' ),
|
||||
'HR' => array( 'woocommerce_payments', 'ppcp-gateway' ),
|
||||
'CH' => array(
|
||||
'woocommerce_payments',
|
||||
'stripe',
|
||||
@@ -1058,15 +1058,16 @@ class DefaultPaymentGateways {
|
||||
'mollie_wc_gateway_banktransfer',
|
||||
'klarna_payments',
|
||||
),
|
||||
'CY' => array( 'stripe', 'ppcp-gateway', 'amazon_payments_advanced' ),
|
||||
'CZ' => array( 'stripe', 'ppcp-gateway' ),
|
||||
'CY' => array( 'woocommerce_payments', 'stripe', 'ppcp-gateway', 'amazon_payments_advanced' ),
|
||||
'CZ' => array( 'woocommerce_payments', 'stripe', 'ppcp-gateway' ),
|
||||
'DK' => array(
|
||||
'woocommerce_payments',
|
||||
'stripe',
|
||||
'ppcp-gateway',
|
||||
'klarna_payments',
|
||||
'amazon_payments_advanced',
|
||||
),
|
||||
'EE' => array( 'stripe', 'ppcp-gateway', 'airwallex_main' ),
|
||||
'EE' => array( 'woocommerce_payments', 'stripe', 'ppcp-gateway', 'airwallex_main' ),
|
||||
'ES' => array(
|
||||
'woocommerce_payments',
|
||||
'stripe',
|
||||
@@ -1077,6 +1078,7 @@ class DefaultPaymentGateways {
|
||||
'amazon_payments_advanced',
|
||||
),
|
||||
'FI' => array(
|
||||
'woocommerce_payments',
|
||||
'stripe',
|
||||
'ppcp-gateway',
|
||||
'mollie_wc_gateway_banktransfer',
|
||||
@@ -1112,8 +1114,8 @@ class DefaultPaymentGateways {
|
||||
'klarna_payments',
|
||||
'amazon_payments_advanced',
|
||||
),
|
||||
'GR' => array( 'stripe', 'ppcp-gateway' ),
|
||||
'HU' => array( 'stripe', 'ppcp-gateway', 'amazon_payments_advanced' ),
|
||||
'GR' => array( 'woocommerce_payments', 'stripe', 'ppcp-gateway', 'airwallex_main' ),
|
||||
'HU' => array( 'woocommerce_payments', 'stripe', 'ppcp-gateway', 'amazon_payments_advanced' ),
|
||||
'IE' => array(
|
||||
'woocommerce_payments',
|
||||
'stripe',
|
||||
@@ -1131,10 +1133,10 @@ class DefaultPaymentGateways {
|
||||
'klarna_payments',
|
||||
'amazon_payments_advanced',
|
||||
),
|
||||
'LV' => array( 'stripe', 'ppcp-gateway' ),
|
||||
'LT' => array( 'stripe', 'ppcp-gateway' ),
|
||||
'LU' => array( 'stripe', 'ppcp-gateway', 'amazon_payments_advanced' ),
|
||||
'MT' => array( 'stripe', 'ppcp-gateway' ),
|
||||
'LV' => array( 'woocommerce_payments', 'stripe', 'ppcp-gateway' ),
|
||||
'LT' => array( 'woocommerce_payments', 'stripe', 'ppcp-gateway' ),
|
||||
'LU' => array( 'woocommerce_payments', 'stripe', 'ppcp-gateway', 'amazon_payments_advanced' ),
|
||||
'MT' => array( 'woocommerce_payments', 'stripe', 'ppcp-gateway' ),
|
||||
'NL' => array(
|
||||
'woocommerce_payments',
|
||||
'stripe',
|
||||
@@ -1144,7 +1146,7 @@ class DefaultPaymentGateways {
|
||||
'klarna_payments',
|
||||
'amazon_payments_advanced',
|
||||
),
|
||||
'NO' => array( 'stripe', 'ppcp-gateway', 'kco', 'klarna_payments' ),
|
||||
'NO' => array( 'woocommerce_payments', 'stripe', 'ppcp-gateway', 'kco', 'klarna_payments' ),
|
||||
'PL' => array(
|
||||
'woocommerce_payments',
|
||||
'stripe',
|
||||
@@ -1157,12 +1159,14 @@ class DefaultPaymentGateways {
|
||||
'woocommerce_payments',
|
||||
'stripe',
|
||||
'ppcp-gateway',
|
||||
'airwallex_main',
|
||||
'amazon_payments_advanced',
|
||||
),
|
||||
'RO' => array( 'stripe', 'ppcp-gateway' ),
|
||||
'SK' => array( 'stripe', 'ppcp-gateway' ),
|
||||
'SL' => array( 'stripe', 'ppcp-gateway', 'amazon_payments_advanced' ),
|
||||
'RO' => array( 'woocommerce_payments', 'stripe', 'ppcp-gateway' ),
|
||||
'SK' => array( 'woocommerce_payments', 'stripe', 'ppcp-gateway' ),
|
||||
'SL' => array( 'woocommerce_payments', 'stripe', 'ppcp-gateway', 'amazon_payments_advanced' ),
|
||||
'SE' => array(
|
||||
'woocommerce_payments',
|
||||
'stripe',
|
||||
'ppcp-gateway',
|
||||
'kco',
|
||||
@@ -1213,6 +1217,7 @@ class DefaultPaymentGateways {
|
||||
'payoneer-checkout',
|
||||
),
|
||||
'JP' => array(
|
||||
'woocommerce_payments',
|
||||
'stripe',
|
||||
'ppcp-gateway',
|
||||
'square_credit_card',
|
||||
@@ -1227,6 +1232,7 @@ class DefaultPaymentGateways {
|
||||
'ZA' => array( 'payfast', 'paystack' ),
|
||||
'NG' => array( 'paystack' ),
|
||||
'GH' => array( 'paystack' ),
|
||||
'AE' => array( 'woocommerce_payments' ),
|
||||
);
|
||||
|
||||
// If the country code is not in the list, return default priority.
|
||||
|
||||
@@ -7,7 +7,7 @@ namespace Automattic\WooCommerce\Admin\Features\PaymentGatewaySuggestions;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use Automattic\WooCommerce\Admin\RemoteInboxNotifications\RuleEvaluator;
|
||||
use Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\RuleEvaluator;
|
||||
|
||||
/**
|
||||
* Evaluates the spec and returns the evaluated suggestion.
|
||||
|
||||
@@ -18,7 +18,7 @@ class PaymentGatewaySuggestionsDataSourcePoller extends DataSourcePoller {
|
||||
* Default data sources array.
|
||||
*/
|
||||
const DATA_SOURCES = array(
|
||||
'https://woocommerce.com/wp-json/wccom/payment-gateway-suggestions/1.0/suggestions.json',
|
||||
'https://woocommerce.com/wp-json/wccom/payment-gateway-suggestions/2.0/suggestions.json',
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@@ -41,6 +41,7 @@ class BlockRegistry {
|
||||
'woocommerce/product-text-area-field',
|
||||
'woocommerce/product-number-field',
|
||||
'woocommerce/product-linked-list-field',
|
||||
'woocommerce/product-select-field',
|
||||
);
|
||||
|
||||
/**
|
||||
@@ -48,6 +49,8 @@ class BlockRegistry {
|
||||
*/
|
||||
const PRODUCT_FIELDS_BLOCKS = array(
|
||||
'woocommerce/product-catalog-visibility-field',
|
||||
'woocommerce/product-custom-fields',
|
||||
'woocommerce/product-custom-fields-toggle-field',
|
||||
'woocommerce/product-description-field',
|
||||
'woocommerce/product-downloads-field',
|
||||
'woocommerce/product-images-field',
|
||||
|
||||
@@ -10,8 +10,8 @@ use Automattic\WooCommerce\Admin\Features\ProductBlockEditor\ProductTemplate;
|
||||
use Automattic\WooCommerce\Admin\PageController;
|
||||
use Automattic\WooCommerce\LayoutTemplates\LayoutTemplateRegistry;
|
||||
|
||||
use Automattic\WooCommerce\Internal\Admin\Features\ProductBlockEditor\ProductTemplates\SimpleProductTemplate;
|
||||
use Automattic\WooCommerce\Internal\Admin\Features\ProductBlockEditor\ProductTemplates\ProductVariationTemplate;
|
||||
use Automattic\WooCommerce\Internal\Features\ProductBlockEditor\ProductTemplates\SimpleProductTemplate;
|
||||
use Automattic\WooCommerce\Internal\Features\ProductBlockEditor\ProductTemplates\ProductVariationTemplate;
|
||||
|
||||
use WP_Block_Editor_Context;
|
||||
|
||||
@@ -76,6 +76,9 @@ class Init {
|
||||
add_action( 'current_screen', array( $this, 'set_current_screen_to_block_editor_if_wc_admin' ) );
|
||||
|
||||
add_action( 'rest_api_init', array( $this, 'register_layout_templates' ) );
|
||||
add_action( 'rest_api_init', array( $this, 'register_user_metas' ) );
|
||||
|
||||
add_filter( 'register_block_type_args', array( $this, 'register_metadata_attribute' ) );
|
||||
|
||||
// Make sure the block registry is initialized so that core blocks are registered.
|
||||
BlockRegistry::get_instance();
|
||||
@@ -112,6 +115,9 @@ class Init {
|
||||
);
|
||||
wp_tinymce_inline_scripts();
|
||||
wp_enqueue_media();
|
||||
wp_register_style( 'wc-global-presets', false ); // phpcs:ignore
|
||||
wp_add_inline_style( 'wc-global-presets', wp_get_global_stylesheet( array( 'presets' ) ) );
|
||||
wp_enqueue_style( 'wc-global-presets' );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -379,4 +385,68 @@ class Init {
|
||||
|
||||
$this->redirection_controller->set_product_templates( $this->product_templates );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register user metas.
|
||||
*/
|
||||
public function register_user_metas() {
|
||||
register_rest_field(
|
||||
'user',
|
||||
'metaboxhidden_product',
|
||||
array(
|
||||
'get_callback' => function ( $object, $attr ) {
|
||||
$hidden = get_user_meta( $object['id'], $attr, true );
|
||||
|
||||
if ( is_array( $hidden ) ) {
|
||||
// Ensures to always return a string array.
|
||||
return array_values( $hidden );
|
||||
}
|
||||
|
||||
return array( 'postcustom' );
|
||||
},
|
||||
'update_callback' => function ( $value, $object, $attr ) {
|
||||
// Update the field/meta value.
|
||||
update_user_meta( $object->ID, $attr, $value );
|
||||
},
|
||||
'schema' => array(
|
||||
'type' => 'array',
|
||||
'description' => __( 'The metaboxhidden_product meta from the user metas.', 'woocommerce' ),
|
||||
'items' => array(
|
||||
'type' => 'string',
|
||||
),
|
||||
'arg_options' => array(
|
||||
'sanitize_callback' => 'wp_parse_list',
|
||||
'validate_callback' => 'rest_validate_request_arg',
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Registers the metadata block attribute for all block types.
|
||||
* This is a fallback/temporary solution until
|
||||
* the Gutenberg core version registers the metadata attribute.
|
||||
*
|
||||
* @see https://github.com/WordPress/gutenberg/blob/6aaa3686ae67adc1a6a6b08096d3312859733e1b/lib/compat/wordpress-6.5/blocks.php#L27-L47
|
||||
* To do: Remove this method once the Gutenberg core version registers the metadata attribute.
|
||||
*
|
||||
* @param array $args Array of arguments for registering a block type.
|
||||
* @return array $args
|
||||
*/
|
||||
public function register_metadata_attribute( $args ) {
|
||||
// Setup attributes if needed.
|
||||
if ( ! isset( $args['attributes'] ) || ! is_array( $args['attributes'] ) ) {
|
||||
$args['attributes'] = array();
|
||||
}
|
||||
|
||||
// Add metadata attribute if it doesn't exist.
|
||||
if ( ! array_key_exists( 'metadata', $args['attributes'] ) ) {
|
||||
$args['attributes']['metadata'] = array(
|
||||
'type' => 'object',
|
||||
);
|
||||
}
|
||||
|
||||
return $args;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -61,6 +61,13 @@ class ProductTemplate {
|
||||
*/
|
||||
private $icon = null;
|
||||
|
||||
/**
|
||||
* If the template is directly selectable through the UI.
|
||||
*
|
||||
* @var boolean
|
||||
*/
|
||||
private $is_selectable_by_user = true;
|
||||
|
||||
/**
|
||||
* ProductTemplate constructor
|
||||
*
|
||||
@@ -86,6 +93,10 @@ class ProductTemplate {
|
||||
if ( isset( $data['icon'] ) ) {
|
||||
$this->icon = $data['icon'];
|
||||
}
|
||||
|
||||
if ( isset( $data['is_selectable_by_user'] ) ) {
|
||||
$this->is_selectable_by_user = $data['is_selectable_by_user'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -180,6 +191,15 @@ class ProductTemplate {
|
||||
return $this->order;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the selectable attribute.
|
||||
*
|
||||
* @return boolean Selectable.
|
||||
*/
|
||||
public function get_is_selectable_by_user() {
|
||||
return $this->is_selectable_by_user;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the template order.
|
||||
*
|
||||
@@ -196,13 +216,14 @@ class ProductTemplate {
|
||||
*/
|
||||
public function to_json() {
|
||||
return array(
|
||||
'id' => $this->get_id(),
|
||||
'title' => $this->get_title(),
|
||||
'description' => $this->get_description(),
|
||||
'icon' => $this->get_icon(),
|
||||
'order' => $this->get_order(),
|
||||
'layoutTemplateId' => $this->get_layout_template_id(),
|
||||
'productData' => $this->get_product_data(),
|
||||
'id' => $this->get_id(),
|
||||
'title' => $this->get_title(),
|
||||
'description' => $this->get_description(),
|
||||
'icon' => $this->get_icon(),
|
||||
'order' => $this->get_order(),
|
||||
'layoutTemplateId' => $this->get_layout_template_id(),
|
||||
'productData' => $this->get_product_data(),
|
||||
'isSelectableByUser' => $this->get_is_selectable_by_user(),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -114,7 +114,7 @@ class DefaultShippingPartners {
|
||||
'image' => $asset_base_url . 'envia-column.svg',
|
||||
'features' => $column_layout_features,
|
||||
),
|
||||
'learn_more_link' => 'https://woo.com/products/envia-shipping-and-fulfillment/',
|
||||
'learn_more_link' => 'https://woocommerce.com/products/envia-shipping-and-fulfillment/',
|
||||
'is_visible' => array(
|
||||
self::get_rules_for_countries( array( 'CL', 'AR', 'PE', 'BR', 'UY', 'GT' ) ),
|
||||
),
|
||||
@@ -157,7 +157,7 @@ class DefaultShippingPartners {
|
||||
),
|
||||
),
|
||||
),
|
||||
'learn_more_link' => 'https://woo.com/products/easyship-shipping-rates/',
|
||||
'learn_more_link' => 'https://woocommerce.com/products/easyship-shipping-rates/',
|
||||
'is_visible' => array(
|
||||
self::get_rules_for_countries( array( 'SG', 'HK', 'AU', 'NZ' ) ),
|
||||
),
|
||||
@@ -282,7 +282,7 @@ class DefaultShippingPartners {
|
||||
),
|
||||
),
|
||||
),
|
||||
'learn_more_link' => 'https://woo.com/products/shipping/',
|
||||
'learn_more_link' => 'https://woocommerce.com/products/shipping/',
|
||||
'is_visible' => array(
|
||||
self::get_rules_for_countries( array( 'US' ) ),
|
||||
),
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\Features\ShippingPartnerSuggestions;
|
||||
|
||||
use Automattic\WooCommerce\Admin\DataSourcePoller;
|
||||
use Automattic\WooCommerce\Admin\RemoteSpecs\DataSourcePoller;
|
||||
|
||||
/**
|
||||
* Specs data source poller class for shipping partner suggestions.
|
||||
@@ -18,7 +18,7 @@ class ShippingPartnerSuggestionsDataSourcePoller extends DataSourcePoller {
|
||||
* Default data sources array.
|
||||
*/
|
||||
const DATA_SOURCES = array(
|
||||
'https://woocommerce.com/wp-json/wccom/shipping-partner-suggestions/1.0/suggestions.json',
|
||||
'https://woocommerce.com/wp-json/wccom/shipping-partner-suggestions/2.0/suggestions.json',
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@@ -36,7 +36,7 @@ class Loader extends DeprecatedClassFacade {
|
||||
* @deprecated since 5.0.0, use Features::is_enabled( $feature )
|
||||
*/
|
||||
public static function is_feature_enabled( $feature ) {
|
||||
wc_deprecated_function( 'is_feature_enabled', '5.0', '\Automattic\WooCommerce\Internal\Admin\Features\Features::is_enabled()' );
|
||||
wc_deprecated_function( 'is_feature_enabled', '5.0', '\Automattic\WooCommerce\Internal\Features\Features::is_enabled()' );
|
||||
return Features::is_enabled( $feature );
|
||||
}
|
||||
|
||||
|
||||
@@ -275,7 +275,7 @@ class InstalledExtensions {
|
||||
$data = self::get_extension_base_data( $slug );
|
||||
$data['icon'] = WC_ADMIN_IMAGES_FOLDER_URL . '/marketing/pinterest.svg';
|
||||
|
||||
$data['docsUrl'] = 'https://woo.com/document/pinterest-for-woocommerce/?utm_medium=product';
|
||||
$data['docsUrl'] = 'https://woocommerce.com/document/pinterest-for-woocommerce/?utm_medium=product';
|
||||
|
||||
if ( 'activated' === $data['status'] && class_exists( 'Pinterest_For_Woocommerce' ) ) {
|
||||
$pinterest_onboarding_completed = Pinterest_For_Woocommerce()::is_setup_complete();
|
||||
@@ -316,7 +316,7 @@ class InstalledExtensions {
|
||||
$data['settingsUrl'] = admin_url( 'admin.php?page=wc-admin&path=/google/start' );
|
||||
}
|
||||
|
||||
$data['docsUrl'] = 'https://woo.com/document/google-listings-and-ads/?utm_medium=product';
|
||||
$data['docsUrl'] = 'https://woocommerce.com/document/google-listings-and-ads/?utm_medium=product';
|
||||
}
|
||||
|
||||
return $data;
|
||||
@@ -347,7 +347,7 @@ class InstalledExtensions {
|
||||
}
|
||||
|
||||
$data['settingsUrl'] = admin_url( 'admin.php?page=codisto-settings' );
|
||||
$data['docsUrl'] = 'https://woo.com/document/multichannel-for-woocommerce-google-amazon-ebay-walmart-integration/?utm_medium=product';
|
||||
$data['docsUrl'] = 'https://woocommerce.com/document/multichannel-for-woocommerce-google-amazon-ebay-walmart-integration/?utm_medium=product';
|
||||
}
|
||||
|
||||
return $data;
|
||||
@@ -463,7 +463,7 @@ class InstalledExtensions {
|
||||
}
|
||||
|
||||
$data['settingsUrl'] = admin_url( 'admin.php?page=tiktok' );
|
||||
$data['docsUrl'] = 'https://woo.com/document/tiktok-for-woocommerce/';
|
||||
$data['docsUrl'] = 'https://woocommerce.com/document/tiktok-for-woocommerce/';
|
||||
$data['supportUrl'] = 'https://ads.tiktok.com/athena/user-feedback/?identify_key=6a1e079024806640c5e1e695d13db80949525168a052299b4970f9c99cb5ac78';
|
||||
}
|
||||
|
||||
@@ -540,7 +540,7 @@ class InstalledExtensions {
|
||||
}
|
||||
|
||||
$data['settingsUrl'] = admin_url( 'admin.php?page=integration-with-salesforce' );
|
||||
$data['docsUrl'] = 'https://woo.com/document/salesforce-integration/';
|
||||
$data['docsUrl'] = 'https://woocommerce.com/document/salesforce-integration/';
|
||||
$data['supportUrl'] = 'https://wpswings.com/submit-query/';
|
||||
}
|
||||
|
||||
@@ -573,7 +573,7 @@ class InstalledExtensions {
|
||||
}
|
||||
|
||||
$data['settingsUrl'] = admin_url( 'options-general.php?page=vimeo_settings' );
|
||||
$data['docsUrl'] = 'https://woo.com/document/vimeo/';
|
||||
$data['docsUrl'] = 'https://woocommerce.com/document/vimeo/';
|
||||
$data['supportUrl'] = 'https://vimeo.com/help/contact';
|
||||
}
|
||||
|
||||
@@ -598,7 +598,7 @@ class InstalledExtensions {
|
||||
if ( 'activated' === $data['status'] ) {
|
||||
$data['status'] = 'configured';
|
||||
$data['settingsUrl'] = admin_url( 'admin.php?page=woocommerce-trustpilot-settings-page' );
|
||||
$data['docsUrl'] = 'https://woo.com/document/trustpilot-reviews/';
|
||||
$data['docsUrl'] = 'https://woocommerce.com/document/trustpilot-reviews/';
|
||||
$data['supportUrl'] = 'https://support.trustpilot.com/hc/en-us/requests/new';
|
||||
}
|
||||
|
||||
@@ -626,7 +626,7 @@ class InstalledExtensions {
|
||||
'status' => $status,
|
||||
'name' => $plugin_data['Name'],
|
||||
'description' => html_entity_decode( wp_trim_words( $plugin_data['Description'], 20 ) ),
|
||||
'supportUrl' => 'https://woo.com/my-account/create-a-ticket/?utm_medium=product',
|
||||
'supportUrl' => 'https://woocommerce.com/my-account/create-a-ticket/?utm_medium=product',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -37,6 +37,7 @@ class DataStore extends \WC_Data_Store_WP implements \WC_Object_Data_Store_Inter
|
||||
'layout' => $note->get_layout(),
|
||||
'image' => $note->get_image(),
|
||||
'is_deleted' => (int) $note->get_is_deleted(),
|
||||
'is_read' => (int) $note->get_is_read(),
|
||||
);
|
||||
|
||||
$note_to_be_inserted['content_data'] = wp_json_encode( $note->get_content_data() );
|
||||
@@ -109,7 +110,7 @@ class DataStore extends \WC_Data_Store_WP implements \WC_Object_Data_Store_Inter
|
||||
$note->set_source( $note_row->source );
|
||||
$note->set_date_created( $note_row->date_created );
|
||||
$note->set_date_reminder( $note_row->date_reminder );
|
||||
$note->set_is_snoozable( $note_row->is_snoozable );
|
||||
$note->set_is_snoozable( (bool) $note_row->is_snoozable );
|
||||
$note->set_is_deleted( (bool) $note_row->is_deleted );
|
||||
isset( $note_row->is_read ) && $note->set_is_read( (bool) $note_row->is_read );
|
||||
$note->set_layout( $note_row->layout );
|
||||
@@ -162,11 +163,11 @@ class DataStore extends \WC_Data_Store_WP implements \WC_Object_Data_Store_Inter
|
||||
'source' => $note->get_source(),
|
||||
'date_created' => $date_created_to_db,
|
||||
'date_reminder' => $date_reminder_to_db,
|
||||
'is_snoozable' => $note->get_is_snoozable(),
|
||||
'is_snoozable' => (int) $note->get_is_snoozable(),
|
||||
'layout' => $note->get_layout(),
|
||||
'image' => $note->get_image(),
|
||||
'is_deleted' => $note->get_is_deleted(),
|
||||
'is_read' => $note->get_is_read(),
|
||||
'is_deleted' => (int) $note->get_is_deleted(),
|
||||
'is_read' => (int) $note->get_is_read(),
|
||||
),
|
||||
array( 'note_id' => $note->get_id() )
|
||||
);
|
||||
|
||||
@@ -339,7 +339,7 @@ class Note extends \WC_Data {
|
||||
* Get deleted status.
|
||||
*
|
||||
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
|
||||
* @return array
|
||||
* @return bool
|
||||
*/
|
||||
public function get_is_deleted( $context = 'view' ) {
|
||||
return $this->get_prop( 'is_deleted', $context );
|
||||
@@ -349,7 +349,7 @@ class Note extends \WC_Data {
|
||||
* Get is_read status.
|
||||
*
|
||||
* @param string $context What the value is for. Valid values are 'view' and 'edit'.
|
||||
* @return array
|
||||
* @return bool
|
||||
*/
|
||||
public function get_is_read( $context = 'view' ) {
|
||||
return $this->get_prop( 'is_read', $context );
|
||||
|
||||
@@ -167,16 +167,17 @@ class PageController {
|
||||
return apply_filters( 'woocommerce_navigation_get_breadcrumbs', array( '' ), $current_page );
|
||||
}
|
||||
|
||||
$current_page['title'] = (array) $current_page['title'];
|
||||
if ( 1 === count( $current_page['title'] ) ) {
|
||||
$breadcrumbs = $current_page['title'];
|
||||
$page_title = ! empty( $current_page['page_title'] ) ? $current_page['page_title'] : $current_page['title'];
|
||||
$page_title = (array) $page_title;
|
||||
if ( 1 === count( $page_title ) ) {
|
||||
$breadcrumbs = $page_title;
|
||||
} else {
|
||||
// If this page has multiple title pieces, only link the first one.
|
||||
$breadcrumbs = array_merge(
|
||||
array(
|
||||
array( $current_page['path'], reset( $current_page['title'] ) ),
|
||||
array( $current_page['path'], reset( $page_title ) ),
|
||||
),
|
||||
array_slice( $current_page['title'], 1 )
|
||||
array_slice( $page_title, 1 )
|
||||
);
|
||||
}
|
||||
|
||||
@@ -438,6 +439,7 @@ class PageController {
|
||||
'id' => null,
|
||||
'parent' => null,
|
||||
'title' => '',
|
||||
'page_title' => '',
|
||||
'capability' => 'view_woocommerce_reports',
|
||||
'path' => '',
|
||||
'icon' => '',
|
||||
@@ -455,9 +457,13 @@ class PageController {
|
||||
$options['position'] = intval( round( $options['position'] ) );
|
||||
}
|
||||
|
||||
if ( empty( $options['page_title'] ) ) {
|
||||
$options['page_title'] = $options['title'];
|
||||
}
|
||||
|
||||
if ( is_null( $options['parent'] ) ) {
|
||||
add_menu_page(
|
||||
$options['title'],
|
||||
$options['page_title'],
|
||||
$options['title'],
|
||||
$options['capability'],
|
||||
$options['path'],
|
||||
@@ -470,7 +476,7 @@ class PageController {
|
||||
// @todo check for null path.
|
||||
add_submenu_page(
|
||||
$parent_path,
|
||||
$options['title'],
|
||||
$options['page_title'],
|
||||
$options['title'],
|
||||
$options['capability'],
|
||||
$options['path'],
|
||||
|
||||
@@ -13,7 +13,10 @@ use ActionScheduler_QueueRunner;
|
||||
use Automatic_Upgrader_Skin;
|
||||
use Automattic\WooCommerce\Admin\PluginsInstallLoggers\AsyncPluginsInstallLogger;
|
||||
use Automattic\WooCommerce\Admin\PluginsInstallLoggers\PluginsInstallLogger;
|
||||
use Automattic\WooCommerce\Internal\Admin\WCAdminAssets;
|
||||
use Plugin_Upgrader;
|
||||
use WC_Helper;
|
||||
use WC_Helper_Updater;
|
||||
use WP_Error;
|
||||
use WP_Upgrader;
|
||||
|
||||
@@ -35,6 +38,9 @@ class PluginsHelper {
|
||||
add_action( 'woocommerce_plugins_install_callback', array( __CLASS__, 'install_plugins' ), 10, 2 );
|
||||
add_action( 'woocommerce_plugins_install_and_activate_async_callback', array( __CLASS__, 'install_and_activate_plugins_async_callback' ), 10, 2 );
|
||||
add_action( 'woocommerce_plugins_activate_callback', array( __CLASS__, 'activate_plugins' ), 10, 2 );
|
||||
add_action( 'admin_notices', array( __CLASS__, 'maybe_show_connect_notice_in_plugin_list' ) );
|
||||
add_action( 'admin_enqueue_scripts', array( __CLASS__, 'maybe_enqueue_scripts_for_connect_notice' ) );
|
||||
add_action( 'admin_enqueue_scripts', array( __CLASS__, 'maybe_enqueue_scripts_for_connect_notice_in_plugins' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -532,4 +538,80 @@ class PluginsHelper {
|
||||
return self::get_action_data( $actions );
|
||||
}
|
||||
|
||||
/**
|
||||
* Show notices to connect to woocommerce.com for unconnected store in the plugin list.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function maybe_show_connect_notice_in_plugin_list() {
|
||||
if ( 'woocommerce_page_wc-settings' !== get_current_screen()->id ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$notice_type = WC_Helper_Updater::get_woo_connect_notice_type();
|
||||
|
||||
if ( 'none' === $notice_type ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$notice_string = '';
|
||||
|
||||
if ( 'long' === $notice_type ) {
|
||||
$notice_string .= __( 'Your store might be at risk as you are running old versions of WooCommerce plugins.', 'woocommerce' );
|
||||
$notice_string .= ' ';
|
||||
}
|
||||
|
||||
$connect_page_url = add_query_arg(
|
||||
array(
|
||||
'page' => 'wc-admin',
|
||||
'tab' => 'my-subscriptions',
|
||||
'path' => rawurlencode( '/extensions' ),
|
||||
),
|
||||
admin_url( 'admin.php' )
|
||||
);
|
||||
|
||||
$notice_string .= sprintf(
|
||||
/* translators: %s: Connect page URL */
|
||||
__( '<a id="woo-connect-notice-url" href="%s">Connect your store</a> to WooCommerce.com to get updates and streamlined support for your subscriptions.', 'woocommerce' ),
|
||||
esc_url( $connect_page_url )
|
||||
);
|
||||
|
||||
echo '<div class="woo-connect-notice notice notice-error is-dismissible">
|
||||
<p class="widefat">' . wp_kses_post( $notice_string ) . '</p>
|
||||
</div>';
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue scripts for connect notice in WooCommerce settings page.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function maybe_enqueue_scripts_for_connect_notice() {
|
||||
if ( 'woocommerce_page_wc-settings' !== get_current_screen()->id ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$notice_type = WC_Helper_Updater::get_woo_connect_notice_type();
|
||||
|
||||
if ( 'none' === $notice_type ) {
|
||||
return;
|
||||
}
|
||||
|
||||
WCAdminAssets::register_script( 'wp-admin-scripts', 'woo-connect-notice' );
|
||||
wp_enqueue_script( 'woo-connect-notice' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue scripts for connect notice in plugin list page.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public static function maybe_enqueue_scripts_for_connect_notice_in_plugins() {
|
||||
if ( 'plugins' !== get_current_screen()->id ) {
|
||||
return;
|
||||
}
|
||||
|
||||
WCAdminAssets::register_script( 'wp-admin-scripts', 'woo-plugin-update-connect-notice' );
|
||||
wp_enqueue_script( 'woo-plugin-update-connect-notice' );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,65 +6,28 @@
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications;
|
||||
|
||||
use Automattic\WooCommerce\Internal\Admin\Onboarding\OnboardingProfile;
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Rule processor that performs a comparison operation against the base
|
||||
* location - country.
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class BaseLocationCountryRuleProcessor implements RuleProcessorInterface {
|
||||
class BaseLocationCountryRuleProcessor extends DeprecatedClassFacade {
|
||||
/**
|
||||
* Performs a comparison operation against the base location - country.
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @param object $rule The specific rule being processed by this rule processor.
|
||||
* @param object $stored_state Stored state.
|
||||
*
|
||||
* @return bool The result of the operation.
|
||||
* @var string
|
||||
*/
|
||||
public function process( $rule, $stored_state ) {
|
||||
$base_location = wc_get_base_location();
|
||||
if (
|
||||
! is_array( $base_location ) ||
|
||||
! array_key_exists( 'country', $base_location ) ||
|
||||
! array_key_exists( 'state', $base_location )
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$onboarding_profile = get_option( 'woocommerce_onboarding_profile', array() );
|
||||
$is_address_default = 'US' === $base_location['country'] && 'CA' === $base_location['state'] && empty( get_option( 'woocommerce_store_address', '' ) );
|
||||
$is_store_country_set = isset( $onboarding_profile['is_store_country_set'] ) && $onboarding_profile['is_store_country_set'];
|
||||
|
||||
// Return false if the location is the default country and if onboarding hasn't been finished or the store address not been updated.
|
||||
if ( $is_address_default && OnboardingProfile::needs_completion() && ! $is_store_country_set ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ComparisonOperation::compare(
|
||||
$base_location['country'],
|
||||
$rule->value,
|
||||
$rule->operation
|
||||
);
|
||||
}
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\BaseLocationCountryRuleProcessor';
|
||||
|
||||
/**
|
||||
* Validates the rule.
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @param object $rule The rule to validate.
|
||||
*
|
||||
* @return bool Pass/fail.
|
||||
* @var string
|
||||
*/
|
||||
public function validate( $rule ) {
|
||||
if ( ! isset( $rule->value ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! isset( $rule->operation ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -6,50 +6,28 @@
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications;
|
||||
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Rule processor that performs a comparison operation against the base
|
||||
* location - state.
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class BaseLocationStateRuleProcessor implements RuleProcessorInterface {
|
||||
class BaseLocationStateRuleProcessor extends DeprecatedClassFacade {
|
||||
/**
|
||||
* Performs a comparison operation against the base location - state.
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @param object $rule The specific rule being processed by this rule processor.
|
||||
* @param object $stored_state Stored state.
|
||||
*
|
||||
* @return bool The result of the operation.
|
||||
* @var string
|
||||
*/
|
||||
public function process( $rule, $stored_state ) {
|
||||
$base_location = wc_get_base_location();
|
||||
if ( ! is_array( $base_location ) || ! array_key_exists( 'state', $base_location ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ComparisonOperation::compare(
|
||||
$base_location['state'],
|
||||
$rule->value,
|
||||
$rule->operation
|
||||
);
|
||||
}
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\BaseLocationStateRuleProcessor';
|
||||
|
||||
/**
|
||||
* Validates the rule.
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @param object $rule The rule to validate.
|
||||
*
|
||||
* @return bool Pass/fail.
|
||||
* @var string
|
||||
*/
|
||||
public function validate( $rule ) {
|
||||
if ( ! isset( $rule->value ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! isset( $rule->operation ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -7,65 +7,25 @@ namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
/**
|
||||
* Compare two operands using the specified operation.
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class ComparisonOperation {
|
||||
class ComparisonOperation extends DeprecatedClassFacade {
|
||||
/**
|
||||
* Compare two operands using the specified operation.
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @param object $left_operand The left hand operand.
|
||||
* @param object $right_operand The right hand operand.
|
||||
* @param string $operation The operation used to compare the operands.
|
||||
* @var string
|
||||
*/
|
||||
public static function compare( $left_operand, $right_operand, $operation ) {
|
||||
switch ( $operation ) {
|
||||
case '=':
|
||||
return $left_operand === $right_operand;
|
||||
case '<':
|
||||
return $left_operand < $right_operand;
|
||||
case '<=':
|
||||
return $left_operand <= $right_operand;
|
||||
case '>':
|
||||
return $left_operand > $right_operand;
|
||||
case '>=':
|
||||
return $left_operand >= $right_operand;
|
||||
case '!=':
|
||||
return $left_operand !== $right_operand;
|
||||
case 'contains':
|
||||
if ( is_array( $left_operand ) && is_string( $right_operand ) ) {
|
||||
return in_array( $right_operand, $left_operand, true );
|
||||
}
|
||||
if ( is_string( $right_operand ) && is_string( $left_operand ) ) {
|
||||
return strpos( $right_operand, $left_operand ) !== false;
|
||||
}
|
||||
break;
|
||||
case '!contains':
|
||||
if ( is_array( $left_operand ) && is_string( $right_operand ) ) {
|
||||
return ! in_array( $right_operand, $left_operand, true );
|
||||
}
|
||||
if ( is_string( $right_operand ) && is_string( $left_operand ) ) {
|
||||
return strpos( $right_operand, $left_operand ) === false;
|
||||
}
|
||||
break;
|
||||
case 'in':
|
||||
if ( is_array( $right_operand ) && is_string( $left_operand ) ) {
|
||||
return in_array( $left_operand, $right_operand, true );
|
||||
}
|
||||
if ( is_string( $left_operand ) && is_string( $right_operand ) ) {
|
||||
return strpos( $left_operand, $right_operand ) !== false;
|
||||
}
|
||||
break;
|
||||
case '!in':
|
||||
if ( is_array( $right_operand ) && is_string( $left_operand ) ) {
|
||||
return ! in_array( $left_operand, $right_operand, true );
|
||||
}
|
||||
if ( is_string( $left_operand ) && is_string( $right_operand ) ) {
|
||||
return strpos( $left_operand, $right_operand ) === false;
|
||||
}
|
||||
break;
|
||||
}
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\ComparisonOperation';
|
||||
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -7,53 +7,25 @@ namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use Automattic\WooCommerce\Admin\Notes\Note;
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
/**
|
||||
* Evaluates the spec and returns a status.
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class EvaluateAndGetStatus {
|
||||
class EvaluateAndGetStatus extends DeprecatedClassFacade {
|
||||
/**
|
||||
* Evaluates the spec and returns a status.
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @param array $spec The spec to evaluate.
|
||||
* @param string $current_status The note's current status.
|
||||
* @param object $stored_state Stored state.
|
||||
* @param object $rule_evaluator Evaluates rules into true/false.
|
||||
*
|
||||
* @return string The evaluated status.
|
||||
* @var string
|
||||
*/
|
||||
public static function evaluate( $spec, $current_status, $stored_state, $rule_evaluator ) {
|
||||
// No rules should leave the note alone.
|
||||
if ( ! isset( $spec->rules ) ) {
|
||||
return $current_status;
|
||||
}
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\EvaluateAndGetStatus';
|
||||
|
||||
$evaluated_result = $rule_evaluator->evaluate(
|
||||
$spec->rules,
|
||||
$stored_state,
|
||||
array(
|
||||
'slug' => $spec->slug,
|
||||
'source' => 'remote-inbox-notifications',
|
||||
)
|
||||
);
|
||||
|
||||
// Pending notes should be the spec status if the spec passes,
|
||||
// left alone otherwise.
|
||||
if ( Note::E_WC_ADMIN_NOTE_PENDING === $current_status ) {
|
||||
return $evaluated_result
|
||||
? $spec->status
|
||||
: Note::E_WC_ADMIN_NOTE_PENDING;
|
||||
}
|
||||
|
||||
// When allow_redisplay isn't set, just leave the note alone.
|
||||
if ( ! isset( $spec->allow_redisplay ) || ! $spec->allow_redisplay ) {
|
||||
return $current_status;
|
||||
}
|
||||
|
||||
// allow_redisplay is set, unaction the note if eval to true.
|
||||
return $evaluated_result
|
||||
? Note::E_WC_ADMIN_NOTE_UNACTIONED
|
||||
: $current_status;
|
||||
}
|
||||
/**
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -2,89 +2,26 @@
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications;
|
||||
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
/**
|
||||
* Class EvaluationLogger
|
||||
*
|
||||
* @package Automattic\WooCommerce\Admin\RemoteInboxNotifications
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class EvaluationLogger {
|
||||
class EvaluationLogger extends DeprecatedClassFacade {
|
||||
/**
|
||||
* Slug of the spec.
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $slug;
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\EvaluationLogger';
|
||||
|
||||
/**
|
||||
* Results of rules in the given spec.
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @var array
|
||||
* @var string
|
||||
*/
|
||||
private $results = array();
|
||||
|
||||
/**
|
||||
* Logger class to use.
|
||||
*
|
||||
* @var WC_Logger_Interface|null
|
||||
*/
|
||||
private $logger;
|
||||
|
||||
/**
|
||||
* Logger source.
|
||||
*
|
||||
* @var string logger source.
|
||||
*/
|
||||
private $source = '';
|
||||
|
||||
/**
|
||||
* EvaluationLogger constructor.
|
||||
*
|
||||
* @param string $slug Slug of a spec that is being evaluated.
|
||||
* @param null $source Logger source.
|
||||
* @param \WC_Logger_Interface $logger Logger class to use.
|
||||
*/
|
||||
public function __construct( $slug, $source = null, \WC_Logger_Interface $logger = null ) {
|
||||
$this->slug = $slug;
|
||||
if ( null === $logger ) {
|
||||
$logger = wc_get_logger();
|
||||
}
|
||||
|
||||
if ( $source ) {
|
||||
$this->source = $source;
|
||||
}
|
||||
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add evaluation result of a rule.
|
||||
*
|
||||
* @param string $rule_type name of the rule being tested.
|
||||
* @param boolean $result result of a given rule.
|
||||
*/
|
||||
public function add_result( $rule_type, $result ) {
|
||||
array_push(
|
||||
$this->results,
|
||||
array(
|
||||
'rule' => $rule_type,
|
||||
'result' => $result ? 'passed' : 'failed',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log the results.
|
||||
*/
|
||||
public function log() {
|
||||
if ( false === defined( 'WC_ADMIN_DEBUG_RULE_EVALUATOR' ) || true !== constant( 'WC_ADMIN_DEBUG_RULE_EVALUATOR' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( $this->results as $result ) {
|
||||
$this->logger->debug(
|
||||
"[{$this->slug}] {$result['rule']}: {$result['result']}",
|
||||
array( 'source' => $this->source )
|
||||
);
|
||||
}
|
||||
}
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -7,30 +7,25 @@ namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
/**
|
||||
* Rule processor that fails.
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class FailRuleProcessor implements RuleProcessorInterface {
|
||||
class FailRuleProcessor extends DeprecatedClassFacade {
|
||||
/**
|
||||
* Fails the rule.
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @param object $rule The specific rule being processed by this rule processor.
|
||||
* @param object $stored_state Stored state.
|
||||
*
|
||||
* @return bool Always false.
|
||||
* @var string
|
||||
*/
|
||||
public function process( $rule, $stored_state ) {
|
||||
return false;
|
||||
}
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\FailRuleProcessor';
|
||||
|
||||
/**
|
||||
* Validates the rule.
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @param object $rule The rule to validate.
|
||||
*
|
||||
* @return bool Pass/fail.
|
||||
* @var string
|
||||
*/
|
||||
public function validate( $rule ) {
|
||||
return true;
|
||||
}
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -7,63 +7,25 @@ namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
/**
|
||||
* Class encapsulating getting the processor for a given rule type.
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class GetRuleProcessor {
|
||||
class GetRuleProcessor extends DeprecatedClassFacade {
|
||||
/**
|
||||
* Get the processor for the specified rule type.
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @param string $rule_type The rule type.
|
||||
*
|
||||
* @return RuleProcessorInterface The matching processor for the specified rule type, or a FailRuleProcessor if no matching processor is found.
|
||||
* @var string
|
||||
*/
|
||||
public static function get_processor( $rule_type ) {
|
||||
switch ( $rule_type ) {
|
||||
case 'plugins_activated':
|
||||
return new PluginsActivatedRuleProcessor();
|
||||
case 'publish_after_time':
|
||||
return new PublishAfterTimeRuleProcessor();
|
||||
case 'publish_before_time':
|
||||
return new PublishBeforeTimeRuleProcessor();
|
||||
case 'not':
|
||||
return new NotRuleProcessor();
|
||||
case 'or':
|
||||
return new OrRuleProcessor();
|
||||
case 'fail':
|
||||
return new FailRuleProcessor();
|
||||
case 'pass':
|
||||
return new PassRuleProcessor();
|
||||
case 'plugin_version':
|
||||
return new PluginVersionRuleProcessor();
|
||||
case 'stored_state':
|
||||
return new StoredStateRuleProcessor();
|
||||
case 'order_count':
|
||||
return new OrderCountRuleProcessor();
|
||||
case 'wcadmin_active_for':
|
||||
return new WCAdminActiveForRuleProcessor();
|
||||
case 'product_count':
|
||||
return new ProductCountRuleProcessor();
|
||||
case 'onboarding_profile':
|
||||
return new OnboardingProfileRuleProcessor();
|
||||
case 'is_ecommerce':
|
||||
return new IsEcommerceRuleProcessor();
|
||||
case 'is_woo_express':
|
||||
return new IsWooExpressRuleProcessor();
|
||||
case 'base_location_country':
|
||||
return new BaseLocationCountryRuleProcessor();
|
||||
case 'base_location_state':
|
||||
return new BaseLocationStateRuleProcessor();
|
||||
case 'note_status':
|
||||
return new NoteStatusRuleProcessor();
|
||||
case 'option':
|
||||
return new OptionRuleProcessor();
|
||||
case 'wca_updated':
|
||||
return new WooCommerceAdminUpdatedRuleProcessor();
|
||||
case 'total_payments_value':
|
||||
return new TotalPaymentsVolumeProcessor();
|
||||
}
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\GetRuleProcessor';
|
||||
|
||||
return new FailRuleProcessor();
|
||||
}
|
||||
/**
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -10,40 +10,26 @@ namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
/**
|
||||
* Rule processor that passes (or fails) when the site is on the eCommerce
|
||||
* plan.
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class IsEcommerceRuleProcessor implements RuleProcessorInterface {
|
||||
class IsEcommerceRuleProcessor extends DeprecatedClassFacade {
|
||||
/**
|
||||
* Passes (or fails) based on whether the site is on the eCommerce plan or
|
||||
* not.
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @param object $rule The rule being processed by this rule processor.
|
||||
* @param object $stored_state Stored state.
|
||||
*
|
||||
* @return bool The result of the operation.
|
||||
* @var string
|
||||
*/
|
||||
public function process( $rule, $stored_state ) {
|
||||
if ( ! function_exists( 'wc_calypso_bridge_is_ecommerce_plan' ) ) {
|
||||
return false === $rule->value;
|
||||
}
|
||||
|
||||
return (bool) wc_calypso_bridge_is_ecommerce_plan() === $rule->value;
|
||||
}
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\IsEcommerceRuleProcessor';
|
||||
|
||||
/**
|
||||
* Validate the rule.
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @param object $rule The rule to validate.
|
||||
*
|
||||
* @return bool Pass/fail.
|
||||
* @var string
|
||||
*/
|
||||
public function validate( $rule ) {
|
||||
if ( ! isset( $rule->value ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -9,61 +9,26 @@ namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
/**
|
||||
* Rule processor that passes (or fails) when the site is on a Woo Express plan.
|
||||
* You may optionally pass a plan name to target a specific Woo Express plan.
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class IsWooExpressRuleProcessor implements RuleProcessorInterface {
|
||||
class IsWooExpressRuleProcessor extends DeprecatedClassFacade {
|
||||
/**
|
||||
* Passes (or fails) based on whether the site is a Woo Express plan.
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @param object $rule The rule being processed by this rule processor.
|
||||
* @param object $stored_state Stored state.
|
||||
*
|
||||
* @return bool The result of the operation.
|
||||
* @var string
|
||||
*/
|
||||
public function process( $rule, $stored_state ) {
|
||||
if ( ! function_exists( 'wc_calypso_bridge_is_woo_express_plan' ) ) {
|
||||
return false === $rule->value;
|
||||
}
|
||||
|
||||
// If the plan is undefined, only check if it's a Woo Express plan.
|
||||
if ( ! isset( $rule->plan ) ) {
|
||||
return wc_calypso_bridge_is_woo_express_plan() === $rule->value;
|
||||
}
|
||||
|
||||
// If a plan name is defined, only evaluate the plan if we're on the Woo Express plan.
|
||||
if ( wc_calypso_bridge_is_woo_express_plan() ) {
|
||||
$fn = 'wc_calypso_bridge_is_woo_express_' . (string) $rule->plan . '_plan';
|
||||
if ( function_exists( $fn ) ) {
|
||||
return $fn() === $rule->value;
|
||||
}
|
||||
|
||||
// If an invalid plan name is given, only evaluate the rule if we're targeting all plans other than the specified (invalid) one.
|
||||
return false === $rule->value;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\IsWooExpressRuleProcessor';
|
||||
|
||||
/**
|
||||
* Validate the rule.
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @param object $rule The rule to validate.
|
||||
*
|
||||
* @return bool Pass/fail.
|
||||
* @var string
|
||||
*/
|
||||
public function validate( $rule ) {
|
||||
if ( ! isset( $rule->value ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( isset( $rule->plan ) ) {
|
||||
if ( ! function_exists( 'wc_calypso_bridge_is_woo_express_plan' ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -7,58 +7,25 @@ namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
/**
|
||||
* Rule processor that negates the rules in the rule's operand.
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class NotRuleProcessor implements RuleProcessorInterface {
|
||||
class NotRuleProcessor extends DeprecatedClassFacade {
|
||||
/**
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\NotRuleProcessor';
|
||||
|
||||
/**
|
||||
* The rule evaluator to use.
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @var RuleEvaluator
|
||||
* @var string
|
||||
*/
|
||||
protected $rule_evaluator;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param RuleEvaluator $rule_evaluator The rule evaluator to use.
|
||||
*/
|
||||
public function __construct( $rule_evaluator = null ) {
|
||||
$this->rule_evaluator = null === $rule_evaluator
|
||||
? new RuleEvaluator()
|
||||
: $rule_evaluator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluates the rules in the operand and negates the result.
|
||||
*
|
||||
* @param object $rule The specific rule being processed by this rule processor.
|
||||
* @param object $stored_state Stored state.
|
||||
*
|
||||
* @return bool The result of the operation.
|
||||
*/
|
||||
public function process( $rule, $stored_state ) {
|
||||
$evaluated_operand = $this->rule_evaluator->evaluate(
|
||||
$rule->operand,
|
||||
$stored_state
|
||||
);
|
||||
|
||||
return ! $evaluated_operand;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the rule.
|
||||
*
|
||||
* @param object $rule The rule to validate.
|
||||
*
|
||||
* @return bool Pass/fail.
|
||||
*/
|
||||
public function validate( $rule ) {
|
||||
if ( ! isset( $rule->operand ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -9,53 +9,25 @@ namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use Automattic\WooCommerce\Admin\Notes\Notes;
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
/**
|
||||
* Rule processor that compares against the status of another note.
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class NoteStatusRuleProcessor implements RuleProcessorInterface {
|
||||
class NoteStatusRuleProcessor extends DeprecatedClassFacade {
|
||||
/**
|
||||
* Compare against the status of another note.
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @param object $rule The rule being processed by this rule processor.
|
||||
* @param object $stored_state Stored state.
|
||||
*
|
||||
* @return bool The result of the operation.
|
||||
* @var string
|
||||
*/
|
||||
public function process( $rule, $stored_state ) {
|
||||
$status = Notes::get_note_status( $rule->note_name );
|
||||
if ( ! $status ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ComparisonOperation::compare(
|
||||
$status,
|
||||
$rule->status,
|
||||
$rule->operation
|
||||
);
|
||||
}
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\NoteStatusRuleProcessor';
|
||||
|
||||
/**
|
||||
* Validates the rule.
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @param object $rule The rule to validate.
|
||||
*
|
||||
* @return bool Pass/fail.
|
||||
* @var string
|
||||
*/
|
||||
public function validate( $rule ) {
|
||||
if ( ! isset( $rule->note_name ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! isset( $rule->status ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! isset( $rule->operation ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -8,58 +8,26 @@ namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
/**
|
||||
* Rule processor that performs a comparison operation against a value in the
|
||||
* onboarding profile.
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class OnboardingProfileRuleProcessor implements RuleProcessorInterface {
|
||||
class OnboardingProfileRuleProcessor extends DeprecatedClassFacade {
|
||||
/**
|
||||
* Performs a comparison operation against a value in the onboarding
|
||||
* profile.
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @param object $rule The rule being processed by this rule processor.
|
||||
* @param object $stored_state Stored state.
|
||||
*
|
||||
* @return bool The result of the operation.
|
||||
* @var string
|
||||
*/
|
||||
public function process( $rule, $stored_state ) {
|
||||
$onboarding_profile = get_option( 'woocommerce_onboarding_profile' );
|
||||
|
||||
if ( empty( $onboarding_profile ) || ! is_array( $onboarding_profile ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! isset( $onboarding_profile[ $rule->index ] ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ComparisonOperation::compare(
|
||||
$onboarding_profile[ $rule->index ],
|
||||
$rule->value,
|
||||
$rule->operation
|
||||
);
|
||||
}
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\OnboardingProfileRuleProcessor';
|
||||
|
||||
/**
|
||||
* Validates the rule.
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @param object $rule The rule to validate.
|
||||
*
|
||||
* @return bool Pass/fail.
|
||||
* @var string
|
||||
*/
|
||||
public function validate( $rule ) {
|
||||
if ( ! isset( $rule->index ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! isset( $rule->value ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! isset( $rule->operation ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -7,97 +7,25 @@ namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
/**
|
||||
* Rule processor that performs a comparison operation against an option value.
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class OptionRuleProcessor implements RuleProcessorInterface {
|
||||
class OptionRuleProcessor extends DeprecatedClassFacade {
|
||||
/**
|
||||
* Performs a comparison operation against the option value.
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @param object $rule The specific rule being processed by this rule processor.
|
||||
* @param object $stored_state Stored state.
|
||||
*
|
||||
* @return bool The result of the operation.
|
||||
* @var string
|
||||
*/
|
||||
public function process( $rule, $stored_state ) {
|
||||
$is_contains = $rule->operation && strpos( $rule->operation, 'contains' ) !== false;
|
||||
$default_value = $is_contains ? array() : false;
|
||||
$is_default_set = property_exists( $rule, 'default' );
|
||||
$default = $is_default_set ? $rule->default : $default_value;
|
||||
$option_value = $this->get_option_value( $rule, $default, $is_contains );
|
||||
|
||||
if ( isset( $rule->transformers ) && is_array( $rule->transformers ) ) {
|
||||
$option_value = TransformerService::apply( $option_value, $rule->transformers, $is_default_set, $default );
|
||||
}
|
||||
|
||||
return ComparisonOperation::compare(
|
||||
$option_value,
|
||||
$rule->value,
|
||||
$rule->operation
|
||||
);
|
||||
}
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\OptionRuleProcessor';
|
||||
|
||||
/**
|
||||
* Retrieves the option value and handles logging if necessary.
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @param object $rule The specific rule being processed.
|
||||
* @param mixed $default The default value.
|
||||
* @param bool $is_contains Indicates whether the operation is "contains".
|
||||
*
|
||||
* @return mixed The option value.
|
||||
* @var string
|
||||
*/
|
||||
private function get_option_value( $rule, $default, $is_contains ) {
|
||||
$option_value = get_option( $rule->option_name, $default );
|
||||
$is_contains_valid = $is_contains && ( is_array( $option_value ) || ( is_string( $option_value ) && is_string( $rule->value ) ) );
|
||||
|
||||
if ( $is_contains && ! $is_contains_valid ) {
|
||||
$logger = wc_get_logger();
|
||||
$logger->warning(
|
||||
sprintf(
|
||||
'ComparisonOperation "%s" option value "%s" is not an array, defaulting to empty array.',
|
||||
$rule->operation,
|
||||
$rule->option_name
|
||||
),
|
||||
array(
|
||||
'option_value' => $option_value,
|
||||
'rule' => $rule,
|
||||
)
|
||||
);
|
||||
$option_value = array();
|
||||
}
|
||||
|
||||
return $option_value;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the rule.
|
||||
*
|
||||
* @param object $rule The rule to validate.
|
||||
*
|
||||
* @return bool Pass/fail.
|
||||
*/
|
||||
public function validate( $rule ) {
|
||||
if ( ! isset( $rule->option_name ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! isset( $rule->value ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! isset( $rule->operation ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( isset( $rule->transformers ) && is_array( $rule->transformers ) ) {
|
||||
foreach ( $rule->transformers as $transform_args ) {
|
||||
$transformer = TransformerService::create_transformer( $transform_args->use );
|
||||
if ( ! $transformer->validate( $transform_args->arguments ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -8,66 +8,26 @@ namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
/**
|
||||
* Rule processor that performs an OR operation on the rule's left and right
|
||||
* operands.
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class OrRuleProcessor implements RuleProcessorInterface {
|
||||
class OrRuleProcessor extends DeprecatedClassFacade {
|
||||
/**
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\OrRuleProcessor';
|
||||
|
||||
/**
|
||||
* Rule evaluator to use.
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @var RuleEvaluator
|
||||
* @var string
|
||||
*/
|
||||
private $rule_evaluator;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param RuleEvaluator $rule_evaluator The rule evaluator to use.
|
||||
*/
|
||||
public function __construct( $rule_evaluator = null ) {
|
||||
$this->rule_evaluator = null === $rule_evaluator
|
||||
? new RuleEvaluator()
|
||||
: $rule_evaluator;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs an OR operation on the rule's left and right operands.
|
||||
*
|
||||
* @param object $rule The specific rule being processed by this rule processor.
|
||||
* @param object $stored_state Stored state.
|
||||
*
|
||||
* @return bool The result of the operation.
|
||||
*/
|
||||
public function process( $rule, $stored_state ) {
|
||||
foreach ( $rule->operands as $operand ) {
|
||||
$evaluated_operand = $this->rule_evaluator->evaluate(
|
||||
$operand,
|
||||
$stored_state
|
||||
);
|
||||
|
||||
if ( $evaluated_operand ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the rule.
|
||||
*
|
||||
* @param object $rule The rule to validate.
|
||||
*
|
||||
* @return bool Pass/fail.
|
||||
*/
|
||||
public function validate( $rule ) {
|
||||
if ( ! isset( $rule->operands ) || ! is_array( $rule->operands ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -7,63 +7,25 @@ namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
/**
|
||||
* Rule processor for publishing based on the number of orders.
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class OrderCountRuleProcessor implements RuleProcessorInterface {
|
||||
class OrderCountRuleProcessor extends DeprecatedClassFacade {
|
||||
/**
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\OrderCountRuleProcessor';
|
||||
|
||||
/**
|
||||
* The orders provider.
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @var OrdersProvider
|
||||
* @var string
|
||||
*/
|
||||
protected $orders_provider;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param object $orders_provider The orders provider.
|
||||
*/
|
||||
public function __construct( $orders_provider = null ) {
|
||||
$this->orders_provider = null === $orders_provider
|
||||
? new OrdersProvider()
|
||||
: $orders_provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the rule.
|
||||
*
|
||||
* @param object $rule The rule to process.
|
||||
* @param object $stored_state Stored state.
|
||||
*
|
||||
* @return bool Whether the rule passes or not.
|
||||
*/
|
||||
public function process( $rule, $stored_state ) {
|
||||
$count = $this->orders_provider->get_order_count();
|
||||
|
||||
return ComparisonOperation::compare(
|
||||
$count,
|
||||
$rule->value,
|
||||
$rule->operation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the rule.
|
||||
*
|
||||
* @param object $rule The rule to validate.
|
||||
*
|
||||
* @return bool Pass/fail.
|
||||
*/
|
||||
public function validate( $rule ) {
|
||||
if ( ! isset( $rule->value ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! isset( $rule->operation ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -7,30 +7,25 @@ namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
/**
|
||||
* Provider for order-related queries and operations.
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class OrdersProvider {
|
||||
class OrdersProvider extends DeprecatedClassFacade {
|
||||
/**
|
||||
* Allowed order statuses for calculating milestones.
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @var array
|
||||
* @var string
|
||||
*/
|
||||
protected $allowed_statuses = array(
|
||||
'pending',
|
||||
'processing',
|
||||
'completed',
|
||||
);
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\OrdersProvider';
|
||||
|
||||
/**
|
||||
* Returns the number of orders.
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @return integer The number of orders.
|
||||
* @var string
|
||||
*/
|
||||
public function get_order_count() {
|
||||
$status_counts = array_map( 'wc_orders_count', $this->allowed_statuses );
|
||||
$orders_count = array_sum( $status_counts );
|
||||
|
||||
return $orders_count;
|
||||
}
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -8,30 +8,25 @@ namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
/**
|
||||
* Rule processor that passes.
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class PassRuleProcessor implements RuleProcessorInterface {
|
||||
class PassRuleProcessor extends DeprecatedClassFacade {
|
||||
/**
|
||||
* Passes the rule.
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @param object $rule The specific rule being processed by this rule processor.
|
||||
* @param object $stored_state Stored state.
|
||||
*
|
||||
* @return bool Always true.
|
||||
* @var string
|
||||
*/
|
||||
public function process( $rule, $stored_state ) {
|
||||
return true;
|
||||
}
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\PassRuleProcessor';
|
||||
|
||||
/**
|
||||
* Validates the rule.
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @param object $rule The rule to validate.
|
||||
*
|
||||
* @return bool Pass/fail.
|
||||
* @var string
|
||||
*/
|
||||
public function validate( $rule ) {
|
||||
return true;
|
||||
}
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -8,79 +8,26 @@ namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use Automattic\WooCommerce\Admin\PluginsProvider\PluginsProvider;
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
/**
|
||||
* Rule processor for sending when the provided plugin is activated and
|
||||
* matches the specified version.
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class PluginVersionRuleProcessor implements RuleProcessorInterface {
|
||||
class PluginVersionRuleProcessor extends DeprecatedClassFacade {
|
||||
/**
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\PluginVersionRuleProcessor';
|
||||
|
||||
/**
|
||||
* Plugins provider instance.
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @var PluginsProviderInterface
|
||||
* @var string
|
||||
*/
|
||||
private $plugins_provider;
|
||||
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param PluginsProviderInterface $plugins_provider The plugins provider.
|
||||
*/
|
||||
public function __construct( $plugins_provider = null ) {
|
||||
$this->plugins_provider = null === $plugins_provider
|
||||
? new PluginsProvider()
|
||||
: $plugins_provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the rule.
|
||||
*
|
||||
* @param object $rule The specific rule being processed by this rule processor.
|
||||
* @param object $stored_state Stored state.
|
||||
*
|
||||
* @return bool Whether the rule passes or not.
|
||||
*/
|
||||
public function process( $rule, $stored_state ) {
|
||||
$active_plugin_slugs = $this->plugins_provider->get_active_plugin_slugs();
|
||||
|
||||
if ( ! in_array( $rule->plugin, $active_plugin_slugs, true ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$plugin_data = $this->plugins_provider->get_plugin_data( $rule->plugin );
|
||||
|
||||
if ( ! is_array( $plugin_data ) || ! array_key_exists( 'Version', $plugin_data ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$plugin_version = $plugin_data['Version'];
|
||||
|
||||
return version_compare( $plugin_version, $rule->version, $rule->operator );
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the rule.
|
||||
*
|
||||
* @param object $rule The rule to validate.
|
||||
*
|
||||
* @return bool Pass/fail.
|
||||
*/
|
||||
public function validate( $rule ) {
|
||||
if ( ! isset( $rule->plugin ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! isset( $rule->version ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! isset( $rule->operator ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -7,75 +7,25 @@ namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use Automattic\WooCommerce\Admin\PluginsProvider\PluginsProvider;
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
/**
|
||||
* Rule processor for sending when the provided plugins are activated.
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class PluginsActivatedRuleProcessor implements RuleProcessorInterface {
|
||||
class PluginsActivatedRuleProcessor extends DeprecatedClassFacade {
|
||||
/**
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\PluginsActivatedRuleProcessor';
|
||||
|
||||
/**
|
||||
* The plugins provider.
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @var PluginsProviderInterface
|
||||
* @var string
|
||||
*/
|
||||
protected $plugins_provider;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param PluginsProviderInterface $plugins_provider The plugins provider.
|
||||
*/
|
||||
public function __construct( $plugins_provider = null ) {
|
||||
$this->plugins_provider = null === $plugins_provider
|
||||
? new PluginsProvider()
|
||||
: $plugins_provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the rule.
|
||||
*
|
||||
* @param object $rule The specific rule being processed by this rule processor.
|
||||
* @param object $stored_state Stored state.
|
||||
*
|
||||
* @return bool Whether the rule passes or not.
|
||||
*/
|
||||
public function process( $rule, $stored_state ) {
|
||||
if ( ! is_countable( $rule->plugins ) || 0 === count( $rule->plugins ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$active_plugin_slugs = $this->plugins_provider->get_active_plugin_slugs();
|
||||
|
||||
foreach ( $rule->plugins as $plugin_slug ) {
|
||||
if ( ! is_string( $plugin_slug ) ) {
|
||||
$logger = wc_get_logger();
|
||||
$logger->warning(
|
||||
__( 'Invalid plugin slug provided in the plugins activated rule.', 'woocommerce' )
|
||||
);
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! in_array( $plugin_slug, $active_plugin_slugs, true ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the rule.
|
||||
*
|
||||
* @param object $rule The rule to validate.
|
||||
*
|
||||
* @return bool Pass/fail.
|
||||
*/
|
||||
public function validate( $rule ) {
|
||||
if ( ! isset( $rule->plugins ) || ! is_array( $rule->plugins ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -8,71 +8,26 @@ namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
/**
|
||||
* Rule processor that performs a comparison operation against the number of
|
||||
* products.
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class ProductCountRuleProcessor implements RuleProcessorInterface {
|
||||
class ProductCountRuleProcessor extends DeprecatedClassFacade {
|
||||
/**
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\ProductCountRuleProcessor';
|
||||
|
||||
/**
|
||||
* The product query.
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @var WC_Product_Query
|
||||
* @var string
|
||||
*/
|
||||
protected $product_query;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param object $product_query The product query.
|
||||
*/
|
||||
public function __construct( $product_query = null ) {
|
||||
$this->product_query = null === $product_query
|
||||
? new \WC_Product_Query(
|
||||
array(
|
||||
'limit' => 1,
|
||||
'paginate' => true,
|
||||
'return' => 'ids',
|
||||
'status' => array( 'publish' ),
|
||||
)
|
||||
)
|
||||
: $product_query;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a comparison operation against the number of products.
|
||||
*
|
||||
* @param object $rule The specific rule being processed by this rule processor.
|
||||
* @param object $stored_state Stored state.
|
||||
*
|
||||
* @return bool The result of the operation.
|
||||
*/
|
||||
public function process( $rule, $stored_state ) {
|
||||
$products = $this->product_query->get_products();
|
||||
|
||||
return ComparisonOperation::compare(
|
||||
$products->total,
|
||||
$rule->value,
|
||||
$rule->operation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the rule.
|
||||
*
|
||||
* @param object $rule The rule to validate.
|
||||
*
|
||||
* @return bool Pass/fail.
|
||||
*/
|
||||
public function validate( $rule ) {
|
||||
if ( ! isset( $rule->value ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! isset( $rule->operation ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -7,61 +7,25 @@ namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use Automattic\WooCommerce\Admin\DateTimeProvider\CurrentDateTimeProvider;
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
/**
|
||||
* Rule processor for sending after a specified date/time.
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class PublishAfterTimeRuleProcessor implements RuleProcessorInterface {
|
||||
class PublishAfterTimeRuleProcessor extends DeprecatedClassFacade {
|
||||
/**
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\PublishAfterTimeRuleProcessor';
|
||||
|
||||
/**
|
||||
* The DateTime provider.
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @var DateTimeProviderInterface
|
||||
* @var string
|
||||
*/
|
||||
protected $date_time_provider;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param DateTimeProviderInterface $date_time_provider The DateTime provider.
|
||||
*/
|
||||
public function __construct( $date_time_provider = null ) {
|
||||
$this->date_time_provider = null === $date_time_provider
|
||||
? new CurrentDateTimeProvider()
|
||||
: $date_time_provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the rule.
|
||||
*
|
||||
* @param object $rule The specific rule being processed by this rule processor.
|
||||
* @param object $stored_state Stored state.
|
||||
*
|
||||
* @return bool Whether the rule passes or not.
|
||||
*/
|
||||
public function process( $rule, $stored_state ) {
|
||||
return $this->date_time_provider->get_now() >= new \DateTime( $rule->publish_after );
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the rule.
|
||||
*
|
||||
* @param object $rule The rule to validate.
|
||||
*
|
||||
* @return bool Pass/fail.
|
||||
*/
|
||||
public function validate( $rule ) {
|
||||
if ( ! isset( $rule->publish_after ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
new \DateTime( $rule->publish_after );
|
||||
} catch ( \Throwable $e ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -7,61 +7,25 @@ namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use Automattic\WooCommerce\Admin\DateTimeProvider\CurrentDateTimeProvider;
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
/**
|
||||
* Rule processor for sending before a specified date/time.
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class PublishBeforeTimeRuleProcessor implements RuleProcessorInterface {
|
||||
class PublishBeforeTimeRuleProcessor extends DeprecatedClassFacade {
|
||||
/**
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\PublishBeforeTimeRuleProcessor';
|
||||
|
||||
/**
|
||||
* The DateTime provider.
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @var DateTimeProviderInterface
|
||||
* @var string
|
||||
*/
|
||||
protected $date_time_provider;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param DateTimeProviderInterface $date_time_provider The DateTime provider.
|
||||
*/
|
||||
public function __construct( $date_time_provider = null ) {
|
||||
$this->date_time_provider = null === $date_time_provider
|
||||
? new CurrentDateTimeProvider()
|
||||
: $date_time_provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Process the rule.
|
||||
*
|
||||
* @param object $rule The specific rule being processed by this rule processor.
|
||||
* @param object $stored_state Stored state.
|
||||
*
|
||||
* @return bool Whether the rule passes or not.
|
||||
*/
|
||||
public function process( $rule, $stored_state ) {
|
||||
return $this->date_time_provider->get_now() <= new \DateTime( $rule->publish_before );
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the rule.
|
||||
*
|
||||
* @param object $rule The rule to validate.
|
||||
*
|
||||
* @return bool Pass/fail.
|
||||
*/
|
||||
public function validate( $rule ) {
|
||||
if ( ! isset( $rule->publish_before ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
try {
|
||||
new \DateTime( $rule->publish_before );
|
||||
} catch ( \Throwable $e ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -7,15 +7,18 @@ namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use Automattic\WooCommerce\Admin\RemoteSpecs\DataSourcePoller;
|
||||
use Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\GetRuleProcessor;
|
||||
|
||||
/**
|
||||
* Specs data source poller class.
|
||||
* This handles polling specs from JSON endpoints, and
|
||||
* stores the specs in to the database as an option.
|
||||
*/
|
||||
class DataSourcePoller extends \Automattic\WooCommerce\Admin\DataSourcePoller {
|
||||
class RemoteInboxNotificationsDataSourcePoller extends DataSourcePoller {
|
||||
const ID = 'remote_inbox_notifications';
|
||||
const DATA_SOURCES = array(
|
||||
'https://woocommerce.com/wp-json/wccom/inbox-notifications/1.0/notifications.json',
|
||||
'https://woocommerce.com/wp-json/wccom/inbox-notifications/2.0/notifications.json',
|
||||
);
|
||||
/**
|
||||
* Class instance.
|
||||
@@ -11,6 +11,7 @@ use Automattic\WooCommerce\Admin\PluginsProvider\PluginsProvider;
|
||||
use Automattic\WooCommerce\Internal\Admin\Onboarding\OnboardingProfile;
|
||||
use Automattic\WooCommerce\Admin\Notes\Note;
|
||||
use Automattic\WooCommerce\Admin\RemoteSpecs\RemoteSpecsEngine;
|
||||
use Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\StoredStateSetupForProducts;
|
||||
|
||||
/**
|
||||
* Remote Inbox Notifications engine.
|
||||
@@ -111,7 +112,7 @@ class RemoteInboxNotificationsEngine extends RemoteSpecsEngine {
|
||||
* Go through the specs and run them.
|
||||
*/
|
||||
public static function run() {
|
||||
$specs = DataSourcePoller::get_instance()->get_specs_from_data_sources();
|
||||
$specs = RemoteInboxNotificationsDataSourcePoller::get_instance()->get_specs_from_data_sources();
|
||||
|
||||
if ( false === $specs || ! is_countable( $specs ) || count( $specs ) === 0 ) {
|
||||
return;
|
||||
@@ -204,7 +205,7 @@ class RemoteInboxNotificationsEngine extends RemoteSpecsEngine {
|
||||
if ( ! $note_from_db instanceof Note || get_user_locale() === $note_from_db->get_locale() ) {
|
||||
return $note_from_db;
|
||||
}
|
||||
$specs = DataSourcePoller::get_instance()->get_specs_from_data_sources();
|
||||
$specs = RemoteInboxNotificationsDataSourcePoller::get_instance()->get_specs_from_data_sources();
|
||||
foreach ( $specs as $spec ) {
|
||||
if ( $spec->slug !== $note_from_db->get_name() ) {
|
||||
continue;
|
||||
|
||||
@@ -8,85 +8,26 @@ namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
/**
|
||||
* Evaluate the given rules as an AND operation - return false early if a
|
||||
* rule evaluates to false.
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class RuleEvaluator {
|
||||
class RuleEvaluator extends DeprecatedClassFacade {
|
||||
/**
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\RuleEvaluator';
|
||||
|
||||
/**
|
||||
* GetRuleProcessor to use.
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @var GetRuleProcessor
|
||||
* @var string
|
||||
*/
|
||||
private $get_rule_processor;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param GetRuleProcessor $get_rule_processor The GetRuleProcessor to use.
|
||||
*/
|
||||
public function __construct( $get_rule_processor = null ) {
|
||||
$this->get_rule_processor = null === $get_rule_processor
|
||||
? new GetRuleProcessor()
|
||||
: $get_rule_processor;
|
||||
}
|
||||
|
||||
/**
|
||||
* Evaluate the given rules as an AND operation - return false early if a
|
||||
* rule evaluates to false.
|
||||
*
|
||||
* @param array|object $rules The rule or rules being processed.
|
||||
* @param object|null $stored_state Stored state.
|
||||
* @param array $logger_args Arguments for the event logger. `slug` is required.
|
||||
*
|
||||
* @throws \InvalidArgumentException Thrown when $logger_args is missing slug.
|
||||
*
|
||||
* @return bool The result of the operation.
|
||||
*/
|
||||
public function evaluate( $rules, $stored_state = null, $logger_args = array() ) {
|
||||
|
||||
if ( is_bool( $rules ) ) {
|
||||
return $rules;
|
||||
}
|
||||
|
||||
if ( ! is_array( $rules ) ) {
|
||||
$rules = array( $rules );
|
||||
}
|
||||
|
||||
if ( 0 === count( $rules ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$evaluation_logger = null;
|
||||
|
||||
if ( count( $logger_args ) ) {
|
||||
if ( ! array_key_exists( 'slug', $logger_args ) ) {
|
||||
throw new \InvalidArgumentException( 'Missing required field: slug in $logger_args.' );
|
||||
}
|
||||
|
||||
array_key_exists( 'source', $logger_args ) ? $source = $logger_args['source'] : $source = null;
|
||||
|
||||
$evaluation_logger = new EvaluationLogger( $logger_args['slug'], $source );
|
||||
}
|
||||
|
||||
foreach ( $rules as $rule ) {
|
||||
if ( ! is_object( $rule ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$processor = $this->get_rule_processor->get_processor( $rule->type );
|
||||
$processor_result = $processor->process( $rule, $stored_state );
|
||||
$evaluation_logger && $evaluation_logger->add_result( $rule->type, $processor_result );
|
||||
|
||||
if ( ! $processor_result ) {
|
||||
$evaluation_logger && $evaluation_logger->log();
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
$evaluation_logger && $evaluation_logger->log();
|
||||
|
||||
return true;
|
||||
}
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -9,6 +9,8 @@ defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use Automattic\WooCommerce\Admin\Notes\Note;
|
||||
use Automattic\WooCommerce\Admin\Notes\Notes;
|
||||
use Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\EvaluateAndGetStatus;
|
||||
use Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\RuleEvaluator;
|
||||
|
||||
/**
|
||||
* Runs a single spec.
|
||||
|
||||
@@ -8,51 +8,26 @@ namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
/**
|
||||
* Rule processor that performs a comparison operation against a value in the
|
||||
* stored state object.
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class StoredStateRuleProcessor implements RuleProcessorInterface {
|
||||
class StoredStateRuleProcessor extends DeprecatedClassFacade {
|
||||
/**
|
||||
* Performs a comparison operation against a value in the stored state object.
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @param object $rule The rule being processed by this rule processor.
|
||||
* @param object $stored_state Stored state.
|
||||
*
|
||||
* @return bool The result of the operation.
|
||||
* @var string
|
||||
*/
|
||||
public function process( $rule, $stored_state ) {
|
||||
if ( ! isset( $stored_state->{$rule->index} ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ComparisonOperation::compare(
|
||||
$stored_state->{$rule->index},
|
||||
$rule->value,
|
||||
$rule->operation
|
||||
);
|
||||
}
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\StoredStateRuleProcessor';
|
||||
|
||||
/**
|
||||
* Validates the rule.
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @param object $rule The rule to validate.
|
||||
*
|
||||
* @return bool Pass/fail.
|
||||
* @var string
|
||||
*/
|
||||
public function validate( $rule ) {
|
||||
if ( ! isset( $rule->index ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! isset( $rule->value ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! isset( $rule->operation ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -7,125 +7,25 @@ namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use Automattic\WooCommerce\Admin\PluginsProvider\PluginsProvider;
|
||||
use Automattic\WooCommerce\Admin\RemoteInboxNotifications\SpecRunner;
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
/**
|
||||
* Handles stored state setup for products.
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class StoredStateSetupForProducts {
|
||||
const ASYNC_RUN_REMOTE_NOTIFICATIONS_ACTION_NAME =
|
||||
'woocommerce_admin/stored_state_setup_for_products/async/run_remote_notifications';
|
||||
|
||||
class StoredStateSetupForProducts extends DeprecatedClassFacade {
|
||||
/**
|
||||
* Initialize the class via the admin_init hook.
|
||||
*/
|
||||
public static function admin_init() {
|
||||
add_action( 'product_page_product_importer', array( __CLASS__, 'run_on_product_importer' ) );
|
||||
add_action( 'transition_post_status', array( __CLASS__, 'run_on_transition_post_status' ), 10, 3 );
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the class via the init hook.
|
||||
*/
|
||||
public static function init() {
|
||||
add_action( self::ASYNC_RUN_REMOTE_NOTIFICATIONS_ACTION_NAME, array( __CLASS__, 'run_remote_notifications' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Run the remote notifications engine. This is triggered by
|
||||
* action-scheduler after a product is added. It also cleans up from
|
||||
* setting the product count increment.
|
||||
*/
|
||||
public static function run_remote_notifications() {
|
||||
RemoteInboxNotificationsEngine::run();
|
||||
}
|
||||
|
||||
/**
|
||||
* Set initial stored state values.
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @param object $stored_state The stored state.
|
||||
* @var string
|
||||
*/
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\StoredStateSetupForProducts';
|
||||
|
||||
/**
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @return object The stored state.
|
||||
* @var string
|
||||
*/
|
||||
public static function init_stored_state( $stored_state ) {
|
||||
$stored_state->there_were_no_products = ! self::are_there_products();
|
||||
$stored_state->there_are_now_products = ! $stored_state->there_were_no_products;
|
||||
|
||||
return $stored_state;
|
||||
}
|
||||
|
||||
/**
|
||||
* Are there products query.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
private static function are_there_products() {
|
||||
$query = new \WC_Product_Query(
|
||||
array(
|
||||
'limit' => 1,
|
||||
'paginate' => true,
|
||||
'return' => 'ids',
|
||||
'status' => array( 'publish' ),
|
||||
)
|
||||
);
|
||||
$products = $query->get_products();
|
||||
$count = $products->total;
|
||||
|
||||
return $count > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs on product importer steps.
|
||||
*/
|
||||
public static function run_on_product_importer() {
|
||||
// We're only interested in when the importer completes.
|
||||
// phpcs:disable WordPress.Security.NonceVerification.Recommended
|
||||
if ( ! isset( $_REQUEST['step'] ) ) {
|
||||
return;
|
||||
}
|
||||
if ( 'done' !== $_REQUEST['step'] ) {
|
||||
return;
|
||||
}
|
||||
// phpcs:enable
|
||||
|
||||
self::update_stored_state_and_possibly_run_remote_notifications();
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs when a post status transitions, but we're only interested if it is
|
||||
* a product being published.
|
||||
*
|
||||
* @param string $new_status The new status.
|
||||
* @param string $old_status The old status.
|
||||
* @param Post $post The post.
|
||||
*/
|
||||
public static function run_on_transition_post_status( $new_status, $old_status, $post ) {
|
||||
if (
|
||||
'product' !== $post->post_type ||
|
||||
'publish' !== $new_status
|
||||
) {
|
||||
return;
|
||||
}
|
||||
|
||||
self::update_stored_state_and_possibly_run_remote_notifications();
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueues an async action (using action-scheduler) to run remote
|
||||
* notifications.
|
||||
*/
|
||||
private static function update_stored_state_and_possibly_run_remote_notifications() {
|
||||
$stored_state = RemoteInboxNotificationsEngine::get_stored_state();
|
||||
// If the stored_state is the same, we don't need to run remote notifications to avoid unnecessary action scheduling.
|
||||
if ( true === $stored_state->there_are_now_products ) {
|
||||
return;
|
||||
}
|
||||
|
||||
$stored_state->there_are_now_products = true;
|
||||
RemoteInboxNotificationsEngine::update_stored_state( $stored_state );
|
||||
|
||||
// Run self::run_remote_notifications asynchronously.
|
||||
as_enqueue_async_action( self::ASYNC_RUN_REMOTE_NOTIFICATIONS_ACTION_NAME );
|
||||
}
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -7,87 +7,25 @@ namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use Automattic\WooCommerce\Admin\API\Reports\Revenue\Query as RevenueQuery;
|
||||
use Automattic\WooCommerce\Admin\API\Reports\TimeInterval;
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
/**
|
||||
* Rule processor that passes when a store's payments volume exceeds a provided amount.
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class TotalPaymentsVolumeProcessor implements RuleProcessorInterface {
|
||||
class TotalPaymentsVolumeProcessor extends DeprecatedClassFacade {
|
||||
/**
|
||||
* Compare against the store's total payments volume.
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @param object $rule The rule being processed by this rule processor.
|
||||
* @param object $stored_state Stored state.
|
||||
*
|
||||
* @return bool The result of the operation.
|
||||
* @var string
|
||||
*/
|
||||
public function process( $rule, $stored_state ) {
|
||||
$dates = TimeInterval::get_timeframe_dates( $rule->timeframe );
|
||||
$reports_revenue = $this->get_reports_query(
|
||||
array(
|
||||
'before' => $dates['end'],
|
||||
'after' => $dates['start'],
|
||||
'interval' => 'year',
|
||||
'fields' => array( 'total_sales' ),
|
||||
)
|
||||
);
|
||||
$report_data = $reports_revenue->get_data();
|
||||
|
||||
if ( ! $report_data || ! isset( $report_data->totals->total_sales ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$value = $report_data->totals->total_sales;
|
||||
|
||||
return ComparisonOperation::compare(
|
||||
$value,
|
||||
$rule->value,
|
||||
$rule->operation
|
||||
);
|
||||
}
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\TotalPaymentsVolumeProcessor';
|
||||
|
||||
/**
|
||||
* Validates the rule.
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @param object $rule The rule to validate.
|
||||
*
|
||||
* @return bool Pass/fail.
|
||||
* @var string
|
||||
*/
|
||||
public function validate( $rule ) {
|
||||
$allowed_timeframes = array(
|
||||
'last_week',
|
||||
'last_month',
|
||||
'last_quarter',
|
||||
'last_6_months',
|
||||
'last_year',
|
||||
);
|
||||
|
||||
if ( ! isset( $rule->timeframe ) || ! in_array( $rule->timeframe, $allowed_timeframes, true ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! isset( $rule->value ) || ! is_numeric( $rule->value ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! isset( $rule->operation ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the report query.
|
||||
*
|
||||
* @param array $args The query args.
|
||||
*
|
||||
* @return RevenueQuery The report query.
|
||||
*/
|
||||
protected function get_reports_query( $args ) {
|
||||
return new RevenueQuery(
|
||||
$args
|
||||
);
|
||||
}
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -17,11 +17,11 @@ interface TransformerInterface {
|
||||
*
|
||||
* @param mixed $value a value to transform.
|
||||
* @param stdClass|null $arguments arguments.
|
||||
* @param string|null $default default value.
|
||||
* @param string|null $default_value default value.
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function transform( $value, stdClass $arguments = null, $default = null);
|
||||
public function transform( $value, stdClass $arguments = null, $default_value = null );
|
||||
|
||||
/**
|
||||
* Validate Transformer arguments.
|
||||
|
||||
@@ -2,8 +2,7 @@
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications;
|
||||
|
||||
use InvalidArgumentException;
|
||||
use stdClass;
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
/**
|
||||
* A simple service class for the Transformer classes.
|
||||
@@ -11,73 +10,21 @@ use stdClass;
|
||||
* Class TransformerService
|
||||
*
|
||||
* @package Automattic\WooCommerce\Admin\RemoteInboxNotifications
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class TransformerService {
|
||||
class TransformerService extends DeprecatedClassFacade {
|
||||
/**
|
||||
* Create a transformer object by name.
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @param string $name name of the transformer.
|
||||
*
|
||||
* @return TransformerInterface|null
|
||||
* @var string
|
||||
*/
|
||||
public static function create_transformer( $name ) {
|
||||
$camel_cased = str_replace( ' ', '', ucwords( str_replace( '_', ' ', $name ) ) );
|
||||
|
||||
$classname = __NAMESPACE__ . '\\Transformers\\' . $camel_cased;
|
||||
if ( ! class_exists( $classname ) ) {
|
||||
return null;
|
||||
}
|
||||
|
||||
return new $classname();
|
||||
}
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\Transformers\TransformerService';
|
||||
|
||||
/**
|
||||
* Apply transformers to the given value.
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @param mixed $target_value a value to transform.
|
||||
* @param array $transformer_configs transform configuration.
|
||||
* @param bool $is_default_set flag on is default value set.
|
||||
* @param string $default default value.
|
||||
*
|
||||
* @throws InvalidArgumentException Throws when one of the requried arguments is missing.
|
||||
* @return mixed|null
|
||||
* @var string
|
||||
*/
|
||||
public static function apply( $target_value, array $transformer_configs, $is_default_set, $default ) {
|
||||
foreach ( $transformer_configs as $transformer_config ) {
|
||||
if ( ! isset( $transformer_config->use ) ) {
|
||||
throw new InvalidArgumentException( 'Missing required config value: use' );
|
||||
}
|
||||
|
||||
if ( ! isset( $transformer_config->arguments ) ) {
|
||||
$transformer_config->arguments = null;
|
||||
}
|
||||
|
||||
$transformer = self::create_transformer( $transformer_config->use );
|
||||
if ( null === $transformer ) {
|
||||
throw new InvalidArgumentException( "Unable to find a transformer by name: {$transformer_config->use}" );
|
||||
}
|
||||
|
||||
$target_value = $transformer->transform( $target_value, $transformer_config->arguments, $is_default_set ? $default : null );
|
||||
|
||||
// Break early when there's no more value to traverse.
|
||||
if ( null === $target_value ) {
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if ( $is_default_set ) {
|
||||
// Nulls always return the default value.
|
||||
if ( null === $target_value ) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
// When type of the default value is different from the target value, return the default value
|
||||
// to ensure type safety.
|
||||
if ( gettype( $default ) !== gettype( $target_value ) ) {
|
||||
return $default;
|
||||
}
|
||||
}
|
||||
|
||||
return $target_value;
|
||||
}
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -2,55 +2,27 @@
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications\Transformers;
|
||||
|
||||
use Automattic\WooCommerce\Admin\RemoteInboxNotifications\TransformerInterface;
|
||||
use InvalidArgumentException;
|
||||
use stdClass;
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
/**
|
||||
* Search array value by one of its key.
|
||||
*
|
||||
* @package Automattic\WooCommerce\Admin\RemoteInboxNotifications\Transformers
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class ArrayColumn implements TransformerInterface {
|
||||
class ArrayColumn extends DeprecatedClassFacade {
|
||||
/**
|
||||
* Search array value by one of its key.
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @param mixed $value a value to transform.
|
||||
* @param stdClass|null $arguments required arguments 'key'.
|
||||
* @param string|null $default default value.
|
||||
*
|
||||
* @throws InvalidArgumentException Throws when the required argument 'key' is missing.
|
||||
*
|
||||
* @return mixed
|
||||
* @var string
|
||||
*/
|
||||
public function transform( $value, stdClass $arguments = null, $default = array() ) {
|
||||
if ( ! is_array( $value ) ) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return array_column( $value, $arguments->key );
|
||||
}
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\Transformers\ArrayColumn';
|
||||
|
||||
/**
|
||||
* Validate Transformer arguments.
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @param stdClass|null $arguments arguments to validate.
|
||||
*
|
||||
* @return mixed
|
||||
* @var string
|
||||
*/
|
||||
public function validate( stdClass $arguments = null ) {
|
||||
if ( ! isset( $arguments->key ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if (
|
||||
null !== $arguments->key &&
|
||||
! is_string( $arguments->key ) &&
|
||||
! is_int( $arguments->key )
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -2,48 +2,27 @@
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications\Transformers;
|
||||
|
||||
use Automattic\WooCommerce\Admin\RemoteInboxNotifications\TransformerInterface;
|
||||
use stdClass;
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
/**
|
||||
* Flatten nested array.
|
||||
*
|
||||
* @package Automattic\WooCommerce\Admin\RemoteInboxNotifications\Transformers
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class ArrayFlatten implements TransformerInterface {
|
||||
class ArrayFlatten extends DeprecatedClassFacade {
|
||||
/**
|
||||
* Search a given value in the array.
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @param mixed $value a value to transform.
|
||||
* @param stdClass|null $arguments arguments.
|
||||
* @param string|null $default default value.
|
||||
*
|
||||
* @return mixed|null
|
||||
* @var string
|
||||
*/
|
||||
public function transform( $value, stdClass $arguments = null, $default = array() ) {
|
||||
if ( ! is_array( $value ) ) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
$return = array();
|
||||
array_walk_recursive(
|
||||
$value,
|
||||
function( $item ) use ( &$return ) {
|
||||
$return[] = $item;
|
||||
}
|
||||
);
|
||||
|
||||
return $return;
|
||||
}
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\Transformers\ArrayColumn';
|
||||
|
||||
/**
|
||||
* Validate Transformer arguments.
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @param stdClass|null $arguments arguments to validate.
|
||||
*
|
||||
* @return mixed
|
||||
* @var string
|
||||
*/
|
||||
public function validate( stdClass $arguments = null ) {
|
||||
return true;
|
||||
}
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -2,40 +2,27 @@
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications\Transformers;
|
||||
|
||||
use Automattic\WooCommerce\Admin\RemoteInboxNotifications\TransformerInterface;
|
||||
use stdClass;
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
/**
|
||||
* Search array value by one of its key.
|
||||
*
|
||||
* @package Automattic\WooCommerce\Admin\RemoteInboxNotifications\Transformers
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class ArrayKeys implements TransformerInterface {
|
||||
class ArrayKeys extends DeprecatedClassFacade {
|
||||
/**
|
||||
* Search array value by one of its key.
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @param mixed $value a value to transform.
|
||||
* @param stdClass|null $arguments arguments.
|
||||
* @param string|null $default default value.
|
||||
*
|
||||
* @return mixed
|
||||
* @var string
|
||||
*/
|
||||
public function transform( $value, stdClass $arguments = null, $default = array() ) {
|
||||
if ( ! is_array( $value ) ) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return array_keys( $value );
|
||||
}
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\Transformers\ArrayColumn';
|
||||
|
||||
/**
|
||||
* Validate Transformer arguments.
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @param stdClass|null $arguments arguments to validate.
|
||||
*
|
||||
* @return mixed
|
||||
* @var string
|
||||
*/
|
||||
public function validate( stdClass $arguments = null ) {
|
||||
return true;
|
||||
}
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -2,52 +2,27 @@
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications\Transformers;
|
||||
|
||||
use Automattic\WooCommerce\Admin\RemoteInboxNotifications\TransformerInterface;
|
||||
use InvalidArgumentException;
|
||||
use stdClass;
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
/**
|
||||
* Searches a given a given value in the array.
|
||||
*
|
||||
* @package Automattic\WooCommerce\Admin\RemoteInboxNotifications\Transformers
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class ArraySearch implements TransformerInterface {
|
||||
class ArraySearch extends DeprecatedClassFacade {
|
||||
/**
|
||||
* Search a given value in the array.
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @param mixed $value a value to transform.
|
||||
* @param stdClass|null $arguments required argument 'value'.
|
||||
* @param string|null $default default value.
|
||||
*
|
||||
* @throws InvalidArgumentException Throws when the required 'value' is missing.
|
||||
*
|
||||
* @return mixed|null
|
||||
* @var string
|
||||
*/
|
||||
public function transform( $value, stdClass $arguments = null, $default = null ) {
|
||||
if ( ! is_array( $value ) ) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
$key = array_search( $arguments->value, $value, true );
|
||||
if ( false !== $key ) {
|
||||
return $value[ $key ];
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\Transformers\ArrayColumn';
|
||||
|
||||
/**
|
||||
* Validate Transformer arguments.
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @param stdClass|null $arguments arguments to validate.
|
||||
*
|
||||
* @return mixed
|
||||
* @var string
|
||||
*/
|
||||
public function validate( stdClass $arguments = null ) {
|
||||
if ( ! isset( $arguments->value ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -2,40 +2,27 @@
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications\Transformers;
|
||||
|
||||
use Automattic\WooCommerce\Admin\RemoteInboxNotifications\TransformerInterface;
|
||||
use stdClass;
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
/**
|
||||
* Search array value by one of its key.
|
||||
*
|
||||
* @package Automattic\WooCommerce\Admin\RemoteInboxNotifications\Transformers
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class ArrayValues implements TransformerInterface {
|
||||
class ArrayValues extends DeprecatedClassFacade {
|
||||
/**
|
||||
* Search array value by one of its key.
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @param mixed $value a value to transform.
|
||||
* @param stdClass|null $arguments arguments.
|
||||
* @param string|null $default default value.
|
||||
*
|
||||
* @return mixed
|
||||
* @var string
|
||||
*/
|
||||
public function transform( $value, stdClass $arguments = null, $default = array() ) {
|
||||
if ( ! is_array( $value ) ) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return array_values( $value );
|
||||
}
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\Transformers\ArrayColumn';
|
||||
|
||||
/**
|
||||
* Validate Transformer arguments.
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @param stdClass|null $arguments arguments to validate.
|
||||
*
|
||||
* @return mixed
|
||||
* @var string
|
||||
*/
|
||||
public function validate( stdClass $arguments = null ) {
|
||||
return true;
|
||||
}
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -2,40 +2,27 @@
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications\Transformers;
|
||||
|
||||
use Automattic\WooCommerce\Admin\RemoteInboxNotifications\TransformerInterface;
|
||||
use stdClass;
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
/**
|
||||
* Count elements in Array or Countable object.
|
||||
*
|
||||
* @package Automattic\WooCommerce\Admin\RemoteInboxNotifications\Transformers
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class Count implements TransformerInterface {
|
||||
class Count extends DeprecatedClassFacade {
|
||||
/**
|
||||
* Count elements in Array or Countable object.
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @param array|Countable $value an array to count.
|
||||
* @param stdClass|null $arguments arguments.
|
||||
* @param string|null $default default value.
|
||||
*
|
||||
* @return number
|
||||
* @var string
|
||||
*/
|
||||
public function transform( $value, stdClass $arguments = null, $default = null ) {
|
||||
if ( ! is_array( $value ) && ! $value instanceof \Countable ) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
return count( $value );
|
||||
}
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\Transformers\ArrayColumn';
|
||||
|
||||
/**
|
||||
* Validate Transformer arguments.
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @param stdClass|null $arguments arguments to validate.
|
||||
*
|
||||
* @return mixed
|
||||
* @var string
|
||||
*/
|
||||
public function validate( stdClass $arguments = null ) {
|
||||
return true;
|
||||
}
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -2,78 +2,27 @@
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications\Transformers;
|
||||
|
||||
use Automattic\WooCommerce\Admin\RemoteInboxNotifications\TransformerInterface;
|
||||
use InvalidArgumentException;
|
||||
use stdClass;
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
/**
|
||||
* Find an array value by dot notation.
|
||||
*
|
||||
* @package Automattic\WooCommerce\Admin\RemoteInboxNotifications\Transformers
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class DotNotation implements TransformerInterface {
|
||||
class DotNotation extends DeprecatedClassFacade {
|
||||
/**
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\Transformers\ArrayColumn';
|
||||
|
||||
/**
|
||||
* Find given path from the given value.
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @param mixed $value a value to transform.
|
||||
* @param stdClass|null $arguments required argument 'path'.
|
||||
* @param string|null $default default value.
|
||||
*
|
||||
* @throws InvalidArgumentException Throws when the required 'path' is missing.
|
||||
*
|
||||
* @return mixed
|
||||
* @var string
|
||||
*/
|
||||
public function transform( $value, stdclass $arguments = null, $default = null ) {
|
||||
if ( is_object( $value ) ) {
|
||||
// if the value is an object, convert it to an array.
|
||||
$value = json_decode( wp_json_encode( $value ), true );
|
||||
}
|
||||
|
||||
return $this->get( $value, $arguments->path, $default );
|
||||
}
|
||||
|
||||
/**
|
||||
* Find the given $path in $array by dot notation.
|
||||
*
|
||||
* @param array $array an array to search in.
|
||||
* @param string $path a path in the given array.
|
||||
* @param null $default default value to return if $path was not found.
|
||||
*
|
||||
* @return mixed|null
|
||||
*/
|
||||
public function get( $array, $path, $default = null ) {
|
||||
if ( ! is_array( $array ) ) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
if ( isset( $array[ $path ] ) ) {
|
||||
return $array[ $path ];
|
||||
}
|
||||
|
||||
foreach ( explode( '.', $path ) as $segment ) {
|
||||
if ( ! is_array( $array ) || ! array_key_exists( $segment, $array ) ) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
$array = $array[ $segment ];
|
||||
}
|
||||
|
||||
return $array;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate Transformer arguments.
|
||||
*
|
||||
* @param stdClass|null $arguments arguments to validate.
|
||||
*
|
||||
* @return mixed
|
||||
*/
|
||||
public function validate( stdClass $arguments = null ) {
|
||||
if ( ! isset( $arguments->path ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -2,54 +2,27 @@
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications\Transformers;
|
||||
|
||||
use Automattic\WooCommerce\Admin\RemoteInboxNotifications\TransformerInterface;
|
||||
use stdClass;
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
/**
|
||||
* Prepare site URL for comparison.
|
||||
*
|
||||
* @package Automattic\WooCommerce\Admin\RemoteInboxNotifications\Transformers
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class PrepareUrl implements TransformerInterface {
|
||||
class PrepareUrl extends DeprecatedClassFacade {
|
||||
/**
|
||||
* Prepares the site URL by removing the protocol and trailing slash.
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @param string $value a value to transform.
|
||||
* @param stdClass|null $arguments arguments.
|
||||
* @param string|null $default default value.
|
||||
*
|
||||
* @return mixed|null
|
||||
* @var string
|
||||
*/
|
||||
public function transform( $value, stdClass $arguments = null, $default = null ) {
|
||||
if ( ! is_string( $value ) ) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
$url_parts = wp_parse_url( rtrim( $value, '/' ) );
|
||||
|
||||
if ( ! $url_parts ) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
if ( ! isset( $url_parts['host'] ) ) {
|
||||
return $default;
|
||||
}
|
||||
|
||||
if ( isset( $url_parts['path'] ) ) {
|
||||
return $url_parts['host'] . $url_parts['path'];
|
||||
}
|
||||
|
||||
return $url_parts['host'];
|
||||
}
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\Transformers\ArrayColumn';
|
||||
|
||||
/**
|
||||
* Validate Transformer arguments.
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @param stdClass|null $arguments arguments to validate.
|
||||
*
|
||||
* @return mixed
|
||||
* @var string
|
||||
*/
|
||||
public function validate( stdClass $arguments = null ) {
|
||||
return true;
|
||||
}
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -5,20 +5,27 @@
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications;
|
||||
|
||||
use Automattic\WooCommerce\Admin\WCAdminHelper;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
/**
|
||||
* WCAdminActiveForProvider class
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class WCAdminActiveForProvider {
|
||||
class WCAdminActiveForProvider extends DeprecatedClassFacade {
|
||||
/**
|
||||
* Get the number of seconds that the store has been active.
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @return number Number of seconds.
|
||||
* @var string
|
||||
*/
|
||||
public function get_wcadmin_active_for_in_seconds() {
|
||||
return WCAdminHelper::get_wcadmin_active_for_in_seconds();
|
||||
}
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\WCAdminActiveForProvider';
|
||||
|
||||
/**
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -8,72 +8,26 @@ namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
/**
|
||||
* Rule processor for publishing if wc-admin has been active for at least the
|
||||
* given number of seconds.
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class WCAdminActiveForRuleProcessor implements RuleProcessorInterface {
|
||||
class WCAdminActiveForRuleProcessor extends DeprecatedClassFacade {
|
||||
/**
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\WCAdminActiveForRuleProcessor';
|
||||
|
||||
/**
|
||||
* Provides the amount of time wcadmin has been active for.
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @var WCAdminActiveForProvider
|
||||
* @var string
|
||||
*/
|
||||
protected $wcadmin_active_for_provider;
|
||||
|
||||
/**
|
||||
* Constructor
|
||||
*
|
||||
* @param object $wcadmin_active_for_provider Provides the amount of time wcadmin has been active for.
|
||||
*/
|
||||
public function __construct( $wcadmin_active_for_provider = null ) {
|
||||
$this->wcadmin_active_for_provider = null === $wcadmin_active_for_provider
|
||||
? new WCAdminActiveForProvider()
|
||||
: $wcadmin_active_for_provider;
|
||||
}
|
||||
|
||||
/**
|
||||
* Performs a comparison operation against the amount of time wc-admin has
|
||||
* been active for in days.
|
||||
*
|
||||
* @param object $rule The rule being processed.
|
||||
* @param object $stored_state Stored state.
|
||||
*
|
||||
* @return bool The result of the operation.
|
||||
*/
|
||||
public function process( $rule, $stored_state ) {
|
||||
$active_for_seconds = $this->wcadmin_active_for_provider->get_wcadmin_active_for_in_seconds();
|
||||
|
||||
if ( ! $active_for_seconds || ! is_numeric( $active_for_seconds ) || $active_for_seconds < 0 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$rule_seconds = $rule->days * DAY_IN_SECONDS;
|
||||
|
||||
return ComparisonOperation::compare(
|
||||
$active_for_seconds,
|
||||
$rule_seconds,
|
||||
$rule->operation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the rule.
|
||||
*
|
||||
* @param object $rule The rule to validate.
|
||||
*
|
||||
* @return bool Pass/fail.
|
||||
*/
|
||||
public function validate( $rule ) {
|
||||
// Ensure that 'days' property is set and is a valid numeric value.
|
||||
if ( ! isset( $rule->days ) || ! is_numeric( $rule->days ) || $rule->days < 0 ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! isset( $rule->operation ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -7,30 +7,25 @@ namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use Automattic\WooCommerce\Admin\DeprecatedClassFacade;
|
||||
|
||||
/**
|
||||
* Rule processor for sending when WooCommerce Admin has been updated.
|
||||
*
|
||||
* @deprecated 8.8.0
|
||||
*/
|
||||
class WooCommerceAdminUpdatedRuleProcessor implements RuleProcessorInterface {
|
||||
class WooCommerceAdminUpdatedRuleProcessor extends DeprecatedClassFacade {
|
||||
/**
|
||||
* Process the rule.
|
||||
* The name of the non-deprecated class that this facade covers.
|
||||
*
|
||||
* @param object $rule The specific rule being processed by this rule processor.
|
||||
* @param object $stored_state Stored state.
|
||||
*
|
||||
* @return bool Whether the rule passes or not.
|
||||
* @var string
|
||||
*/
|
||||
public function process( $rule, $stored_state ) {
|
||||
return get_option( RemoteInboxNotificationsEngine::WCA_UPDATED_OPTION_NAME, false );
|
||||
}
|
||||
protected static $facade_over_classname = 'Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors\WooCommerceAdminUpdatedRuleProcessor';
|
||||
|
||||
/**
|
||||
* Validates the rule.
|
||||
* The version that this class was deprecated in.
|
||||
*
|
||||
* @param object $rule The rule to validate.
|
||||
*
|
||||
* @return bool Pass/fail.
|
||||
* @var string
|
||||
*/
|
||||
public function validate( $rule ) {
|
||||
return true;
|
||||
}
|
||||
protected static $deprecated_in_version = '8.8.0';
|
||||
}
|
||||
|
||||
@@ -0,0 +1,288 @@
|
||||
<?php
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\RemoteSpecs;
|
||||
|
||||
/**
|
||||
* Specs data source poller class.
|
||||
* This handles polling specs from JSON endpoints, and
|
||||
* stores the specs in to the database as an option.
|
||||
*/
|
||||
abstract class DataSourcePoller {
|
||||
|
||||
/**
|
||||
* Get class instance.
|
||||
*/
|
||||
abstract public static function get_instance();
|
||||
|
||||
/**
|
||||
* Name of data sources filter.
|
||||
*/
|
||||
const FILTER_NAME = 'data_source_poller_data_sources';
|
||||
|
||||
/**
|
||||
* Name of data source specs filter.
|
||||
*/
|
||||
const FILTER_NAME_SPECS = 'data_source_poller_specs';
|
||||
|
||||
/**
|
||||
* Id of DataSourcePoller.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $id = array();
|
||||
|
||||
/**
|
||||
* Default data sources array.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $data_sources = array();
|
||||
|
||||
/**
|
||||
* Default args.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
protected $args = array();
|
||||
|
||||
/**
|
||||
* The logger instance.
|
||||
*
|
||||
* @var WC_Logger|null
|
||||
*/
|
||||
protected static $logger = null;
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*
|
||||
* @param string $id id of DataSourcePoller.
|
||||
* @param array $data_sources urls for data sources.
|
||||
* @param array $args Options for DataSourcePoller.
|
||||
*/
|
||||
public function __construct( $id, $data_sources = array(), $args = array() ) {
|
||||
$this->data_sources = $data_sources;
|
||||
$this->id = $id;
|
||||
|
||||
$arg_defaults = array(
|
||||
'spec_key' => 'id',
|
||||
'transient_name' => 'woocommerce_admin_' . $id . '_specs',
|
||||
'transient_expiry' => 7 * DAY_IN_SECONDS,
|
||||
);
|
||||
$this->args = wp_parse_args( $args, $arg_defaults );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the logger instance.
|
||||
*
|
||||
* @return WC_Logger
|
||||
*/
|
||||
protected static function get_logger() {
|
||||
if ( is_null( self::$logger ) ) {
|
||||
self::$logger = wc_get_logger();
|
||||
}
|
||||
|
||||
return self::$logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the key identifier of spec, this can easily be overwritten. Defaults to id.
|
||||
*
|
||||
* @param mixed $spec a JSON parsed spec coming from the JSON feed.
|
||||
* @return string|boolean
|
||||
*/
|
||||
protected function get_spec_key( $spec ) {
|
||||
$key = $this->args['spec_key'];
|
||||
if ( isset( $spec->$key ) ) {
|
||||
return $spec->$key;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the data sources for specs and persists those specs.
|
||||
*
|
||||
* @return array list of specs.
|
||||
*/
|
||||
public function get_specs_from_data_sources() {
|
||||
$locale = get_user_locale();
|
||||
$specs_group = get_transient( $this->args['transient_name'] ) ?? array();
|
||||
$specs = isset( $specs_group[ $locale ] ) ? $specs_group[ $locale ] : array();
|
||||
|
||||
if ( ! is_array( $specs ) || empty( $specs ) ) {
|
||||
$this->read_specs_from_data_sources();
|
||||
$specs_group = get_transient( $this->args['transient_name'] );
|
||||
$specs = isset( $specs_group[ $locale ] ) ? $specs_group[ $locale ] : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Filter specs.
|
||||
*
|
||||
* @param array $specs List of specs.
|
||||
* @param string $this->id Spec identifier.
|
||||
*
|
||||
* @since 8.8.0
|
||||
*/
|
||||
$specs = apply_filters( self::FILTER_NAME_SPECS, $specs, $this->id );
|
||||
return false !== $specs ? $specs : array();
|
||||
}
|
||||
|
||||
/**
|
||||
* Reads the data sources for specs and persists those specs.
|
||||
*
|
||||
* @return bool Whether any specs were read.
|
||||
*/
|
||||
public function read_specs_from_data_sources() {
|
||||
$specs = array();
|
||||
|
||||
/**
|
||||
* Filter data sources.
|
||||
*
|
||||
* @param array $this->data_sources List of data sources.
|
||||
* @param string $this->id Spec identifier.
|
||||
*
|
||||
* @since 8.8.0
|
||||
*/
|
||||
$data_sources = apply_filters( self::FILTER_NAME, $this->data_sources, $this->id );
|
||||
|
||||
// Note that this merges the specs from the data sources based on the
|
||||
// id - last one wins.
|
||||
foreach ( $data_sources as $url ) {
|
||||
$specs_from_data_source = self::read_data_source( $url );
|
||||
$this->merge_specs( $specs_from_data_source, $specs, $url );
|
||||
}
|
||||
|
||||
$specs_group = get_transient( $this->args['transient_name'] );
|
||||
$specs_group = is_array( $specs_group ) ? $specs_group : array();
|
||||
$locale = get_user_locale();
|
||||
$specs_group[ $locale ] = $specs;
|
||||
// Persist the specs as a transient.
|
||||
$this->set_specs_transient(
|
||||
$specs_group,
|
||||
$this->args['transient_expiry']
|
||||
);
|
||||
return count( $specs ) !== 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the specs transient.
|
||||
*
|
||||
* @return bool success of failure of transient deletion.
|
||||
*/
|
||||
public function delete_specs_transient() {
|
||||
return delete_transient( $this->args['transient_name'] );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the specs transient.
|
||||
*
|
||||
* @param array $specs The specs to set in the transient.
|
||||
* @param int $expiration The expiration time for the transient.
|
||||
*/
|
||||
public function set_specs_transient( $specs, $expiration = 0 ) {
|
||||
set_transient(
|
||||
$this->args['transient_name'],
|
||||
$specs,
|
||||
$expiration,
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Read a single data source and return the read specs
|
||||
*
|
||||
* @param string $url The URL to read the specs from.
|
||||
*
|
||||
* @return array The specs that have been read from the data source.
|
||||
*/
|
||||
protected static function read_data_source( $url ) {
|
||||
$logger_context = array( 'source' => $url );
|
||||
$logger = self::get_logger();
|
||||
$response = wp_remote_get(
|
||||
add_query_arg(
|
||||
'locale',
|
||||
get_user_locale(),
|
||||
$url
|
||||
),
|
||||
array(
|
||||
'user-agent' => 'WooCommerce/' . WC_VERSION . '; ' . home_url( '/' ),
|
||||
)
|
||||
);
|
||||
|
||||
if ( is_wp_error( $response ) || ! isset( $response['body'] ) ) {
|
||||
$logger->error(
|
||||
'Error getting data feed',
|
||||
$logger_context
|
||||
);
|
||||
// phpcs:ignore
|
||||
$logger->error( print_r( $response, true ), $logger_context );
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
$body = $response['body'];
|
||||
$specs = json_decode( $body );
|
||||
|
||||
if ( null === $specs ) {
|
||||
$logger->error(
|
||||
'Empty response in data feed',
|
||||
$logger_context
|
||||
);
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
if ( ! is_array( $specs ) ) {
|
||||
$logger->error(
|
||||
'Data feed is not an array',
|
||||
$logger_context
|
||||
);
|
||||
|
||||
return array();
|
||||
}
|
||||
|
||||
return $specs;
|
||||
}
|
||||
|
||||
/**
|
||||
* Merge the specs.
|
||||
*
|
||||
* @param Array $specs_to_merge_in The specs to merge in to $specs.
|
||||
* @param Array $specs The list of specs being merged into.
|
||||
* @param string $url The url of the feed being merged in (for error reporting).
|
||||
*/
|
||||
protected function merge_specs( $specs_to_merge_in, &$specs, $url ) {
|
||||
foreach ( $specs_to_merge_in as $spec ) {
|
||||
if ( ! $this->validate_spec( $spec, $url ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$id = $this->get_spec_key( $spec );
|
||||
$specs[ $id ] = $spec;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate the spec.
|
||||
*
|
||||
* @param object $spec The spec to validate.
|
||||
* @param string $url The url of the feed that provided the spec.
|
||||
*
|
||||
* @return bool The result of the validation.
|
||||
*/
|
||||
protected function validate_spec( $spec, $url ) {
|
||||
$logger = self::get_logger();
|
||||
$logger_context = array( 'source' => $url );
|
||||
|
||||
if ( ! $this->get_spec_key( $spec ) ) {
|
||||
$logger->error(
|
||||
'Spec is invalid because the id is missing in feed',
|
||||
$logger_context
|
||||
);
|
||||
// phpcs:ignore
|
||||
$logger->error( print_r( $spec, true ), $logger_context );
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,70 @@
|
||||
<?php
|
||||
/**
|
||||
* Rule processor that performs a comparison operation against the base
|
||||
* location - country.
|
||||
*/
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors;
|
||||
|
||||
use Automattic\WooCommerce\Internal\Admin\Onboarding\OnboardingProfile;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Rule processor that performs a comparison operation against the base
|
||||
* location - country.
|
||||
*/
|
||||
class BaseLocationCountryRuleProcessor implements RuleProcessorInterface {
|
||||
/**
|
||||
* Performs a comparison operation against the base location - country.
|
||||
*
|
||||
* @param object $rule The specific rule being processed by this rule processor.
|
||||
* @param object $stored_state Stored state.
|
||||
*
|
||||
* @return bool The result of the operation.
|
||||
*/
|
||||
public function process( $rule, $stored_state ) {
|
||||
$base_location = wc_get_base_location();
|
||||
if (
|
||||
! is_array( $base_location ) ||
|
||||
! array_key_exists( 'country', $base_location ) ||
|
||||
! array_key_exists( 'state', $base_location )
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$onboarding_profile = get_option( 'woocommerce_onboarding_profile', array() );
|
||||
$is_address_default = 'US' === $base_location['country'] && 'CA' === $base_location['state'] && empty( get_option( 'woocommerce_store_address', '' ) );
|
||||
$is_store_country_set = isset( $onboarding_profile['is_store_country_set'] ) && $onboarding_profile['is_store_country_set'];
|
||||
|
||||
// Return false if the location is the default country and if onboarding hasn't been finished or the store address not been updated.
|
||||
if ( $is_address_default && OnboardingProfile::needs_completion() && ! $is_store_country_set ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ComparisonOperation::compare(
|
||||
$base_location['country'],
|
||||
$rule->value,
|
||||
$rule->operation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the rule.
|
||||
*
|
||||
* @param object $rule The rule to validate.
|
||||
*
|
||||
* @return bool Pass/fail.
|
||||
*/
|
||||
public function validate( $rule ) {
|
||||
if ( ! isset( $rule->value ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! isset( $rule->operation ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,55 @@
|
||||
<?php
|
||||
/**
|
||||
* Rule processor that performs a comparison operation against the base
|
||||
* location - state.
|
||||
*/
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Rule processor that performs a comparison operation against the base
|
||||
* location - state.
|
||||
*/
|
||||
class BaseLocationStateRuleProcessor implements RuleProcessorInterface {
|
||||
/**
|
||||
* Performs a comparison operation against the base location - state.
|
||||
*
|
||||
* @param object $rule The specific rule being processed by this rule processor.
|
||||
* @param object $stored_state Stored state.
|
||||
*
|
||||
* @return bool The result of the operation.
|
||||
*/
|
||||
public function process( $rule, $stored_state ) {
|
||||
$base_location = wc_get_base_location();
|
||||
if ( ! is_array( $base_location ) || ! array_key_exists( 'state', $base_location ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return ComparisonOperation::compare(
|
||||
$base_location['state'],
|
||||
$rule->value,
|
||||
$rule->operation
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the rule.
|
||||
*
|
||||
* @param object $rule The rule to validate.
|
||||
*
|
||||
* @return bool Pass/fail.
|
||||
*/
|
||||
public function validate( $rule ) {
|
||||
if ( ! isset( $rule->value ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
if ( ! isset( $rule->operation ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,76 @@
|
||||
<?php
|
||||
/**
|
||||
* Compare two operands using the specified operation.
|
||||
*/
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Compare two operands using the specified operation.
|
||||
*/
|
||||
class ComparisonOperation {
|
||||
/**
|
||||
* Compare two operands using the specified operation.
|
||||
*
|
||||
* @param object $left_operand The left hand operand.
|
||||
* @param object $right_operand The right hand operand -- 'value' from the rule definition.
|
||||
* @param string $operation The operation used to compare the operands.
|
||||
*/
|
||||
public static function compare( $left_operand, $right_operand, $operation ) {
|
||||
switch ( $operation ) {
|
||||
case '=':
|
||||
return $left_operand === $right_operand;
|
||||
case '<':
|
||||
return $left_operand < $right_operand;
|
||||
case '<=':
|
||||
return $left_operand <= $right_operand;
|
||||
case '>':
|
||||
return $left_operand > $right_operand;
|
||||
case '>=':
|
||||
return $left_operand >= $right_operand;
|
||||
case '!=':
|
||||
return $left_operand !== $right_operand;
|
||||
case 'contains':
|
||||
if ( is_array( $left_operand ) && is_string( $right_operand ) ) {
|
||||
return in_array( $right_operand, $left_operand, true );
|
||||
}
|
||||
if ( is_string( $right_operand ) && is_string( $left_operand ) ) {
|
||||
return strpos( $right_operand, $left_operand ) !== false;
|
||||
}
|
||||
break;
|
||||
case '!contains':
|
||||
if ( is_array( $left_operand ) && is_string( $right_operand ) ) {
|
||||
return ! in_array( $right_operand, $left_operand, true );
|
||||
}
|
||||
if ( is_string( $right_operand ) && is_string( $left_operand ) ) {
|
||||
return strpos( $right_operand, $left_operand ) === false;
|
||||
}
|
||||
break;
|
||||
case 'in':
|
||||
if ( is_array( $right_operand ) && is_string( $left_operand ) ) {
|
||||
return in_array( $left_operand, $right_operand, true );
|
||||
}
|
||||
if ( is_string( $left_operand ) && is_string( $right_operand ) ) {
|
||||
return strpos( $left_operand, $right_operand ) !== false;
|
||||
}
|
||||
break;
|
||||
case '!in':
|
||||
if ( is_array( $right_operand ) && is_string( $left_operand ) ) {
|
||||
return ! in_array( $left_operand, $right_operand, true );
|
||||
}
|
||||
if ( is_string( $left_operand ) && is_string( $right_operand ) ) {
|
||||
return strpos( $left_operand, $right_operand ) === false;
|
||||
}
|
||||
break;
|
||||
case 'range':
|
||||
if ( ! is_array( $right_operand ) || count( $right_operand ) !== 2 ) {
|
||||
return false;
|
||||
}
|
||||
return $left_operand >= $right_operand[0] && $left_operand <= $right_operand[1];
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,59 @@
|
||||
<?php
|
||||
/**
|
||||
* Evaluates the spec and returns a status.
|
||||
*/
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
use Automattic\WooCommerce\Admin\Notes\Note;
|
||||
|
||||
/**
|
||||
* Evaluates the spec and returns a status.
|
||||
*/
|
||||
class EvaluateAndGetStatus {
|
||||
/**
|
||||
* Evaluates the spec and returns a status.
|
||||
*
|
||||
* @param array $spec The spec to evaluate.
|
||||
* @param string $current_status The note's current status.
|
||||
* @param object $stored_state Stored state.
|
||||
* @param object $rule_evaluator Evaluates rules into true/false.
|
||||
*
|
||||
* @return string The evaluated status.
|
||||
*/
|
||||
public static function evaluate( $spec, $current_status, $stored_state, $rule_evaluator ) {
|
||||
// No rules should leave the note alone.
|
||||
if ( ! isset( $spec->rules ) ) {
|
||||
return $current_status;
|
||||
}
|
||||
|
||||
$evaluated_result = $rule_evaluator->evaluate(
|
||||
$spec->rules,
|
||||
$stored_state,
|
||||
array(
|
||||
'slug' => $spec->slug,
|
||||
'source' => 'remote-inbox-notifications',
|
||||
)
|
||||
);
|
||||
|
||||
// Pending notes should be the spec status if the spec passes,
|
||||
// left alone otherwise.
|
||||
if ( Note::E_WC_ADMIN_NOTE_PENDING === $current_status ) {
|
||||
return $evaluated_result
|
||||
? $spec->status
|
||||
: Note::E_WC_ADMIN_NOTE_PENDING;
|
||||
}
|
||||
|
||||
// When allow_redisplay isn't set, just leave the note alone.
|
||||
if ( ! isset( $spec->allow_redisplay ) || ! $spec->allow_redisplay ) {
|
||||
return $current_status;
|
||||
}
|
||||
|
||||
// allow_redisplay is set, unaction the note if eval to true.
|
||||
return $evaluated_result
|
||||
? Note::E_WC_ADMIN_NOTE_UNACTIONED
|
||||
: $current_status;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,90 @@
|
||||
<?php
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors;
|
||||
|
||||
/**
|
||||
* Class EvaluationLogger
|
||||
*
|
||||
* @package Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors
|
||||
*/
|
||||
class EvaluationLogger {
|
||||
/**
|
||||
* Slug of the spec.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $slug;
|
||||
|
||||
/**
|
||||
* Results of rules in the given spec.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $results = array();
|
||||
|
||||
/**
|
||||
* Logger class to use.
|
||||
*
|
||||
* @var WC_Logger_Interface|null
|
||||
*/
|
||||
private $logger;
|
||||
|
||||
/**
|
||||
* Logger source.
|
||||
*
|
||||
* @var string logger source.
|
||||
*/
|
||||
private $source = '';
|
||||
|
||||
/**
|
||||
* EvaluationLogger constructor.
|
||||
*
|
||||
* @param string $slug Slug of a spec that is being evaluated.
|
||||
* @param null $source Logger source.
|
||||
* @param \WC_Logger_Interface $logger Logger class to use.
|
||||
*/
|
||||
public function __construct( $slug, $source = null, \WC_Logger_Interface $logger = null ) {
|
||||
$this->slug = $slug;
|
||||
if ( null === $logger ) {
|
||||
$logger = wc_get_logger();
|
||||
}
|
||||
|
||||
if ( $source ) {
|
||||
$this->source = $source;
|
||||
}
|
||||
|
||||
$this->logger = $logger;
|
||||
}
|
||||
|
||||
/**
|
||||
* Add evaluation result of a rule.
|
||||
*
|
||||
* @param string $rule_type name of the rule being tested.
|
||||
* @param boolean $result result of a given rule.
|
||||
*/
|
||||
public function add_result( $rule_type, $result ) {
|
||||
array_push(
|
||||
$this->results,
|
||||
array(
|
||||
'rule' => $rule_type,
|
||||
'result' => $result ? 'passed' : 'failed',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Log the results.
|
||||
*/
|
||||
public function log() {
|
||||
if ( false === defined( 'WC_ADMIN_DEBUG_RULE_EVALUATOR' ) || true !== constant( 'WC_ADMIN_DEBUG_RULE_EVALUATOR' ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
foreach ( $this->results as $result ) {
|
||||
$this->logger->debug(
|
||||
"[{$this->slug}] {$result['rule']}: {$result['result']}",
|
||||
array( 'source' => $this->source )
|
||||
);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,36 @@
|
||||
<?php
|
||||
/**
|
||||
* Rule processor that fails.
|
||||
*/
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Rule processor that fails.
|
||||
*/
|
||||
class FailRuleProcessor implements RuleProcessorInterface {
|
||||
/**
|
||||
* Fails the rule.
|
||||
*
|
||||
* @param object $rule The specific rule being processed by this rule processor.
|
||||
* @param object $stored_state Stored state.
|
||||
*
|
||||
* @return bool Always false.
|
||||
*/
|
||||
public function process( $rule, $stored_state ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validates the rule.
|
||||
*
|
||||
* @param object $rule The rule to validate.
|
||||
*
|
||||
* @return bool Pass/fail.
|
||||
*/
|
||||
public function validate( $rule ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
/**
|
||||
* Gets the processor for the specified rule type.
|
||||
*/
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\RemoteSpecs\RuleProcessors;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Class encapsulating getting the processor for a given rule type.
|
||||
*/
|
||||
class GetRuleProcessor {
|
||||
/**
|
||||
* Get the processor for the specified rule type.
|
||||
*
|
||||
* @param string $rule_type The rule type.
|
||||
*
|
||||
* @return RuleProcessorInterface The matching processor for the specified rule type, or a FailRuleProcessor if no matching processor is found.
|
||||
*/
|
||||
public static function get_processor( $rule_type ) {
|
||||
switch ( $rule_type ) {
|
||||
case 'plugins_activated':
|
||||
return new PluginsActivatedRuleProcessor();
|
||||
case 'publish_after_time':
|
||||
return new PublishAfterTimeRuleProcessor();
|
||||
case 'publish_before_time':
|
||||
return new PublishBeforeTimeRuleProcessor();
|
||||
case 'not':
|
||||
return new NotRuleProcessor();
|
||||
case 'or':
|
||||
return new OrRuleProcessor();
|
||||
case 'fail':
|
||||
return new FailRuleProcessor();
|
||||
case 'pass':
|
||||
return new PassRuleProcessor();
|
||||
case 'plugin_version':
|
||||
return new PluginVersionRuleProcessor();
|
||||
case 'stored_state':
|
||||
return new StoredStateRuleProcessor();
|
||||
case 'order_count':
|
||||
return new OrderCountRuleProcessor();
|
||||
case 'wcadmin_active_for':
|
||||
return new WCAdminActiveForRuleProcessor();
|
||||
case 'product_count':
|
||||
return new ProductCountRuleProcessor();
|
||||
case 'onboarding_profile':
|
||||
return new OnboardingProfileRuleProcessor();
|
||||
case 'is_ecommerce':
|
||||
return new IsEcommerceRuleProcessor();
|
||||
case 'is_woo_express':
|
||||
return new IsWooExpressRuleProcessor();
|
||||
case 'base_location_country':
|
||||
return new BaseLocationCountryRuleProcessor();
|
||||
case 'base_location_state':
|
||||
return new BaseLocationStateRuleProcessor();
|
||||
case 'note_status':
|
||||
return new NoteStatusRuleProcessor();
|
||||
case 'option':
|
||||
return new OptionRuleProcessor();
|
||||
case 'wca_updated':
|
||||
return new WooCommerceAdminUpdatedRuleProcessor();
|
||||
case 'total_payments_value':
|
||||
return new TotalPaymentsVolumeProcessor();
|
||||
}
|
||||
|
||||
return new FailRuleProcessor();
|
||||
}
|
||||
}
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user