plugin updates
This commit is contained in:
@@ -93,6 +93,7 @@ class Init {
|
||||
'Automattic\WooCommerce\Admin\API\OnboardingTasks',
|
||||
'Automattic\WooCommerce\Admin\API\OnboardingThemes',
|
||||
'Automattic\WooCommerce\Admin\API\OnboardingPlugins',
|
||||
'Automattic\WooCommerce\Admin\API\OnboardingProducts',
|
||||
'Automattic\WooCommerce\Admin\API\NavigationFavorites',
|
||||
'Automattic\WooCommerce\Admin\API\Taxes',
|
||||
'Automattic\WooCommerce\Admin\API\MobileAppMagicLink',
|
||||
|
||||
@@ -9,6 +9,7 @@ namespace Automattic\WooCommerce\Admin\API;
|
||||
|
||||
use Automattic\WooCommerce\Admin\PluginsHelper;
|
||||
use Automattic\WooCommerce\Internal\Admin\Marketing\MarketingSpecs;
|
||||
use Automattic\WooCommerce\Admin\Features\MarketingRecommendations\Init as MarketingRecommendationsInit;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
@@ -103,16 +104,9 @@ class Marketing extends \WC_REST_Data_Controller {
|
||||
* @return \WP_Error|\WP_REST_Response
|
||||
*/
|
||||
public function get_recommended_plugins( $request ) {
|
||||
/**
|
||||
* MarketingSpecs class.
|
||||
*
|
||||
* @var MarketingSpecs $marketing_specs
|
||||
*/
|
||||
$marketing_specs = wc_get_container()->get( MarketingSpecs::class );
|
||||
|
||||
// Default to marketing category (if no category set).
|
||||
$category = ( ! empty( $request->get_param( 'category' ) ) ) ? $request->get_param( 'category' ) : 'marketing';
|
||||
$all_plugins = $marketing_specs->get_recommended_plugins();
|
||||
$all_plugins = MarketingRecommendationsInit::get_recommended_plugins();
|
||||
$valid_plugins = [];
|
||||
$per_page = $request->get_param( 'per_page' );
|
||||
|
||||
|
||||
@@ -91,7 +91,7 @@ class MarketingCampaigns extends WC_REST_Controller {
|
||||
$marketing_channels_service = wc_get_container()->get( MarketingChannelsService::class );
|
||||
|
||||
// Aggregate the campaigns from all registered marketing channels.
|
||||
$responses = [];
|
||||
$responses = array();
|
||||
foreach ( $marketing_channels_service->get_registered_channels() as $channel ) {
|
||||
foreach ( $channel->get_campaigns() as $campaign ) {
|
||||
$response = $this->prepare_item_for_response( $campaign, $request );
|
||||
@@ -141,18 +141,25 @@ class MarketingCampaigns extends WC_REST_Controller {
|
||||
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
|
||||
*/
|
||||
public function prepare_item_for_response( $item, $request ) {
|
||||
$data = [
|
||||
$data = array(
|
||||
'id' => $item->get_id(),
|
||||
'channel' => $item->get_type()->get_channel()->get_slug(),
|
||||
'title' => $item->get_title(),
|
||||
'manage_url' => $item->get_manage_url(),
|
||||
];
|
||||
);
|
||||
|
||||
if ( $item->get_cost() instanceof Price ) {
|
||||
$data['cost'] = [
|
||||
$data['cost'] = array(
|
||||
'value' => wc_format_decimal( $item->get_cost()->get_value() ),
|
||||
'currency' => $item->get_cost()->get_currency(),
|
||||
];
|
||||
);
|
||||
}
|
||||
|
||||
if ( $item->get_sales() instanceof Price ) {
|
||||
$data['sales'] = array(
|
||||
'value' => wc_format_decimal( $item->get_sales()->get_value() ),
|
||||
'currency' => $item->get_sales()->get_currency(),
|
||||
);
|
||||
}
|
||||
|
||||
$context = $request['context'] ?? 'view';
|
||||
@@ -168,55 +175,73 @@ class MarketingCampaigns extends WC_REST_Controller {
|
||||
* @return array Item schema data.
|
||||
*/
|
||||
public function get_item_schema() {
|
||||
$schema = [
|
||||
$schema = array(
|
||||
'$schema' => 'http://json-schema.org/draft-04/schema#',
|
||||
'title' => 'marketing_campaign',
|
||||
'type' => 'object',
|
||||
'properties' => [
|
||||
'id' => [
|
||||
'properties' => array(
|
||||
'id' => array(
|
||||
'description' => __( 'The unique identifier for the marketing campaign.', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'context' => [ 'view' ],
|
||||
'context' => array( 'view' ),
|
||||
'readonly' => true,
|
||||
],
|
||||
'channel' => [
|
||||
),
|
||||
'channel' => array(
|
||||
'description' => __( 'The unique identifier for the marketing channel that this campaign belongs to.', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'context' => [ 'view' ],
|
||||
'context' => array( 'view' ),
|
||||
'readonly' => true,
|
||||
],
|
||||
'title' => [
|
||||
),
|
||||
'title' => array(
|
||||
'description' => __( 'Title of the marketing campaign.', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'context' => [ 'view' ],
|
||||
'context' => array( 'view' ),
|
||||
'readonly' => true,
|
||||
],
|
||||
'manage_url' => [
|
||||
),
|
||||
'manage_url' => array(
|
||||
'description' => __( 'URL to the campaign management page.', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'context' => [ 'view' ],
|
||||
'context' => array( 'view' ),
|
||||
'readonly' => true,
|
||||
],
|
||||
'cost' => [
|
||||
),
|
||||
'cost' => array(
|
||||
'description' => __( 'Cost of the marketing campaign.', 'woocommerce' ),
|
||||
'context' => [ 'view' ],
|
||||
'context' => array( 'view' ),
|
||||
'readonly' => true,
|
||||
'type' => 'object',
|
||||
'properties' => [
|
||||
'value' => [
|
||||
'properties' => array(
|
||||
'value' => array(
|
||||
'type' => 'string',
|
||||
'context' => [ 'view' ],
|
||||
'context' => array( 'view' ),
|
||||
'readonly' => true,
|
||||
],
|
||||
'currency' => [
|
||||
),
|
||||
'currency' => array(
|
||||
'type' => 'string',
|
||||
'context' => [ 'view' ],
|
||||
'context' => array( 'view' ),
|
||||
'readonly' => true,
|
||||
],
|
||||
],
|
||||
],
|
||||
],
|
||||
];
|
||||
),
|
||||
),
|
||||
),
|
||||
'sales' => array(
|
||||
'description' => __( 'Sales of the marketing campaign.', 'woocommerce' ),
|
||||
'context' => array( 'view' ),
|
||||
'readonly' => true,
|
||||
'type' => 'object',
|
||||
'properties' => array(
|
||||
'value' => array(
|
||||
'type' => 'string',
|
||||
'context' => array( 'view' ),
|
||||
'readonly' => true,
|
||||
),
|
||||
'currency' => array(
|
||||
'type' => 'string',
|
||||
'context' => array( 'view' ),
|
||||
'readonly' => true,
|
||||
),
|
||||
),
|
||||
),
|
||||
),
|
||||
);
|
||||
|
||||
return $this->add_additional_fields_schema( $schema );
|
||||
}
|
||||
|
||||
@@ -7,7 +7,7 @@
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\API;
|
||||
|
||||
use Automattic\WooCommerce\Internal\Admin\Marketing\MarketingSpecs;
|
||||
use Automattic\WooCommerce\Admin\Features\MarketingRecommendations\Init as MarketingRecommendationsInit;
|
||||
use WC_REST_Controller;
|
||||
use WP_Error;
|
||||
use WP_REST_Request;
|
||||
@@ -88,18 +88,11 @@ class MarketingRecommendations extends WC_REST_Controller {
|
||||
* @return WP_REST_Response|WP_Error Response object on success, or WP_Error object on failure.
|
||||
*/
|
||||
public function get_items( $request ) {
|
||||
/**
|
||||
* MarketingSpecs class.
|
||||
*
|
||||
* @var MarketingSpecs $marketing_specs
|
||||
*/
|
||||
$marketing_specs = wc_get_container()->get( MarketingSpecs::class );
|
||||
|
||||
$category = $request->get_param( 'category' );
|
||||
if ( 'channels' === $category ) {
|
||||
$items = $marketing_specs->get_recommended_marketing_channels();
|
||||
$items = MarketingRecommendationsInit::get_recommended_marketing_channels();
|
||||
} elseif ( 'extensions' === $category ) {
|
||||
$items = $marketing_specs->get_recommended_marketing_extensions_excluding_channels();
|
||||
$items = MarketingRecommendationsInit::get_recommended_marketing_extensions_excluding_channels();
|
||||
} else {
|
||||
return new WP_Error( 'woocommerce_rest_invalid_category', __( 'The specified category for recommendations is invalid. Allowed values: "channels", "extensions".', 'woocommerce' ), array( 'status' => 400 ) );
|
||||
}
|
||||
|
||||
@@ -0,0 +1,85 @@
|
||||
<?php
|
||||
/**
|
||||
* REST API Onboarding Themes Controller
|
||||
*
|
||||
* Handles requests to install and activate themes.
|
||||
*/
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\API;
|
||||
|
||||
use Automattic\WooCommerce\Blocks\AIContent\UpdateProducts;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Onboarding Themes Controller.
|
||||
*
|
||||
* @internal
|
||||
* @extends WC_REST_Data_Controller
|
||||
*/
|
||||
class OnboardingProducts extends \WC_REST_Data_Controller {
|
||||
/**
|
||||
* Endpoint namespace.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $namespace = 'wc-admin';
|
||||
|
||||
/**
|
||||
* Route base.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
protected $rest_base = 'onboarding';
|
||||
|
||||
/**
|
||||
* Register routes.
|
||||
*/
|
||||
public function register_routes() {
|
||||
register_rest_route(
|
||||
$this->namespace,
|
||||
'/' . $this->rest_base . '/products',
|
||||
array(
|
||||
array(
|
||||
'methods' => \WP_REST_Server::CREATABLE,
|
||||
'callback' => array( $this, 'create_products' ),
|
||||
'permission_callback' => array( $this, 'update_item_permissions_check' ),
|
||||
),
|
||||
'schema' => array( $this, 'get_item_schema' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Create products.
|
||||
*
|
||||
* @param WP_REST_Request $request Full details about the request.
|
||||
* @return WP_Error|WP_REST_Response
|
||||
*/
|
||||
public function create_products( $request ) {
|
||||
$update_products = new UpdateProducts();
|
||||
|
||||
$products = $update_products->fetch_dummy_products_to_update();
|
||||
|
||||
if ( is_wp_error( $products ) ) {
|
||||
return rest_ensure_response( array( 'success' => false ) );
|
||||
}
|
||||
|
||||
return rest_ensure_response( array( 'success' => true ) );
|
||||
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a given request has access to manage themes.
|
||||
*
|
||||
* @param WP_REST_Request $request Full details about the request.
|
||||
* @return WP_Error|boolean
|
||||
*/
|
||||
public function update_item_permissions_check( $request ) {
|
||||
if ( ! current_user_can( 'manage_options' ) ) {
|
||||
return new \WP_Error( 'woocommerce_rest_cannot_update', __( 'Sorry, you cannot create dummy products.', 'woocommerce' ), array( 'status' => rest_authorization_required_code() ) );
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -389,21 +389,6 @@ class OnboardingProfile extends \WC_REST_Data_Controller {
|
||||
'sanitize_callback' => 'wp_parse_slug_list',
|
||||
'validate_callback' => 'rest_validate_request_arg',
|
||||
'items' => array(
|
||||
'enum' => array(
|
||||
'jetpack',
|
||||
'jetpack-boost',
|
||||
'woocommerce-services',
|
||||
'woocommerce-payments',
|
||||
'mailchimp-for-woocommerce',
|
||||
'creative-mail-by-constant-contact',
|
||||
'facebook-for-woocommerce',
|
||||
'google-listings-and-ads',
|
||||
'pinterest-for-woocommerce',
|
||||
'mailpoet',
|
||||
'codistoconnect',
|
||||
'tiktok-for-business',
|
||||
'tiktok-for-business:alt',
|
||||
),
|
||||
'type' => 'string',
|
||||
),
|
||||
),
|
||||
|
||||
@@ -304,6 +304,10 @@ class DataStore extends ReportsDataStore implements DataStoreInterface {
|
||||
$cache_key = $this->get_cache_key( $query_args );
|
||||
$data = $this->get_cached_data( $cache_key );
|
||||
|
||||
if ( isset( $query_args['date_type'] ) ) {
|
||||
$this->date_column_name = $query_args['date_type'];
|
||||
}
|
||||
|
||||
if ( false === $data ) {
|
||||
$this->initialize_queries();
|
||||
|
||||
|
||||
@@ -54,6 +54,7 @@ class Controller extends GenericStatsController implements ExportableInterface {
|
||||
$args['segmentby'] = $request['segmentby'];
|
||||
$args['fields'] = $request['fields'];
|
||||
$args['force_cache_refresh'] = $request['force_cache_refresh'];
|
||||
$args['date_type'] = $request['date_type'];
|
||||
|
||||
return $args;
|
||||
}
|
||||
@@ -268,6 +269,16 @@ class Controller extends GenericStatsController implements ExportableInterface {
|
||||
),
|
||||
'validate_callback' => 'rest_validate_request_arg',
|
||||
);
|
||||
$params['date_type'] = array(
|
||||
'description' => __( 'Override the "woocommerce_date_type" option that is used for the database date field considered for revenue reports.', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'enum' => array(
|
||||
'date_paid',
|
||||
'date_created',
|
||||
'date_completed',
|
||||
),
|
||||
'validate_callback' => 'rest_validate_request_arg',
|
||||
);
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
@@ -33,4 +33,11 @@ interface BlockTemplateInterface extends ContainerInterface {
|
||||
* @return string
|
||||
*/
|
||||
public function generate_block_id( string $id_base ): string;
|
||||
|
||||
/**
|
||||
* Get the template as JSON like array.
|
||||
*
|
||||
* @return array The JSON.
|
||||
*/
|
||||
public function to_json(): array;
|
||||
}
|
||||
|
||||
@@ -0,0 +1,380 @@
|
||||
<?php
|
||||
/**
|
||||
* Gets a list of fallback methods if remote fetching is disabled.
|
||||
*/
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\Features\MarketingRecommendations;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Default Marketing Recommendations
|
||||
*/
|
||||
class DefaultMarketingRecommendations {
|
||||
/**
|
||||
* Get default specs.
|
||||
*
|
||||
* @return array Default specs.
|
||||
*/
|
||||
public static function get_all() {
|
||||
// Icon directory URL.
|
||||
$icon_dir_url = WC_ADMIN_IMAGES_FOLDER_URL . '/marketing';
|
||||
|
||||
$utm_string = '?utm_source=marketingtab&utm_medium=product&utm_campaign=wcaddons';
|
||||
|
||||
// Categories. Note that these are keys used in code, not texts to be displayed in the UI.
|
||||
$marketing = 'marketing';
|
||||
$coupons = 'coupons';
|
||||
|
||||
// Subcategories.
|
||||
$sales_channels = array(
|
||||
'slug' => 'sales-channels',
|
||||
'name' => __( 'Sales channels', 'woocommerce' ),
|
||||
);
|
||||
$email = array(
|
||||
'slug' => 'email',
|
||||
'name' => __( 'Email', 'woocommerce' ),
|
||||
);
|
||||
$automations = array(
|
||||
'slug' => 'automations',
|
||||
'name' => __( 'Automations', 'woocommerce' ),
|
||||
);
|
||||
$conversion = array(
|
||||
'slug' => 'conversion',
|
||||
'name' => __( 'Conversion', 'woocommerce' ),
|
||||
);
|
||||
$crm = array(
|
||||
'slug' => 'crm',
|
||||
'name' => __( 'CRM', 'woocommerce' ),
|
||||
);
|
||||
|
||||
// Tags.
|
||||
$built_by_woocommerce = array(
|
||||
'slug' => 'built-by-woocommerce',
|
||||
'name' => __( 'Built by WooCommerce', 'woocommerce' ),
|
||||
);
|
||||
|
||||
return array(
|
||||
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}",
|
||||
'direct_install' => true,
|
||||
'icon' => "{$icon_dir_url}/google.svg",
|
||||
'product' => 'google-listings-and-ads',
|
||||
'plugin' => 'google-listings-and-ads/google-listings-and-ads.php',
|
||||
'categories' => array(
|
||||
$marketing,
|
||||
),
|
||||
'subcategories' => array(
|
||||
$sales_channels,
|
||||
),
|
||||
'tags' => array(
|
||||
$built_by_woocommerce,
|
||||
),
|
||||
),
|
||||
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}",
|
||||
'direct_install' => true,
|
||||
'icon' => "{$icon_dir_url}/pinterest.svg",
|
||||
'product' => 'pinterest-for-woocommerce',
|
||||
'plugin' => 'pinterest-for-woocommerce/pinterest-for-woocommerce.php',
|
||||
'categories' => array(
|
||||
$marketing,
|
||||
),
|
||||
'subcategories' => array(
|
||||
$sales_channels,
|
||||
),
|
||||
'tags' => array(
|
||||
$built_by_woocommerce,
|
||||
),
|
||||
),
|
||||
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}",
|
||||
'direct_install' => true,
|
||||
'icon' => "{$icon_dir_url}/tiktok.jpg",
|
||||
'product' => 'tiktok-for-business',
|
||||
'plugin' => 'tiktok-for-business/tiktok-for-woocommerce.php',
|
||||
'categories' => array(
|
||||
$marketing,
|
||||
),
|
||||
'subcategories' => array(
|
||||
$sales_channels,
|
||||
),
|
||||
'tags' => array(),
|
||||
),
|
||||
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}",
|
||||
'direct_install' => true,
|
||||
'icon' => "{$icon_dir_url}/mailpoet.svg",
|
||||
'product' => 'mailpoet',
|
||||
'plugin' => 'mailpoet/mailpoet.php',
|
||||
'categories' => array(
|
||||
$marketing,
|
||||
),
|
||||
'subcategories' => array(
|
||||
$email,
|
||||
),
|
||||
'tags' => array(
|
||||
$built_by_woocommerce,
|
||||
),
|
||||
),
|
||||
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}",
|
||||
'direct_install' => true,
|
||||
'icon' => "{$icon_dir_url}/mailchimp.svg",
|
||||
'product' => 'mailchimp-for-woocommerce',
|
||||
'plugin' => 'mailchimp-for-woocommerce/mailchimp-woocommerce.php',
|
||||
'categories' => array(
|
||||
$marketing,
|
||||
),
|
||||
'subcategories' => array(
|
||||
$email,
|
||||
),
|
||||
'tags' => array(),
|
||||
),
|
||||
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}",
|
||||
'direct_install' => true,
|
||||
'icon' => "{$icon_dir_url}/klaviyo.png",
|
||||
'product' => 'klaviyo',
|
||||
'plugin' => 'klaviyo/klaviyo.php',
|
||||
'categories' => array(
|
||||
$marketing,
|
||||
),
|
||||
'subcategories' => array(
|
||||
$email,
|
||||
),
|
||||
'tags' => array(),
|
||||
),
|
||||
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}",
|
||||
'direct_install' => false,
|
||||
'icon' => "{$icon_dir_url}/automatewoo.svg",
|
||||
'product' => 'automatewoo',
|
||||
'plugin' => 'automatewoo/automatewoo.php',
|
||||
'categories' => array(
|
||||
$marketing,
|
||||
),
|
||||
'subcategories' => array(
|
||||
$automations,
|
||||
),
|
||||
'tags' => array(
|
||||
$built_by_woocommerce,
|
||||
),
|
||||
),
|
||||
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}",
|
||||
'direct_install' => false,
|
||||
'icon' => "{$icon_dir_url}/automatewoo.svg",
|
||||
'product' => 'automatewoo-referrals',
|
||||
'plugin' => 'automatewoo-referrals/automatewoo-referrals.php',
|
||||
'categories' => array(
|
||||
$marketing,
|
||||
),
|
||||
'subcategories' => array(
|
||||
$automations,
|
||||
),
|
||||
'tags' => array(
|
||||
$built_by_woocommerce,
|
||||
),
|
||||
),
|
||||
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}",
|
||||
'direct_install' => false,
|
||||
'icon' => "{$icon_dir_url}/automatewoo.svg",
|
||||
'product' => 'automatewoo-birthdays',
|
||||
'plugin' => 'automatewoo-birthdays/automatewoo-birthdays.php',
|
||||
'categories' => array(
|
||||
$marketing,
|
||||
),
|
||||
'subcategories' => array(
|
||||
$automations,
|
||||
),
|
||||
'tags' => array(
|
||||
$built_by_woocommerce,
|
||||
),
|
||||
),
|
||||
array(
|
||||
'title' => 'Trustpilot Reviews',
|
||||
'description' => __( 'Collect and showcase verified reviews that consumers trust.', 'woocommerce' ),
|
||||
'url' => "https://woo.com/products/trustpilot-reviews/{$utm_string}",
|
||||
'direct_install' => true,
|
||||
'icon' => "{$icon_dir_url}/trustpilot.png",
|
||||
'product' => 'trustpilot-reviews',
|
||||
'plugin' => 'trustpilot-reviews/wc_trustpilot.php',
|
||||
'categories' => array(
|
||||
$marketing,
|
||||
),
|
||||
'subcategories' => array(
|
||||
$conversion,
|
||||
),
|
||||
'tags' => array(),
|
||||
),
|
||||
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}",
|
||||
'direct_install' => true,
|
||||
'icon' => "{$icon_dir_url}/vimeo.png",
|
||||
'product' => 'vimeo',
|
||||
'plugin' => 'vimeo/Core.php',
|
||||
'categories' => array(
|
||||
$marketing,
|
||||
),
|
||||
'subcategories' => array(
|
||||
$conversion,
|
||||
),
|
||||
'tags' => array(),
|
||||
),
|
||||
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}",
|
||||
'direct_install' => true,
|
||||
'icon' => "{$icon_dir_url}/jetpack-crm.svg",
|
||||
'product' => 'zero-bs-crm',
|
||||
'plugin' => 'zero-bs-crm/ZeroBSCRM.php',
|
||||
'categories' => array(
|
||||
$marketing,
|
||||
),
|
||||
'subcategories' => array(
|
||||
$crm,
|
||||
),
|
||||
'tags' => array(),
|
||||
),
|
||||
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}",
|
||||
'direct_install' => false,
|
||||
'icon' => "{$icon_dir_url}/zapier.png",
|
||||
'product' => 'woocommerce-zapier',
|
||||
'plugin' => 'woocommerce-zapier/woocommerce-zapier.php',
|
||||
'categories' => array(
|
||||
$marketing,
|
||||
),
|
||||
'subcategories' => array(
|
||||
$crm,
|
||||
),
|
||||
'tags' => array(),
|
||||
),
|
||||
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}",
|
||||
'direct_install' => false,
|
||||
'icon' => "{$icon_dir_url}/salesforce.jpg",
|
||||
'product' => 'integration-with-salesforce',
|
||||
'plugin' => 'integration-with-salesforce/integration-with-salesforce.php',
|
||||
'categories' => array(
|
||||
$marketing,
|
||||
),
|
||||
'subcategories' => array(
|
||||
$crm,
|
||||
),
|
||||
'tags' => array(),
|
||||
),
|
||||
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}",
|
||||
'direct_install' => false,
|
||||
'icon' => "{$icon_dir_url}/automatewoo-personalized-coupons.svg",
|
||||
'product' => 'automatewoo',
|
||||
'plugin' => 'automatewoo/automatewoo.php',
|
||||
'categories' => array(
|
||||
$coupons,
|
||||
),
|
||||
'subcategories' => array(),
|
||||
'tags' => array(),
|
||||
),
|
||||
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}",
|
||||
'direct_install' => false,
|
||||
'icon' => "{$icon_dir_url}/woocommerce-smart-coupons.svg",
|
||||
'product' => 'woocommerce-smart-coupons',
|
||||
'plugin' => 'woocommerce-smart-coupons/woocommerce-smart-coupons.php',
|
||||
'categories' => array(
|
||||
$coupons,
|
||||
),
|
||||
'subcategories' => array(),
|
||||
'tags' => array(),
|
||||
),
|
||||
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}",
|
||||
'direct_install' => false,
|
||||
'icon' => "{$icon_dir_url}/woocommerce-url-coupons.svg",
|
||||
'product' => 'woocommerce-url-coupons',
|
||||
'plugin' => 'woocommerce-url-coupons/woocommerce-url-coupons.php',
|
||||
'categories' => array(
|
||||
$coupons,
|
||||
),
|
||||
'subcategories' => array(),
|
||||
'tags' => array(),
|
||||
),
|
||||
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}",
|
||||
'direct_install' => false,
|
||||
'icon' => "{$icon_dir_url}/woocommerce-store-credit.svg",
|
||||
'product' => 'woocommerce-store-credit',
|
||||
'plugin' => 'woocommerce-store-credit/woocommerce-store-credit.php',
|
||||
'categories' => array(
|
||||
$coupons,
|
||||
),
|
||||
'subcategories' => array(),
|
||||
'tags' => array(),
|
||||
),
|
||||
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}",
|
||||
'direct_install' => false,
|
||||
'icon' => "{$icon_dir_url}/woocommerce-free-gift-coupons.svg",
|
||||
'product' => 'woocommerce-free-gift-coupons',
|
||||
'plugin' => 'woocommerce-free-gift-coupons/woocommerce-free-gift-coupons.php',
|
||||
'categories' => array(
|
||||
$coupons,
|
||||
),
|
||||
'subcategories' => array(),
|
||||
'tags' => array(),
|
||||
),
|
||||
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}",
|
||||
'direct_install' => false,
|
||||
'icon' => "{$icon_dir_url}/woocommerce-group-coupons.svg",
|
||||
'product' => 'woocommerce-group-coupons',
|
||||
'plugin' => 'woocommerce-group-coupons/woocommerce-group-coupons.php',
|
||||
'categories' => array(
|
||||
$coupons,
|
||||
),
|
||||
'subcategories' => array(),
|
||||
'tags' => array(),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,158 @@
|
||||
<?php
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\Features\MarketingRecommendations;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* Marketing Recommendations engine.
|
||||
* This goes through the specs and gets marketing recommendations.
|
||||
*/
|
||||
class Init {
|
||||
/**
|
||||
* Slug of the category specifying marketing extensions on the Woo.com store.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const MARKETING_EXTENSION_CATEGORY_SLUG = 'marketing';
|
||||
|
||||
/**
|
||||
* Slug of the subcategory specifying marketing channels on the Woo.com store.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
const MARKETING_CHANNEL_SUBCATEGORY_SLUG = 'sales-channels';
|
||||
|
||||
/**
|
||||
* Constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
add_action( 'woocommerce_updated', array( __CLASS__, 'delete_specs_transient' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
* Delete the specs transient.
|
||||
*/
|
||||
public static function delete_specs_transient() {
|
||||
MarketingRecommendationsDataSourcePoller::get_instance()->delete_specs_transient();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get specs or fetch remotely if they don't exist.
|
||||
*/
|
||||
public static function get_specs() {
|
||||
if ( 'no' === get_option( 'woocommerce_show_marketplace_suggestions', 'yes' ) ) {
|
||||
return DefaultMarketingRecommendations::get_all();
|
||||
}
|
||||
$specs = MarketingRecommendationsDataSourcePoller::get_instance()->get_specs_from_data_sources();
|
||||
|
||||
// Fetch specs if they don't yet exist.
|
||||
if ( ! is_array( $specs ) || 0 === count( $specs ) ) {
|
||||
return DefaultMarketingRecommendations::get_all();
|
||||
}
|
||||
|
||||
return $specs;
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Load recommended plugins from Woo.com
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_recommended_plugins(): array {
|
||||
$specs = self::get_specs();
|
||||
$result = array();
|
||||
|
||||
foreach ( $specs as $spec ) {
|
||||
$result[] = self::object_to_array( $spec );
|
||||
}
|
||||
|
||||
return $result;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return only the recommended marketing channels from Woo.com.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_recommended_marketing_channels(): array {
|
||||
return array_filter(
|
||||
self::get_recommended_plugins(),
|
||||
function ( array $plugin_data ) {
|
||||
return self::is_marketing_channel_plugin( $plugin_data );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return all recommended marketing extensions EXCEPT the marketing channels from Woo.com.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public static function get_recommended_marketing_extensions_excluding_channels(): array {
|
||||
return array_filter(
|
||||
self::get_recommended_plugins(),
|
||||
function ( array $plugin_data ) {
|
||||
return self::is_marketing_plugin( $plugin_data ) && ! self::is_marketing_channel_plugin( $plugin_data );
|
||||
}
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a plugin is a marketing extension.
|
||||
*
|
||||
* @param array $plugin_data The plugin properties returned by the API.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected static function is_marketing_plugin( array $plugin_data ): bool {
|
||||
$categories = $plugin_data['categories'] ?? array();
|
||||
|
||||
return in_array( self::MARKETING_EXTENSION_CATEGORY_SLUG, $categories, true );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns whether a plugin is a marketing channel.
|
||||
*
|
||||
* @param array $plugin_data The plugin properties returned by the API.
|
||||
*
|
||||
* @return bool
|
||||
*/
|
||||
protected static function is_marketing_channel_plugin( array $plugin_data ): bool {
|
||||
if ( ! self::is_marketing_plugin( $plugin_data ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$subcategories = $plugin_data['subcategories'] ?? array();
|
||||
foreach ( $subcategories as $subcategory ) {
|
||||
if ( isset( $subcategory['slug'] ) && self::MARKETING_CHANNEL_SUBCATEGORY_SLUG === $subcategory['slug'] ) {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Convert an object to an array.
|
||||
* This is used to convert the specs to an array so that they can be returned by the API.
|
||||
*
|
||||
* @param mixed $obj Object to convert.
|
||||
* @return array
|
||||
*/
|
||||
protected static function object_to_array( $obj ) {
|
||||
if ( is_object( $obj ) ) {
|
||||
$obj = (array) $obj;
|
||||
}
|
||||
if ( is_array( $obj ) ) {
|
||||
$new = array();
|
||||
foreach ( $obj as $key => $val ) {
|
||||
$new[ $key ] = self::object_to_array( $val );
|
||||
}
|
||||
} else {
|
||||
$new = $obj;
|
||||
}
|
||||
return $new;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,46 @@
|
||||
<?php
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\Features\MarketingRecommendations;
|
||||
|
||||
use Automattic\WooCommerce\Admin\DataSourcePoller;
|
||||
|
||||
/**
|
||||
* Specs data source poller class for marketing recommendations.
|
||||
*/
|
||||
class MarketingRecommendationsDataSourcePoller extends DataSourcePoller {
|
||||
|
||||
/**
|
||||
* Data Source Poller ID.
|
||||
*/
|
||||
const ID = 'marketing_recommendations';
|
||||
|
||||
/**
|
||||
* Default data sources array.
|
||||
*/
|
||||
const DATA_SOURCES = array(
|
||||
'https://woocommerce.com/wp-json/wccom/marketing-tab/1.3/recommendations.json',
|
||||
);
|
||||
|
||||
/**
|
||||
* Class instance.
|
||||
*
|
||||
* @var Analytics instance
|
||||
*/
|
||||
protected static $instance = null;
|
||||
|
||||
/**
|
||||
* Get class instance.
|
||||
*/
|
||||
public static function get_instance() {
|
||||
if ( ! self::$instance ) {
|
||||
self::$instance = new self(
|
||||
self::ID,
|
||||
self::DATA_SOURCES,
|
||||
array(
|
||||
'spec_key' => 'product',
|
||||
)
|
||||
);
|
||||
}
|
||||
return self::$instance;
|
||||
}
|
||||
}
|
||||
@@ -25,7 +25,7 @@ class CustomizeStore extends Task {
|
||||
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' ) );
|
||||
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.
|
||||
|
||||
@@ -88,15 +88,8 @@ class WooCommercePayments extends Task {
|
||||
* @return string
|
||||
*/
|
||||
public function get_additional_info() {
|
||||
if ( WCPayPromotionInit::is_woopay_eligible() ) {
|
||||
return __(
|
||||
'By using WooPayments you agree to be bound by our <a href="https://wordpress.com/tos/" target="_blank">Terms of Service</a> (including WooPay <a href="https://wordpress.com/tos/#more-woopay-specifically" target="_blank">merchant terms</a>) and acknowledge that you have read our <a href="https://automattic.com/privacy/" target="_blank">Privacy Policy</a>',
|
||||
'woocommerce'
|
||||
);
|
||||
}
|
||||
|
||||
return __(
|
||||
'By using WooPayments you agree to be bound by our <a href="https://wordpress.com/tos/" target="_blank">Terms of Service</a> and acknowledge that you have read our <a href="https://automattic.com/privacy/" target="_blank">Privacy Policy</a>',
|
||||
'Accept credit/debit cards and other popular payment methods with no setup or monthly fees — and manage payments right from your store dashboard.',
|
||||
'woocommerce'
|
||||
);
|
||||
}
|
||||
|
||||
@@ -95,6 +95,19 @@ class DefaultPaymentGateways {
|
||||
'AU',
|
||||
),
|
||||
),
|
||||
array(
|
||||
'id' => 'airwallex_main',
|
||||
'title' => __( 'Airwallex Payments', 'woocommerce' ),
|
||||
'content' => __( 'Boost international sales and save on FX fees. Accept 60+ local payment methods including Apple Pay and Google Pay.', 'woocommerce' ),
|
||||
'image' => WC_ADMIN_IMAGES_FOLDER_URL . '/onboarding/airwallex.png',
|
||||
'image_72x72' => WC_ADMIN_IMAGES_FOLDER_URL . '/payment_methods/72x72/airwallex.png',
|
||||
'plugins' => array( 'airwallex-online-payments-gateway' ),
|
||||
'is_visible' => array(
|
||||
self::get_rules_for_countries( array( 'GB', 'AT', 'BE', 'EE', 'FR', 'DE', 'GR', 'IE', 'IT', 'NL', 'PL', 'PT', 'AU', 'NZ', 'HK', 'SG', 'CN' ) ),
|
||||
),
|
||||
'category_other' => array( 'GB', 'AT', 'BE', 'EE', 'FR', 'DE', 'GR', 'IE', 'IT', 'NL', 'PL', 'PT', 'AU', 'NZ', 'HK', 'SG', 'CN' ),
|
||||
'category_additional' => array(),
|
||||
),
|
||||
array(
|
||||
'id' => 'amazon_payments_advanced',
|
||||
'title' => __( 'Amazon Pay', 'woocommerce' ),
|
||||
@@ -177,23 +190,8 @@ class DefaultPaymentGateways {
|
||||
'image' => WC_ADMIN_IMAGES_FOLDER_URL . '/onboarding/eway.png',
|
||||
'image_72x72' => WC_ADMIN_IMAGES_FOLDER_URL . '/payment_methods/72x72/eway.png',
|
||||
'plugins' => array( 'woocommerce-gateway-eway' ),
|
||||
'is_visible' => array(
|
||||
self::get_rules_for_countries(
|
||||
array(
|
||||
'NZ',
|
||||
'HK',
|
||||
'SG',
|
||||
'AU',
|
||||
)
|
||||
),
|
||||
self::get_rules_for_cbd( false ),
|
||||
),
|
||||
'category_other' => array(
|
||||
'NZ',
|
||||
'HK',
|
||||
'SG',
|
||||
'AU',
|
||||
),
|
||||
'is_visible' => false,
|
||||
'category_other' => array(),
|
||||
'category_additional' => array(),
|
||||
),
|
||||
array(
|
||||
@@ -778,12 +776,12 @@ class DefaultPaymentGateways {
|
||||
'operands' => (object) array(
|
||||
(object) array(
|
||||
'type' => 'not',
|
||||
'operand' => [
|
||||
'operand' => array(
|
||||
(object) array(
|
||||
'type' => 'plugins_activated',
|
||||
'plugins' => [ 'woocommerce-admin' ],
|
||||
'plugins' => array( 'woocommerce-admin' ),
|
||||
),
|
||||
],
|
||||
),
|
||||
),
|
||||
(object) array(
|
||||
'type' => 'plugin_version',
|
||||
@@ -871,21 +869,9 @@ class DefaultPaymentGateways {
|
||||
'image' => WC_ADMIN_IMAGES_FOLDER_URL . '/onboarding/zipco.png',
|
||||
'image_72x72' => WC_ADMIN_IMAGES_FOLDER_URL . '/payment_methods/72x72/zipco.png',
|
||||
'plugins' => array( 'zipmoney-payments-woocommerce' ),
|
||||
'is_visible' => array(
|
||||
self::get_rules_for_countries(
|
||||
array(
|
||||
'US',
|
||||
'NZ',
|
||||
'AU',
|
||||
)
|
||||
),
|
||||
),
|
||||
'is_visible' => false,
|
||||
'category_other' => array(),
|
||||
'category_additional' => array(
|
||||
'US',
|
||||
'NZ',
|
||||
'AU',
|
||||
),
|
||||
'category_additional' => array(),
|
||||
),
|
||||
);
|
||||
|
||||
@@ -980,9 +966,9 @@ class DefaultPaymentGateways {
|
||||
),
|
||||
),
|
||||
'option_name' => 'woocommerce_onboarding_profile',
|
||||
'operation' => 'contains',
|
||||
'value' => 'no_im_selling_offline',
|
||||
'default' => array(),
|
||||
'operation' => 'in',
|
||||
'value' => array( 'no_im_selling_offline', 'im_selling_both_online_and_offline' ),
|
||||
'default' => '',
|
||||
);
|
||||
}
|
||||
|
||||
@@ -1026,7 +1012,7 @@ class DefaultPaymentGateways {
|
||||
*/
|
||||
private static function get_recommendation_priority( $gateway_id, $country_code ) {
|
||||
$recommendation_priority_map = array(
|
||||
'US' => [
|
||||
'US' => array(
|
||||
'woocommerce_payments',
|
||||
'stripe',
|
||||
'ppcp-gateway',
|
||||
@@ -1035,9 +1021,8 @@ class DefaultPaymentGateways {
|
||||
'affirm',
|
||||
'afterpay',
|
||||
'klarna_payments',
|
||||
'zipmoney',
|
||||
],
|
||||
'CA' => [
|
||||
),
|
||||
'CA' => array(
|
||||
'woocommerce_payments',
|
||||
'stripe',
|
||||
'ppcp-gateway',
|
||||
@@ -1045,42 +1030,44 @@ class DefaultPaymentGateways {
|
||||
'affirm',
|
||||
'afterpay',
|
||||
'klarna_payments',
|
||||
],
|
||||
'AT' => [
|
||||
),
|
||||
'AT' => array(
|
||||
'woocommerce_payments',
|
||||
'stripe',
|
||||
'ppcp-gateway',
|
||||
'airwallex_main',
|
||||
'mollie_wc_gateway_banktransfer',
|
||||
'klarna_payments',
|
||||
'amazon_payments_advanced',
|
||||
),
|
||||
'BE' => array(
|
||||
'woocommerce_payments',
|
||||
'stripe',
|
||||
'ppcp-gateway',
|
||||
'airwallex_main',
|
||||
'mollie_wc_gateway_banktransfer',
|
||||
'klarna_payments',
|
||||
'amazon_payments_advanced',
|
||||
),
|
||||
'BG' => array( 'stripe', 'ppcp-gateway' ),
|
||||
'HR' => array( 'ppcp-gateway' ),
|
||||
'CH' => array(
|
||||
'woocommerce_payments',
|
||||
'stripe',
|
||||
'ppcp-gateway',
|
||||
'mollie_wc_gateway_banktransfer',
|
||||
'klarna_payments',
|
||||
'amazon_payments_advanced',
|
||||
],
|
||||
'BE' => [
|
||||
'woocommerce_payments',
|
||||
'stripe',
|
||||
'ppcp-gateway',
|
||||
'mollie_wc_gateway_banktransfer',
|
||||
'klarna_payments',
|
||||
'amazon_payments_advanced',
|
||||
],
|
||||
'BG' => [ 'stripe', 'ppcp-gateway' ],
|
||||
'HR' => [ 'ppcp-gateway' ],
|
||||
'CH' => [
|
||||
'woocommerce_payments',
|
||||
'stripe',
|
||||
'ppcp-gateway',
|
||||
'mollie_wc_gateway_banktransfer',
|
||||
'klarna_payments',
|
||||
],
|
||||
'CY' => [ 'stripe', 'ppcp-gateway', 'amazon_payments_advanced' ],
|
||||
'CZ' => [ 'stripe', 'ppcp-gateway' ],
|
||||
'DK' => [
|
||||
),
|
||||
'CY' => array( 'stripe', 'ppcp-gateway', 'amazon_payments_advanced' ),
|
||||
'CZ' => array( 'stripe', 'ppcp-gateway' ),
|
||||
'DK' => array(
|
||||
'stripe',
|
||||
'ppcp-gateway',
|
||||
'klarna_payments',
|
||||
'amazon_payments_advanced',
|
||||
],
|
||||
'EE' => [ 'stripe', 'ppcp-gateway' ],
|
||||
'ES' => [
|
||||
),
|
||||
'EE' => array( 'stripe', 'ppcp-gateway', 'airwallex_main' ),
|
||||
'ES' => array(
|
||||
'woocommerce_payments',
|
||||
'stripe',
|
||||
'ppcp-gateway',
|
||||
@@ -1088,153 +1075,158 @@ class DefaultPaymentGateways {
|
||||
'square_credit_card',
|
||||
'klarna_payments',
|
||||
'amazon_payments_advanced',
|
||||
],
|
||||
'FI' => [
|
||||
),
|
||||
'FI' => array(
|
||||
'stripe',
|
||||
'ppcp-gateway',
|
||||
'mollie_wc_gateway_banktransfer',
|
||||
'kco',
|
||||
'klarna_payments',
|
||||
],
|
||||
'FR' => [
|
||||
),
|
||||
'FR' => array(
|
||||
'woocommerce_payments',
|
||||
'stripe',
|
||||
'ppcp-gateway',
|
||||
'airwallex_main',
|
||||
'mollie_wc_gateway_banktransfer',
|
||||
'square_credit_card',
|
||||
'klarna_payments',
|
||||
'amazon_payments_advanced',
|
||||
],
|
||||
'DE' => [
|
||||
),
|
||||
'DE' => array(
|
||||
'woocommerce_payments',
|
||||
'stripe',
|
||||
'ppcp-gateway',
|
||||
'airwallex_main',
|
||||
'mollie_wc_gateway_banktransfer',
|
||||
'klarna_payments',
|
||||
'amazon_payments_advanced',
|
||||
],
|
||||
'GB' => [
|
||||
),
|
||||
'GB' => array(
|
||||
'woocommerce_payments',
|
||||
'stripe',
|
||||
'ppcp-gateway',
|
||||
'airwallex_main',
|
||||
'mollie_wc_gateway_banktransfer',
|
||||
'square_credit_card',
|
||||
'klarna_payments',
|
||||
'amazon_payments_advanced',
|
||||
],
|
||||
'GR' => [ 'stripe', 'ppcp-gateway' ],
|
||||
'HU' => [ 'stripe', 'ppcp-gateway', 'amazon_payments_advanced' ],
|
||||
'IE' => [
|
||||
),
|
||||
'GR' => array( 'stripe', 'ppcp-gateway' ),
|
||||
'HU' => array( 'stripe', 'ppcp-gateway', 'amazon_payments_advanced' ),
|
||||
'IE' => array(
|
||||
'woocommerce_payments',
|
||||
'stripe',
|
||||
'ppcp-gateway',
|
||||
'airwallex_main',
|
||||
'square_credit_card',
|
||||
'amazon_payments_advanced',
|
||||
],
|
||||
'IT' => [
|
||||
),
|
||||
'IT' => array(
|
||||
'woocommerce_payments',
|
||||
'stripe',
|
||||
'ppcp-gateway',
|
||||
'airwallex_main',
|
||||
'mollie_wc_gateway_banktransfer',
|
||||
'klarna_payments',
|
||||
'amazon_payments_advanced',
|
||||
],
|
||||
'LV' => [ 'stripe', 'ppcp-gateway' ],
|
||||
'LT' => [ 'stripe', 'ppcp-gateway' ],
|
||||
'LU' => [ 'stripe', 'ppcp-gateway', 'amazon_payments_advanced' ],
|
||||
'MT' => [ 'stripe', 'ppcp-gateway' ],
|
||||
'NL' => [
|
||||
),
|
||||
'LV' => array( 'stripe', 'ppcp-gateway' ),
|
||||
'LT' => array( 'stripe', 'ppcp-gateway' ),
|
||||
'LU' => array( 'stripe', 'ppcp-gateway', 'amazon_payments_advanced' ),
|
||||
'MT' => array( 'stripe', 'ppcp-gateway' ),
|
||||
'NL' => array(
|
||||
'woocommerce_payments',
|
||||
'stripe',
|
||||
'ppcp-gateway',
|
||||
'airwallex_main',
|
||||
'mollie_wc_gateway_banktransfer',
|
||||
'klarna_payments',
|
||||
'amazon_payments_advanced',
|
||||
],
|
||||
'NO' => [ 'stripe', 'ppcp-gateway', 'kco', 'klarna_payments' ],
|
||||
'PL' => [
|
||||
),
|
||||
'NO' => array( 'stripe', 'ppcp-gateway', 'kco', 'klarna_payments' ),
|
||||
'PL' => array(
|
||||
'woocommerce_payments',
|
||||
'stripe',
|
||||
'ppcp-gateway',
|
||||
'airwallex_main',
|
||||
'mollie_wc_gateway_banktransfer',
|
||||
'klarna_payments',
|
||||
],
|
||||
'PT' => [
|
||||
),
|
||||
'PT' => array(
|
||||
'woocommerce_payments',
|
||||
'stripe',
|
||||
'ppcp-gateway',
|
||||
'amazon_payments_advanced',
|
||||
],
|
||||
'RO' => [ 'stripe', 'ppcp-gateway' ],
|
||||
'SK' => [ 'stripe', 'ppcp-gateway' ],
|
||||
'SL' => [ 'stripe', 'ppcp-gateway', 'amazon_payments_advanced' ],
|
||||
'SE' => [
|
||||
),
|
||||
'RO' => array( 'stripe', 'ppcp-gateway' ),
|
||||
'SK' => array( 'stripe', 'ppcp-gateway' ),
|
||||
'SL' => array( 'stripe', 'ppcp-gateway', 'amazon_payments_advanced' ),
|
||||
'SE' => array(
|
||||
'stripe',
|
||||
'ppcp-gateway',
|
||||
'kco',
|
||||
'klarna_payments',
|
||||
'amazon_payments_advanced',
|
||||
],
|
||||
'MX' => [
|
||||
),
|
||||
'MX' => array(
|
||||
'stripe',
|
||||
'woo-mercado-pago-custom',
|
||||
'ppcp-gateway',
|
||||
'klarna_payments',
|
||||
],
|
||||
'BR' => [ 'stripe', 'woo-mercado-pago-custom', 'ppcp-gateway' ],
|
||||
'AR' => [ 'woo-mercado-pago-custom', 'ppcp-gateway' ],
|
||||
'BO' => [],
|
||||
'CL' => [ 'woo-mercado-pago-custom', 'ppcp-gateway' ],
|
||||
'CO' => [ 'woo-mercado-pago-custom', 'ppcp-gateway' ],
|
||||
'EC' => [ 'woo-mercado-pago-custom', 'ppcp-gateway' ],
|
||||
'FK' => [],
|
||||
'GF' => [],
|
||||
'GY' => [],
|
||||
'PY' => [],
|
||||
'PE' => [ 'woo-mercado-pago-custom', 'ppcp-gateway' ],
|
||||
'SR' => [],
|
||||
'UY' => [ 'woo-mercado-pago-custom', 'ppcp-gateway' ],
|
||||
'VE' => [ 'ppcp-gateway' ],
|
||||
'AU' => [
|
||||
),
|
||||
'BR' => array( 'stripe', 'woo-mercado-pago-custom', 'ppcp-gateway' ),
|
||||
'AR' => array( 'woo-mercado-pago-custom', 'ppcp-gateway' ),
|
||||
'BO' => array(),
|
||||
'CL' => array( 'woo-mercado-pago-custom', 'ppcp-gateway' ),
|
||||
'CO' => array( 'woo-mercado-pago-custom', 'ppcp-gateway' ),
|
||||
'EC' => array( 'woo-mercado-pago-custom', 'ppcp-gateway' ),
|
||||
'FK' => array(),
|
||||
'GF' => array(),
|
||||
'GY' => array(),
|
||||
'PY' => array(),
|
||||
'PE' => array( 'woo-mercado-pago-custom', 'ppcp-gateway' ),
|
||||
'SR' => array(),
|
||||
'UY' => array( 'woo-mercado-pago-custom', 'ppcp-gateway' ),
|
||||
'VE' => array( 'ppcp-gateway' ),
|
||||
'AU' => array(
|
||||
'woocommerce_payments',
|
||||
'stripe',
|
||||
'airwallex_main',
|
||||
'ppcp-gateway',
|
||||
'square_credit_card',
|
||||
'eway',
|
||||
'afterpay',
|
||||
'klarna_payments',
|
||||
'zipmoney',
|
||||
],
|
||||
'NZ' => [
|
||||
),
|
||||
'NZ' => array(
|
||||
'woocommerce_payments',
|
||||
'stripe',
|
||||
'airwallex_main',
|
||||
'ppcp-gateway',
|
||||
'eway',
|
||||
'klarna_payments',
|
||||
'zipmoney',
|
||||
],
|
||||
'HK' => [
|
||||
),
|
||||
'HK' => array(
|
||||
'woocommerce_payments',
|
||||
'stripe',
|
||||
'airwallex_main',
|
||||
'ppcp-gateway',
|
||||
'eway',
|
||||
'payoneer-checkout',
|
||||
],
|
||||
'JP' => [
|
||||
),
|
||||
'JP' => array(
|
||||
'stripe',
|
||||
'ppcp-gateway',
|
||||
'square_credit_card',
|
||||
'amazon_payments_advanced',
|
||||
],
|
||||
'SG' => [ 'woocommerce_payments', 'stripe', 'ppcp-gateway', 'eway' ],
|
||||
'CN' => [ 'ppcp-gateway', 'payoneer-checkout' ],
|
||||
'FJ' => [],
|
||||
'GU' => [],
|
||||
'ID' => [ 'stripe', 'ppcp-gateway' ],
|
||||
'IN' => [ 'stripe', 'razorpay', 'payubiz', 'ppcp-gateway' ],
|
||||
'ZA' => [ 'payfast', 'paystack' ],
|
||||
'NG' => [ 'paystack' ],
|
||||
'GH' => [ 'paystack' ],
|
||||
),
|
||||
'SG' => array( 'woocommerce_payments', 'stripe', 'airwallex_main', 'ppcp-gateway' ),
|
||||
'CN' => array( 'airwallex_main', 'ppcp-gateway', 'payoneer-checkout' ),
|
||||
'FJ' => array(),
|
||||
'GU' => array(),
|
||||
'ID' => array( 'stripe', 'ppcp-gateway' ),
|
||||
'IN' => array( 'stripe', 'razorpay', 'payubiz', 'ppcp-gateway' ),
|
||||
'ZA' => array( 'payfast', 'paystack' ),
|
||||
'NG' => array( 'paystack' ),
|
||||
'GH' => array( 'paystack' ),
|
||||
);
|
||||
|
||||
// If the country code is not in the list, return default priority.
|
||||
|
||||
@@ -31,11 +31,13 @@ class BlockRegistry {
|
||||
'woocommerce/product-pricing-field',
|
||||
'woocommerce/product-section',
|
||||
'woocommerce/product-section-description',
|
||||
'woocommerce/product-details-section-description',
|
||||
'woocommerce/product-tab',
|
||||
'woocommerce/product-toggle-field',
|
||||
'woocommerce/product-taxonomy-field',
|
||||
'woocommerce/product-text-field',
|
||||
'woocommerce/product-number-field',
|
||||
'woocommerce/product-linked-list-field',
|
||||
);
|
||||
|
||||
/**
|
||||
|
||||
@@ -6,12 +6,13 @@
|
||||
namespace Automattic\WooCommerce\Admin\Features\ProductBlockEditor;
|
||||
|
||||
use Automattic\WooCommerce\Admin\Features\Features;
|
||||
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\Admin\PageController;
|
||||
use Automattic\WooCommerce\Internal\Admin\BlockTemplateRegistry\BlockTemplateRegistry;
|
||||
use Automattic\WooCommerce\Internal\Admin\BlockTemplates\Block;
|
||||
use Automattic\WooCommerce\Internal\Admin\BlockTemplates\BlockTemplateLogger;
|
||||
|
||||
use WP_Block_Editor_Context;
|
||||
|
||||
/**
|
||||
@@ -24,11 +25,18 @@ class Init {
|
||||
const EDITOR_CONTEXT_NAME = 'woocommerce/edit-product';
|
||||
|
||||
/**
|
||||
* Supported post types.
|
||||
* Supported product types.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $supported_post_types = array( 'simple' );
|
||||
private $supported_product_types = array( 'simple' );
|
||||
|
||||
/**
|
||||
* Registered product templates.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $product_templates = array();
|
||||
|
||||
/**
|
||||
* Redirection controller.
|
||||
@@ -42,18 +50,18 @@ class Init {
|
||||
*/
|
||||
public function __construct() {
|
||||
if ( Features::is_enabled( 'product-variation-management' ) ) {
|
||||
array_push( $this->supported_post_types, 'variable' );
|
||||
array_push( $this->supported_product_types, 'variable' );
|
||||
}
|
||||
|
||||
if ( Features::is_enabled( 'product-external-affiliate' ) ) {
|
||||
array_push( $this->supported_post_types, 'external' );
|
||||
array_push( $this->supported_product_types, 'external' );
|
||||
}
|
||||
|
||||
if ( Features::is_enabled( 'product-grouped' ) ) {
|
||||
array_push( $this->supported_post_types, 'grouped' );
|
||||
array_push( $this->supported_product_types, 'grouped' );
|
||||
}
|
||||
|
||||
$this->redirection_controller = new RedirectionController( $this->supported_post_types );
|
||||
$this->redirection_controller = new RedirectionController();
|
||||
|
||||
if ( \Automattic\WooCommerce\Utilities\FeaturesUtil::feature_is_enabled( 'product_block_editor' ) ) {
|
||||
if ( ! Features::is_enabled( 'new-product-management-experience' ) ) {
|
||||
@@ -67,14 +75,15 @@ 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' ) );
|
||||
|
||||
// Make sure the block registry is initialized so that core blocks are registered.
|
||||
BlockRegistry::get_instance();
|
||||
|
||||
$tracks = new Tracks();
|
||||
$tracks->init();
|
||||
|
||||
// Make sure the block template logger is initialized before any templates are created.
|
||||
BlockTemplateLogger::get_instance();
|
||||
$this->register_product_templates();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -86,7 +95,6 @@ class Init {
|
||||
return;
|
||||
}
|
||||
|
||||
$this->register_product_editor_templates();
|
||||
$editor_settings = $this->get_product_editor_settings();
|
||||
|
||||
$script_handle = 'wc-admin-edit-product';
|
||||
@@ -181,6 +189,7 @@ class Init {
|
||||
'variable_product_block_tour_shown',
|
||||
'local_attributes_notice_dismissed_ids',
|
||||
'variable_items_without_price_notice_dismissed',
|
||||
'product_advice_card_dismissed',
|
||||
)
|
||||
);
|
||||
}
|
||||
@@ -210,22 +219,11 @@ class Init {
|
||||
* Get the product editor settings.
|
||||
*/
|
||||
private function get_product_editor_settings() {
|
||||
$editor_settings = array();
|
||||
|
||||
$template_registry = wc_get_container()->get( BlockTemplateRegistry::class );
|
||||
$block_template_logger = BlockTemplateLogger::get_instance();
|
||||
|
||||
$block_template_logger->log_template_events_to_file( 'simple-product' );
|
||||
$block_template_logger->log_template_events_to_file( 'product-variation' );
|
||||
|
||||
$editor_settings['templates'] = array(
|
||||
'product' => $template_registry->get_registered( 'simple-product' )->get_formatted_template(),
|
||||
'product_variation' => $template_registry->get_registered( 'product-variation' )->get_formatted_template(),
|
||||
);
|
||||
|
||||
$editor_settings['templateEvents'] = array(
|
||||
'product' => $block_template_logger->get_formatted_template_events( 'simple-product' ),
|
||||
'product_variation' => $block_template_logger->get_formatted_template_events( 'product-variation' ),
|
||||
$editor_settings['productTemplates'] = array_map(
|
||||
function ( $product_template ) {
|
||||
return $product_template->to_json();
|
||||
},
|
||||
$this->product_templates
|
||||
);
|
||||
|
||||
$block_editor_context = new WP_Block_Editor_Context( array( 'name' => self::EDITOR_CONTEXT_NAME ) );
|
||||
@@ -234,12 +232,151 @@ class Init {
|
||||
}
|
||||
|
||||
/**
|
||||
* Register product editor templates.
|
||||
* Get default product templates.
|
||||
*
|
||||
* @return array The default templates.
|
||||
*/
|
||||
private function register_product_editor_templates() {
|
||||
$template_registry = wc_get_container()->get( BlockTemplateRegistry::class );
|
||||
private function get_default_product_templates() {
|
||||
$templates = array();
|
||||
$templates[] = new ProductTemplate(
|
||||
array(
|
||||
'id' => 'standard-product-template',
|
||||
'title' => __( 'Standard product', 'woocommerce' ),
|
||||
'description' => __( 'A single physical or virtual product, e.g. a t-shirt or an eBook.', 'woocommerce' ),
|
||||
'order' => 10,
|
||||
'icon' => 'shipping',
|
||||
'layout_template_id' => 'simple-product',
|
||||
'product_data' => array(
|
||||
'type' => 'simple',
|
||||
),
|
||||
)
|
||||
);
|
||||
$templates[] = new ProductTemplate(
|
||||
array(
|
||||
'id' => 'grouped-product-template',
|
||||
'title' => __( 'Grouped product', 'woocommerce' ),
|
||||
'description' => __( 'A set of products that go well together, e.g. camera kit.', 'woocommerce' ),
|
||||
'order' => 20,
|
||||
'icon' => 'group',
|
||||
'layout_template_id' => 'simple-product',
|
||||
'product_data' => array(
|
||||
'type' => 'grouped',
|
||||
),
|
||||
)
|
||||
);
|
||||
$templates[] = new ProductTemplate(
|
||||
array(
|
||||
'id' => 'affiliate-product-template',
|
||||
'title' => __( 'Affiliate product', 'woocommerce' ),
|
||||
'description' => __( 'A link to a product sold on a different website, e.g. brand collab.', 'woocommerce' ),
|
||||
'order' => 30,
|
||||
'icon' => 'link',
|
||||
'layout_template_id' => 'simple-product',
|
||||
'product_data' => array(
|
||||
'type' => 'external',
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
$template_registry->register( new SimpleProductTemplate() );
|
||||
$template_registry->register( new ProductVariationTemplate() );
|
||||
return $templates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Create default product template by custom product type if it does not have a
|
||||
* template associated yet.
|
||||
*
|
||||
* @param array $templates The registered product templates.
|
||||
* @return array The new templates.
|
||||
*/
|
||||
private function create_default_product_template_by_custom_product_type( array $templates ) {
|
||||
// Getting the product types registered via the classic editor.
|
||||
$registered_product_types = wc_get_product_types();
|
||||
|
||||
$custom_product_types = array_filter(
|
||||
$registered_product_types,
|
||||
function ( $product_type ) {
|
||||
return ! in_array( $product_type, $this->supported_product_types, true );
|
||||
},
|
||||
ARRAY_FILTER_USE_KEY
|
||||
);
|
||||
|
||||
$templates_with_product_type = array_filter(
|
||||
$templates,
|
||||
function ( $template ) {
|
||||
$product_data = $template->get_product_data();
|
||||
return ! is_null( $product_data ) && array_key_exists( 'type', $product_data );
|
||||
}
|
||||
);
|
||||
|
||||
$custom_product_types_on_templates = array_map(
|
||||
function ( $template ) {
|
||||
$product_data = $template->get_product_data();
|
||||
return $product_data['type'];
|
||||
},
|
||||
$templates_with_product_type
|
||||
);
|
||||
|
||||
foreach ( $custom_product_types as $product_type => $title ) {
|
||||
if ( in_array( $product_type, $custom_product_types_on_templates, true ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$templates[] = new ProductTemplate(
|
||||
array(
|
||||
'id' => $product_type . '-product-template',
|
||||
'title' => $title,
|
||||
'product_data' => array(
|
||||
'type' => $product_type,
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
return $templates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Register layout templates.
|
||||
*/
|
||||
public function register_layout_templates() {
|
||||
$layout_template_registry = wc_get_container()->get( LayoutTemplateRegistry::class );
|
||||
|
||||
if ( ! $layout_template_registry->is_registered( 'simple-product' ) ) {
|
||||
$layout_template_registry->register(
|
||||
'simple-product',
|
||||
'product-form',
|
||||
SimpleProductTemplate::class
|
||||
);
|
||||
}
|
||||
|
||||
if ( ! $layout_template_registry->is_registered( 'product-variation' ) ) {
|
||||
$layout_template_registry->register(
|
||||
'product-variation',
|
||||
'product-form',
|
||||
ProductVariationTemplate::class
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Register product templates.
|
||||
*/
|
||||
public function register_product_templates() {
|
||||
/**
|
||||
* Allows for new product template registration.
|
||||
*
|
||||
* @since 8.5.0
|
||||
*/
|
||||
$this->product_templates = apply_filters( 'woocommerce_product_editor_product_templates', $this->get_default_product_templates() );
|
||||
$this->product_templates = $this->create_default_product_template_by_custom_product_type( $this->product_templates );
|
||||
|
||||
usort(
|
||||
$this->product_templates,
|
||||
function ( $a, $b ) {
|
||||
return $a->get_order() - $b->get_order();
|
||||
}
|
||||
);
|
||||
|
||||
$this->redirection_controller->set_product_templates( $this->product_templates );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,208 @@
|
||||
<?php
|
||||
/**
|
||||
* WooCommerce Product Block Editor
|
||||
*/
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\Features\ProductBlockEditor;
|
||||
|
||||
/**
|
||||
* The Product Template that represents the relation between the Product and
|
||||
* the LayoutTemplate (ProductFormTemplateInterface)
|
||||
*
|
||||
* @see ProductFormTemplateInterface
|
||||
*/
|
||||
class ProductTemplate {
|
||||
/**
|
||||
* The template id.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $id;
|
||||
|
||||
/**
|
||||
* The template title.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $title;
|
||||
|
||||
/**
|
||||
* The product data.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $product_data;
|
||||
|
||||
/**
|
||||
* The template order.
|
||||
*
|
||||
* @var Integer
|
||||
*/
|
||||
private $order = 999;
|
||||
|
||||
/**
|
||||
* The layout template id.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $layout_template_id = null;
|
||||
|
||||
/**
|
||||
* The template description.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $description = null;
|
||||
|
||||
/**
|
||||
* The template icon.
|
||||
*
|
||||
* @var string
|
||||
*/
|
||||
private $icon = null;
|
||||
|
||||
/**
|
||||
* ProductTemplate constructor
|
||||
*
|
||||
* @param array $data The data.
|
||||
*/
|
||||
public function __construct( array $data ) {
|
||||
$this->id = $data['id'];
|
||||
$this->title = $data['title'];
|
||||
$this->product_data = $data['product_data'];
|
||||
|
||||
if ( isset( $data['order'] ) ) {
|
||||
$this->order = $data['order'];
|
||||
}
|
||||
|
||||
if ( isset( $data['layout_template_id'] ) ) {
|
||||
$this->layout_template_id = $data['layout_template_id'];
|
||||
}
|
||||
|
||||
if ( isset( $data['description'] ) ) {
|
||||
$this->description = $data['description'];
|
||||
}
|
||||
|
||||
if ( isset( $data['icon'] ) ) {
|
||||
$this->icon = $data['icon'];
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the template ID.
|
||||
*
|
||||
* @return string The ID.
|
||||
*/
|
||||
public function get_id() {
|
||||
return $this->id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the template title.
|
||||
*
|
||||
* @return string The title.
|
||||
*/
|
||||
public function get_title() {
|
||||
return $this->title;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the layout template ID.
|
||||
*
|
||||
* @return string The layout template ID.
|
||||
*/
|
||||
public function get_layout_template_id() {
|
||||
return $this->layout_template_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the layout template ID.
|
||||
*
|
||||
* @param string $layout_template_id The layout template ID.
|
||||
*/
|
||||
public function set_layout_template_id( string $layout_template_id ) {
|
||||
$this->layout_template_id = $layout_template_id;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the product data.
|
||||
*
|
||||
* @return array The product data.
|
||||
*/
|
||||
public function get_product_data() {
|
||||
return $this->product_data;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the template description.
|
||||
*
|
||||
* @return string The description.
|
||||
*/
|
||||
public function get_description() {
|
||||
return $this->description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the template description.
|
||||
*
|
||||
* @param string $description The template description.
|
||||
*/
|
||||
public function set_description( string $description ) {
|
||||
$this->description = $description;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the template icon.
|
||||
*
|
||||
* @return string The icon.
|
||||
*/
|
||||
public function get_icon() {
|
||||
return $this->icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the template icon.
|
||||
*
|
||||
* @see https://github.com/WordPress/gutenberg/tree/trunk/packages/icons.
|
||||
*
|
||||
* @param string $icon The icon name from the @wordpress/components or a url for an external image resource.
|
||||
*/
|
||||
public function set_icon( string $icon ) {
|
||||
$this->icon = $icon;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the template order.
|
||||
*
|
||||
* @return int The order.
|
||||
*/
|
||||
public function get_order() {
|
||||
return $this->order;
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the template order.
|
||||
*
|
||||
* @param int $order The template order.
|
||||
*/
|
||||
public function set_order( int $order ) {
|
||||
$this->order = $order;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the product template as JSON like.
|
||||
*
|
||||
* @return array The JSON.
|
||||
*/
|
||||
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(),
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -12,22 +12,17 @@ use Automattic\WooCommerce\Internal\Admin\WCAdminAssets;
|
||||
* Handle redirecting to the old or new editor based on features and support.
|
||||
*/
|
||||
class RedirectionController {
|
||||
|
||||
/**
|
||||
* Supported post types.
|
||||
* Registered product templates.
|
||||
*
|
||||
* @var array
|
||||
*/
|
||||
private $supported_post_types;
|
||||
private $product_templates = array();
|
||||
|
||||
/**
|
||||
* Set up the hooks used for redirection.
|
||||
*
|
||||
* @param array $supported_post_types Array of supported post types.
|
||||
*/
|
||||
public function __construct( $supported_post_types ) {
|
||||
$this->supported_post_types = $supported_post_types;
|
||||
|
||||
public function __construct() {
|
||||
if ( \Automattic\WooCommerce\Utilities\FeaturesUtil::feature_is_enabled( 'product_block_editor' ) ) {
|
||||
add_action( 'current_screen', array( $this, 'maybe_redirect_to_new_editor' ), 30, 0 );
|
||||
add_action( 'current_screen', array( $this, 'redirect_non_supported_product_types' ), 30, 0 );
|
||||
@@ -63,18 +58,53 @@ class RedirectionController {
|
||||
*/
|
||||
protected function is_product_supported( $product_id ): bool {
|
||||
$product = $product_id ? wc_get_product( $product_id ) : null;
|
||||
$digital_product = $product->is_downloadable() || $product->is_virtual();
|
||||
|
||||
if ( $product && in_array( $product->get_type(), $this->supported_post_types, true ) ) {
|
||||
if ( Features::is_enabled( 'product-virtual-downloadable' ) ) {
|
||||
if ( is_null( $product ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
$digital_product = $product->is_downloadable() || $product->is_virtual();
|
||||
$product_template_id = $product->get_meta( '_product_template_id' );
|
||||
|
||||
foreach ( $this->product_templates as $product_template ) {
|
||||
if ( is_null( $product_template->get_layout_template_id() ) ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
$product_data = $product_template->get_product_data();
|
||||
$product_data_type = $product_data['type'];
|
||||
// Treat a variable product as a simple product since there is not a product template
|
||||
// for variable products.
|
||||
$product_type = $product->get_type() === 'variable' ? 'simple' : $product->get_type();
|
||||
|
||||
if ( isset( $product_data_type ) && $product_data_type !== $product_type ) {
|
||||
continue;
|
||||
}
|
||||
|
||||
if ( isset( $product_template_id ) && $product_template_id === $product_template->get_id() ) {
|
||||
return true;
|
||||
}
|
||||
return ! $digital_product;
|
||||
|
||||
if ( isset( $product_data_type ) ) {
|
||||
if ( Features::is_enabled( 'product-virtual-downloadable' ) ) {
|
||||
return true;
|
||||
}
|
||||
return ! $digital_product;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if a product is supported by the new experience.
|
||||
*
|
||||
* @param array $product_templates The registered product teamplates.
|
||||
*/
|
||||
public function set_product_templates( array $product_templates ): void {
|
||||
$this->product_templates = $product_templates;
|
||||
}
|
||||
|
||||
/**
|
||||
* Redirects from old product form to the new product form if the
|
||||
* feature `product_block_editor` is enabled.
|
||||
|
||||
@@ -48,6 +48,13 @@ class MarketingCampaign {
|
||||
*/
|
||||
protected $cost;
|
||||
|
||||
/**
|
||||
* The sales of the marketing campaign with the currency.
|
||||
*
|
||||
* @var Price
|
||||
*/
|
||||
protected $sales;
|
||||
|
||||
/**
|
||||
* MarketingCampaign constructor.
|
||||
*
|
||||
@@ -56,13 +63,15 @@ class MarketingCampaign {
|
||||
* @param string $title The title of the marketing campaign.
|
||||
* @param string $manage_url The URL to the channel's campaign management page.
|
||||
* @param Price|null $cost The cost of the marketing campaign with the currency.
|
||||
* @param Price|null $sales The sales of the marketing campaign with the currency.
|
||||
*/
|
||||
public function __construct( string $id, MarketingCampaignType $type, string $title, string $manage_url, Price $cost = null ) {
|
||||
public function __construct( string $id, MarketingCampaignType $type, string $title, string $manage_url, Price $cost = null, Price $sales = null ) {
|
||||
$this->id = $id;
|
||||
$this->type = $type;
|
||||
$this->title = $title;
|
||||
$this->manage_url = $manage_url;
|
||||
$this->cost = $cost;
|
||||
$this->sales = $sales;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -109,4 +118,13 @@ class MarketingCampaign {
|
||||
public function get_cost(): ?Price {
|
||||
return $this->cost;
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the sales of the marketing campaign with the currency.
|
||||
*
|
||||
* @return Price|null
|
||||
*/
|
||||
public function get_sales(): ?Price {
|
||||
return $this->sales;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -20,7 +20,7 @@ class AsyncPluginsInstallLogger implements PluginsInstallLogger {
|
||||
* @param string $option_name option name.
|
||||
*/
|
||||
public function __construct( string $option_name ) {
|
||||
$this->option_name = $option_name;
|
||||
$this->option_name = $option_name;
|
||||
add_option(
|
||||
$this->option_name,
|
||||
array(
|
||||
@@ -129,6 +129,15 @@ class AsyncPluginsInstallLogger implements PluginsInstallLogger {
|
||||
$option['plugins'][ $plugin_name ]['status'] = 'failed';
|
||||
$option['status'] = 'failed';
|
||||
|
||||
wc_admin_record_tracks_event(
|
||||
'coreprofiler_store_extension_installed_and_activated',
|
||||
array(
|
||||
'success' => false,
|
||||
'extension' => $plugin_name,
|
||||
'error_message' => $error_message,
|
||||
)
|
||||
);
|
||||
|
||||
$this->update( $option );
|
||||
}
|
||||
|
||||
@@ -223,7 +232,18 @@ class AsyncPluginsInstallLogger implements PluginsInstallLogger {
|
||||
continue;
|
||||
}
|
||||
|
||||
$track_data[ 'install_time_' . $this->get_plugin_track_key( $plugin ) ] = $this->get_timeframe( $data['time'][ $plugin ] );
|
||||
$plugin_track_key = $this->get_plugin_track_key( $plugin );
|
||||
$install_time = $this->get_timeframe( $data['time'][ $plugin ] );
|
||||
$track_data[ 'install_time_' . $plugin_track_key ] = $install_time;
|
||||
|
||||
wc_admin_record_tracks_event(
|
||||
'coreprofiler_store_extension_installed_and_activated',
|
||||
array(
|
||||
'success' => true,
|
||||
'extension' => $plugin_track_key,
|
||||
'install_time' => $install_time,
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
wc_admin_record_tracks_event( 'coreprofiler_store_extensions_installed_and_activated', $track_data );
|
||||
|
||||
@@ -68,4 +68,4 @@ class ComparisonOperation {
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user