rebase from live enviornment
This commit is contained in:
@@ -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 WooCommerce.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 Woo.com API, then if a plugin with the 'jetpack' slug is found, it is removed.
|
||||
*
|
||||
* @since 7.8
|
||||
*/
|
||||
|
||||
@@ -424,14 +424,14 @@ class OnboardingProfile extends \WC_REST_Data_Controller {
|
||||
),
|
||||
'wccom_connected' => array(
|
||||
'type' => 'boolean',
|
||||
'description' => __( 'Whether or not the store was connected to WooCommerce.com during the extension flow.', 'woocommerce' ),
|
||||
'description' => __( 'Whether or not the store was connected to Woo.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 WooCommerce.com.', 'woocommerce' ),
|
||||
'description' => __( 'Whether or not this store agreed to receiving marketing contents from Woo.com.', 'woocommerce' ),
|
||||
'context' => array( 'view' ),
|
||||
'readonly' => true,
|
||||
'validate_callback' => 'rest_validate_request_arg',
|
||||
|
||||
@@ -249,8 +249,6 @@ class OnboardingThemes extends \WC_REST_Data_Controller {
|
||||
);
|
||||
}
|
||||
|
||||
$current_theme_slug = wp_get_theme()->get_stylesheet();
|
||||
|
||||
// To be implemented: 1. Fetch themes from the marketplace API. 2. Convert prices to the requested currency.
|
||||
// These are Dotcom themes.
|
||||
$themes = array(
|
||||
@@ -260,7 +258,6 @@ class OnboardingThemes extends \WC_REST_Data_Controller {
|
||||
'color_palettes' => array(),
|
||||
'total_palettes' => 0,
|
||||
'slug' => 'tsubaki',
|
||||
'is_active' => 'tsubaki' === $current_theme_slug,
|
||||
'thumbnail_url' => 'https://i0.wp.com/s2.wp.com/wp-content/themes/premium/tsubaki/screenshot.png',
|
||||
'link_url' => 'https://wordpress.com/theme/tsubaki/',
|
||||
),
|
||||
@@ -270,7 +267,6 @@ class OnboardingThemes extends \WC_REST_Data_Controller {
|
||||
'color_palettes' => array(),
|
||||
'total_palettes' => 0,
|
||||
'slug' => 'tazza',
|
||||
'is_active' => 'tazza' === $current_theme_slug,
|
||||
'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,
|
||||
@@ -302,7 +298,6 @@ class OnboardingThemes extends \WC_REST_Data_Controller {
|
||||
),
|
||||
'total_palettes' => 5,
|
||||
'slug' => 'amulet',
|
||||
'is_active' => 'amulet' === $current_theme_slug,
|
||||
'thumbnail_url' => 'https://i0.wp.com/s2.wp.com/wp-content/themes/premium/amulet/screenshot.png',
|
||||
'link_url' => 'https://wordpress.com/theme/amulet/',
|
||||
),
|
||||
@@ -333,7 +328,6 @@ class OnboardingThemes extends \WC_REST_Data_Controller {
|
||||
),
|
||||
'total_palettes' => 11,
|
||||
'slug' => 'zaino',
|
||||
'is_active' => 'zaino' === $current_theme_slug,
|
||||
'thumbnail_url' => 'https://i0.wp.com/s2.wp.com/wp-content/themes/premium/zaino/screenshot.png',
|
||||
'link_url' => 'https://wordpress.com/theme/zaino/',
|
||||
),
|
||||
@@ -374,12 +368,27 @@ class OnboardingThemes extends \WC_REST_Data_Controller {
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
return apply_filters(
|
||||
$filtered_response = apply_filters(
|
||||
'__experimental_woocommerce_rest_get_recommended_themes',
|
||||
$response,
|
||||
$industry,
|
||||
$currency
|
||||
);
|
||||
|
||||
/**
|
||||
* Loop through themes checking to see if any are currently active
|
||||
*/
|
||||
$active_theme = get_stylesheet();
|
||||
|
||||
foreach ( $filtered_response['themes'] as &$theme ) {
|
||||
if ( $theme['slug'] === $active_theme ) {
|
||||
$theme['is_active'] = true;
|
||||
} else {
|
||||
$theme['is_active'] = false;
|
||||
}
|
||||
}
|
||||
|
||||
return $filtered_response;
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
@@ -218,6 +218,7 @@ class Options extends \WC_REST_Data_Controller {
|
||||
'woocommerce_customize_store_ai_suggestions',
|
||||
'woocommerce_admin_customize_store_completed',
|
||||
'woocommerce_admin_customize_store_completed_theme_id',
|
||||
'woocommerce_admin_customize_store_survey_completed',
|
||||
// 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 WooCommerce.com
|
||||
* @return WP_Error|array Connection URL for Woo.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 WooCommerce.com Helper API.', 'woocommerce' ), 404 );
|
||||
return new \WP_Error( 'woocommerce_rest_helper_not_active', __( 'There was an error loading the Woo.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 WooCommerce.com. Please try again.', 'woocommerce' ), 500 );
|
||||
return new \WP_Error( 'woocommerce_rest_helper_connect', __( 'There was an error connecting to Woo.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 WooCommerce.com. Please try again.', 'woocommerce' ), 500 );
|
||||
return new \WP_Error( 'woocommerce_rest_helper_connect', __( 'There was an error connecting to Woo.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 WooCommerce.com.
|
||||
* Finishes connecting to Woo.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 WooCommerce.com Helper API.', 'woocommerce' ), 404 );
|
||||
return new \WP_Error( 'woocommerce_rest_helper_not_active', __( 'There was an error loading the Woo.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 WooCommerce.com. Please try again.', 'woocommerce' ), 500 );
|
||||
return new \WP_Error( 'woocommerce_rest_helper_connect', __( 'There was an error connecting to Woo.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 WooCommerce.com. Please try again.', 'woocommerce' ), 500 );
|
||||
return new \WP_Error( 'woocommerce_rest_helper_connect', __( 'There was an error connecting to Woo.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 WooCommerce.com. Please try again.', 'woocommerce' ), 500 );
|
||||
return new \WP_Error( 'woocommerce_rest_helper_connect', __( 'There was an error connecting to Woo.com. Please try again.', 'woocommerce' ), 500 );
|
||||
}
|
||||
|
||||
delete_transient( '_woocommerce_helper_subscriptions' );
|
||||
|
||||
@@ -42,6 +42,47 @@ final class ProductsLowInStock extends \WC_REST_Products_Controller {
|
||||
'schema' => array( $this, 'get_public_item_schema' ),
|
||||
)
|
||||
);
|
||||
register_rest_route(
|
||||
$this->namespace,
|
||||
'products/count-low-in-stock',
|
||||
array(
|
||||
'args' => array(),
|
||||
array(
|
||||
'methods' => \WP_REST_Server::READABLE,
|
||||
'callback' => array( $this, 'get_low_in_stock_count' ),
|
||||
'permission_callback' => array( $this, 'get_items_permissions_check' ),
|
||||
'args' => $this->get_low_in_stock_count_params(),
|
||||
),
|
||||
'schema' => array( $this, 'get_low_in_stock_count_schema' ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return # of low in stock count.
|
||||
*
|
||||
* @param WP_REST_Request $request request object.
|
||||
*
|
||||
* @return \WP_Error|\WP_HTTP_Response|\WP_REST_Response
|
||||
*/
|
||||
public function get_low_in_stock_count( $request ) {
|
||||
global $wpdb;
|
||||
$status = $request->get_param( 'status' );
|
||||
$low_stock_threshold = absint( max( get_option( 'woocommerce_notify_low_stock_amount' ), 1 ) );
|
||||
|
||||
$sidewide_stock_threshold_only = $this->is_using_sitewide_stock_threshold_only();
|
||||
$count_query_string = $this->get_count_query( $sidewide_stock_threshold_only );
|
||||
$count_query_results = $wpdb->get_results(
|
||||
// phpcs:ignore -- not sure why phpcs complains about this line when prepare() is used here.
|
||||
$wpdb->prepare( $count_query_string, $status, $low_stock_threshold ),
|
||||
);
|
||||
|
||||
$total_results = (int) $count_query_results[0]->total;
|
||||
$response = rest_ensure_response( array( 'total' => $total_results ) );
|
||||
$response->header( 'X-WP-Total', $total_results );
|
||||
$response->header( 'X-WP-TotalPages', 0 );
|
||||
|
||||
return $response;
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -153,7 +194,9 @@ final class ProductsLowInStock extends \WC_REST_Products_Controller {
|
||||
$offset = ( $page - 1 ) * $per_page;
|
||||
$low_stock_threshold = absint( max( get_option( 'woocommerce_notify_low_stock_amount' ), 1 ) );
|
||||
|
||||
$query_string = $this->get_query( $this->is_using_sitewide_stock_threshold_only() );
|
||||
$sidewide_stock_threshold_only = $this->is_using_sitewide_stock_threshold_only();
|
||||
|
||||
$query_string = $this->get_query( $sidewide_stock_threshold_only );
|
||||
|
||||
$query_results = $wpdb->get_results(
|
||||
// phpcs:ignore -- not sure why phpcs complains about this line when prepare() is used here.
|
||||
@@ -161,7 +204,13 @@ final class ProductsLowInStock extends \WC_REST_Products_Controller {
|
||||
OBJECT_K
|
||||
);
|
||||
|
||||
$total_results = $wpdb->get_var( 'SELECT FOUND_ROWS()' );
|
||||
$count_query_string = $this->get_count_query( $sidewide_stock_threshold_only );
|
||||
$count_query_results = $wpdb->get_results(
|
||||
// phpcs:ignore -- not sure why phpcs complains about this line when prepare() is used here.
|
||||
$wpdb->prepare( $count_query_string, $status, $low_stock_threshold ),
|
||||
);
|
||||
|
||||
$total_results = $count_query_results[0]->total;
|
||||
|
||||
return array(
|
||||
'results' => $query_results,
|
||||
@@ -213,19 +262,22 @@ final class ProductsLowInStock extends \WC_REST_Products_Controller {
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a query.
|
||||
* Return a query string for low in stock products.
|
||||
* The query string incldues the following replacement strings:
|
||||
* - :selects
|
||||
* - :postmeta_join
|
||||
* - :postmeta_wheres
|
||||
* - :orderAndLimit
|
||||
*
|
||||
* @param bool $siteside_only generates a query for sitewide low stock threshold only query.
|
||||
* @param array $replacements of replacement strings.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function get_query( $siteside_only = false ) {
|
||||
private function get_base_query( $replacements = array() ) {
|
||||
global $wpdb;
|
||||
$query = "
|
||||
SELECT
|
||||
SQL_CALC_FOUND_ROWS wp_posts.*,
|
||||
:postmeta_select
|
||||
wc_product_meta_lookup.stock_quantity
|
||||
:selects
|
||||
FROM
|
||||
{$wpdb->wc_product_meta_lookup} wc_product_meta_lookup
|
||||
LEFT JOIN {$wpdb->posts} wp_posts ON wp_posts.ID = wc_product_meta_lookup.product_id
|
||||
@@ -236,21 +288,26 @@ final class ProductsLowInStock extends \WC_REST_Products_Controller {
|
||||
AND wc_product_meta_lookup.stock_quantity IS NOT NULL
|
||||
AND wc_product_meta_lookup.stock_status IN('instock', 'outofstock')
|
||||
:postmeta_wheres
|
||||
order by wc_product_meta_lookup.product_id DESC
|
||||
limit %d, %d
|
||||
:orderAndLimit
|
||||
";
|
||||
|
||||
$postmeta = array(
|
||||
'select' => '',
|
||||
'join' => '',
|
||||
'wheres' => 'AND wc_product_meta_lookup.stock_quantity <= %d',
|
||||
);
|
||||
return strtr( $query, $replacements );
|
||||
}
|
||||
|
||||
if ( ! $siteside_only ) {
|
||||
$postmeta['select'] = 'meta.meta_value AS low_stock_amount,';
|
||||
$postmeta['join'] = "LEFT JOIN {$wpdb->postmeta} AS meta ON wp_posts.ID = meta.post_id
|
||||
AND meta.meta_key = '_low_stock_amount'";
|
||||
$postmeta['wheres'] = "AND (
|
||||
/**
|
||||
* Add sitewide stock query string to base query string.
|
||||
*
|
||||
* @param string $query Base query string.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
private function add_sitewide_stock_query_str( $query ) {
|
||||
global $wpdb;
|
||||
$postmeta = array(
|
||||
'select' => 'meta.meta_value AS low_stock_amount,',
|
||||
'join' => "LEFT JOIN {$wpdb->postmeta} AS meta ON wp_posts.ID = meta.post_id
|
||||
AND meta.meta_key = '_low_stock_amount'",
|
||||
'wheres' => "AND (
|
||||
(
|
||||
meta.meta_value > ''
|
||||
AND wc_product_meta_lookup.stock_quantity <= CAST(
|
||||
@@ -264,8 +321,8 @@ final class ProductsLowInStock extends \WC_REST_Products_Controller {
|
||||
)
|
||||
AND wc_product_meta_lookup.stock_quantity <= %d
|
||||
)
|
||||
)";
|
||||
}
|
||||
)",
|
||||
);
|
||||
|
||||
return strtr(
|
||||
$query,
|
||||
@@ -277,6 +334,64 @@ final class ProductsLowInStock extends \WC_REST_Products_Controller {
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a query.
|
||||
*
|
||||
* @param bool $sitewide_only generates a query for sitewide low stock threshold only query.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function get_query( $sitewide_only = false ) {
|
||||
$query = $this->get_base_query(
|
||||
array(
|
||||
':selects' => 'wp_posts.*, :postmeta_select wc_product_meta_lookup.stock_quantity',
|
||||
':orderAndLimit' => 'order by wc_product_meta_lookup.product_id DESC limit %d, %d',
|
||||
)
|
||||
);
|
||||
|
||||
if ( ! $sitewide_only ) {
|
||||
return $this->add_sitewide_stock_query_str( $query );
|
||||
}
|
||||
|
||||
return strtr(
|
||||
$query,
|
||||
array(
|
||||
':postmeta_select' => '',
|
||||
':postmeta_join' => '',
|
||||
':postmeta_wheres' => 'AND wc_product_meta_lookup.stock_quantity <= %d',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Generate a count query.
|
||||
*
|
||||
* @param bool $sitewide_only generates a query for sitewide low stock threshold only query.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
protected function get_count_query( $sitewide_only = false ) {
|
||||
$query = $this->get_base_query(
|
||||
array(
|
||||
':selects' => 'count(*) as total',
|
||||
':orderAndLimit' => '',
|
||||
)
|
||||
);
|
||||
|
||||
if ( ! $sitewide_only ) {
|
||||
return $this->add_sitewide_stock_query_str( $query );
|
||||
}
|
||||
|
||||
return strtr(
|
||||
$query,
|
||||
array(
|
||||
':postmeta_select' => '',
|
||||
':postmeta_join' => '',
|
||||
':postmeta_wheres' => 'AND wc_product_meta_lookup.stock_quantity <= %d',
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the query params for collections of attachments.
|
||||
*
|
||||
@@ -316,4 +431,44 @@ final class ProductsLowInStock extends \WC_REST_Products_Controller {
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the query params for collections for /count-low-in-stock endpoint.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_low_in_stock_count_params() {
|
||||
$params = array();
|
||||
$params['context'] = $this->get_context_param();
|
||||
$params['context']['default'] = 'view';
|
||||
$params['status'] = array(
|
||||
'default' => 'publish',
|
||||
'description' => __( 'Limit result set to products assigned a specific status.', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'enum' => array_merge( array_keys( get_post_statuses() ), array( 'future' ) ),
|
||||
'sanitize_callback' => 'sanitize_key',
|
||||
'validate_callback' => 'rest_validate_request_arg',
|
||||
);
|
||||
|
||||
return $params;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the schema for /count-low-in-stock response.
|
||||
*
|
||||
* @return array
|
||||
*/
|
||||
public function get_low_in_stock_count_schema() {
|
||||
return array(
|
||||
'$schema' => 'http://json-schema.org/draft-04/schema#',
|
||||
'title' => 'Count Low in Stock Items',
|
||||
'type' => 'object',
|
||||
'properties' => array(
|
||||
'type' => 'object',
|
||||
'properties' => array(
|
||||
'total' => 'integer',
|
||||
),
|
||||
),
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -31,6 +31,11 @@ interface BlockInterface {
|
||||
*/
|
||||
public const HIDE_CONDITIONS_KEY = 'hideConditions';
|
||||
|
||||
/**
|
||||
* Key for the block disable conditions in the block configuration.
|
||||
*/
|
||||
public const DISABLE_CONDITIONS_KEY = 'disableConditions';
|
||||
|
||||
/**
|
||||
* Get the block name.
|
||||
*/
|
||||
@@ -110,6 +115,29 @@ interface BlockInterface {
|
||||
*/
|
||||
public function get_hide_conditions(): array;
|
||||
|
||||
/**
|
||||
* Add a disable condition to the block.
|
||||
*
|
||||
* The disable condition is a JavaScript-like expression that will be evaluated on the client to determine if the block should be disabled.
|
||||
* See [@woocommerce/expression-evaluation](https://github.com/woocommerce/woocommerce/blob/trunk/packages/js/expression-evaluation/README.md) for more details.
|
||||
*
|
||||
* @param string $expression An expression, which if true, will disable the block.
|
||||
* @return string The key of the disable condition, which can be used to remove the disable condition.
|
||||
*/
|
||||
public function add_disable_condition( string $expression ): string;
|
||||
|
||||
/**
|
||||
* Remove a disable condition from the block.
|
||||
*
|
||||
* @param string $key The key of the disable condition to remove.
|
||||
*/
|
||||
public function remove_disable_condition( string $key );
|
||||
|
||||
/**
|
||||
* Get the disable conditions of the block.
|
||||
*/
|
||||
public function get_disable_conditions(): array;
|
||||
|
||||
/**
|
||||
* Get the block configuration as a formatted template.
|
||||
*
|
||||
|
||||
@@ -19,12 +19,17 @@ class CustomizeStore extends Task {
|
||||
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'possibly_add_site_editor_scripts' ) );
|
||||
|
||||
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' ) );
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -81,17 +86,32 @@ class CustomizeStore extends Task {
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Action URL.
|
||||
*
|
||||
* @return string
|
||||
*/
|
||||
public function get_action_url() {
|
||||
return admin_url( 'wp-admin/admin.php?page=wc-admin&path=%2Fcustomize-store' );
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* Possibly add site editor scripts.
|
||||
*/
|
||||
public function possibly_add_site_editor_scripts() {
|
||||
$is_customize_store_pages = (
|
||||
// phpcs:disable WordPress.Security.NonceVerification.Recommended
|
||||
$is_wc_admin_page = (
|
||||
isset( $_GET['page'] ) &&
|
||||
'wc-admin' === $_GET['page'] &&
|
||||
isset( $_GET['path'] ) &&
|
||||
str_starts_with( wc_clean( wp_unslash( $_GET['path'] ) ), '/customize-store' )
|
||||
isset( $_GET['path'] )
|
||||
);
|
||||
if ( ! $is_customize_store_pages ) {
|
||||
|
||||
$is_assembler_hub = $is_wc_admin_page && str_starts_with( wc_clean( wp_unslash( $_GET['path'] ) ), '/customize-store/assembler-hub' );
|
||||
$is_transitional_page = $is_wc_admin_page && str_starts_with( wc_clean( wp_unslash( $_GET['path'] ) ), '/customize-store/transitional' );
|
||||
// phpcs:enable WordPress.Security.NonceVerification.Recommended
|
||||
|
||||
if ( ! ( $is_assembler_hub || $is_transitional_page ) ) {
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -204,4 +224,31 @@ class CustomizeStore extends Task {
|
||||
public function mark_task_as_complete() {
|
||||
update_option( 'woocommerce_admin_customize_store_completed', 'yes' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Appends a small style to hide admin bar
|
||||
*
|
||||
* @param bool $show Whether to show the admin bar.
|
||||
*/
|
||||
public function possibly_hide_wp_admin_bar( $show ) {
|
||||
if ( isset( $_GET['cys-hide-admin-bar'] ) ) { // @phpcs:ignore
|
||||
return false;
|
||||
}
|
||||
return $show;
|
||||
}
|
||||
|
||||
/**
|
||||
* Runs script and add styles to remove unwanted elements and hide scrollbar
|
||||
* when users are viewing with ?cys-hide-admin-bar=true.
|
||||
*
|
||||
* @return void
|
||||
*/
|
||||
public function possibly_remove_unwanted_ui_elements() {
|
||||
if ( isset( $_GET['cys-hide-admin-bar'] ) ) { // @phpcs:ignore
|
||||
echo '
|
||||
<style type="text/css">
|
||||
body { overflow: hidden; }
|
||||
</style>';
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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://woocommerce.com/products/woocommerce-gateway-affirm',
|
||||
'external_link' => 'https://woo.com/products/woocommerce-gateway-affirm',
|
||||
'is_visible' => array(
|
||||
self::get_rules_for_countries(
|
||||
array(
|
||||
|
||||
@@ -23,7 +23,7 @@ class BlockRegistry {
|
||||
/**
|
||||
* Array of all available generic blocks.
|
||||
*/
|
||||
const GENERIC_BLOCKS = [
|
||||
const GENERIC_BLOCKS = array(
|
||||
'woocommerce/conditional',
|
||||
'woocommerce/product-checkbox-field',
|
||||
'woocommerce/product-collapsible',
|
||||
@@ -35,12 +35,12 @@ class BlockRegistry {
|
||||
'woocommerce/product-taxonomy-field',
|
||||
'woocommerce/product-text-field',
|
||||
'woocommerce/product-number-field',
|
||||
];
|
||||
);
|
||||
|
||||
/**
|
||||
* Array of all available product fields blocks.
|
||||
*/
|
||||
const PRODUCT_FIELDS_BLOCKS = [
|
||||
const PRODUCT_FIELDS_BLOCKS = array(
|
||||
'woocommerce/product-catalog-visibility-field',
|
||||
'woocommerce/product-description-field',
|
||||
'woocommerce/product-downloads-field',
|
||||
@@ -61,7 +61,7 @@ class BlockRegistry {
|
||||
'woocommerce/product-password-field',
|
||||
'woocommerce/product-has-variations-notice',
|
||||
'woocommerce/product-single-variation-notice',
|
||||
];
|
||||
);
|
||||
|
||||
/**
|
||||
* Get a file path for a given block file.
|
||||
@@ -136,20 +136,28 @@ class BlockRegistry {
|
||||
// registerWooBlockType function in @woocommerce/block-templates.
|
||||
return array_merge(
|
||||
$attributes,
|
||||
[
|
||||
'_templateBlockId' => [
|
||||
array(
|
||||
'_templateBlockId' => array(
|
||||
'type' => 'string',
|
||||
'__experimentalRole' => 'content',
|
||||
],
|
||||
'_templateBlockOrder' => [
|
||||
),
|
||||
'_templateBlockOrder' => array(
|
||||
'type' => 'integer',
|
||||
'__experimentalRole' => 'content',
|
||||
],
|
||||
'_templateBlockHideConditions' => [
|
||||
),
|
||||
'_templateBlockHideConditions' => array(
|
||||
'type' => 'array',
|
||||
'__experimentalRole' => 'content',
|
||||
],
|
||||
]
|
||||
),
|
||||
'_templateBlockDisableConditions' => array(
|
||||
'type' => 'array',
|
||||
'__experimentalRole' => 'content',
|
||||
),
|
||||
'disabled' => isset( $attributes['disabled'] ) ? $attributes['disabled'] : array(
|
||||
'type' => 'boolean',
|
||||
'__experimentalRole' => 'content',
|
||||
),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -162,10 +170,10 @@ class BlockRegistry {
|
||||
// Note: If you modify this function, also update the client-side
|
||||
// registerProductEditorBlockType function in @woocommerce/product-editor.
|
||||
return array_merge(
|
||||
isset( $uses_context ) ? $uses_context : [],
|
||||
[
|
||||
isset( $uses_context ) ? $uses_context : array(),
|
||||
array(
|
||||
'postType',
|
||||
]
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
@@ -199,10 +207,10 @@ class BlockRegistry {
|
||||
|
||||
return register_block_type_from_metadata(
|
||||
$block_json_file,
|
||||
[
|
||||
'attributes' => $this->augment_attributes( isset( $metadata['attributes'] ) ? $metadata['attributes'] : [] ),
|
||||
'uses_context' => $this->augment_uses_context( isset( $metadata['usesContext'] ) ? $metadata['usesContext'] : [] ),
|
||||
]
|
||||
array(
|
||||
'attributes' => $this->augment_attributes( isset( $metadata['attributes'] ) ? $metadata['attributes'] : array() ),
|
||||
'uses_context' => $this->augment_uses_context( isset( $metadata['usesContext'] ) ? $metadata['usesContext'] : array() ),
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -6,10 +6,12 @@
|
||||
namespace Automattic\WooCommerce\Admin\Features\ProductBlockEditor;
|
||||
|
||||
use Automattic\WooCommerce\Admin\Features\Features;
|
||||
use Automattic\WooCommerce\Admin\Features\ProductBlockEditor\ProductTemplates\SimpleProductTemplate;
|
||||
use Automattic\WooCommerce\Admin\Features\ProductBlockEditor\ProductTemplates\ProductVariationTemplate;
|
||||
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;
|
||||
|
||||
/**
|
||||
@@ -43,14 +45,13 @@ class Init {
|
||||
array_push( $this->supported_post_types, 'variable' );
|
||||
}
|
||||
|
||||
if ( Features::is_enabled( 'product-external-affiliate' ) ) {
|
||||
array_push( $this->supported_post_types, 'external' );
|
||||
}
|
||||
|
||||
$this->redirection_controller = new RedirectionController( $this->supported_post_types );
|
||||
|
||||
if ( \Automattic\WooCommerce\Utilities\FeaturesUtil::feature_is_enabled( 'product_block_editor' ) ) {
|
||||
// Register the product block template.
|
||||
$template_registry = wc_get_container()->get( BlockTemplateRegistry::class );
|
||||
$template_registry->register( new SimpleProductTemplate() );
|
||||
$template_registry->register( new ProductVariationTemplate() );
|
||||
|
||||
if ( ! Features::is_enabled( 'new-product-management-experience' ) ) {
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_styles' ) );
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'dequeue_conflicting_styles' ), 100 );
|
||||
@@ -58,7 +59,6 @@ class Init {
|
||||
}
|
||||
add_filter( 'woocommerce_admin_get_user_data_fields', array( $this, 'add_user_data_fields' ) );
|
||||
add_action( 'admin_enqueue_scripts', array( $this, 'enqueue_scripts' ) );
|
||||
add_filter( 'woocommerce_register_post_type_product', array( $this, 'add_product_template' ) );
|
||||
add_filter( 'woocommerce_register_post_type_product_variation', array( $this, 'enable_rest_api_for_product_variation' ) );
|
||||
|
||||
add_action( 'current_screen', array( $this, 'set_current_screen_to_block_editor_if_wc_admin' ) );
|
||||
@@ -68,6 +68,9 @@ class Init {
|
||||
|
||||
$tracks = new Tracks();
|
||||
$tracks->init();
|
||||
|
||||
// Make sure the block template logger is initialized before any templates are created.
|
||||
BlockTemplateLogger::get_instance();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -78,21 +81,9 @@ class Init {
|
||||
if ( ! PageController::is_admin_or_embed_page() ) {
|
||||
return;
|
||||
}
|
||||
$post_type_object = get_post_type_object( 'product' );
|
||||
$block_editor_context = new WP_Block_Editor_Context( array( 'name' => self::EDITOR_CONTEXT_NAME ) );
|
||||
$template_registry = wc_get_container()->get( BlockTemplateRegistry::class );
|
||||
|
||||
$editor_settings = array();
|
||||
if ( ! empty( $post_type_object->template ) ) {
|
||||
$editor_settings['template'] = $post_type_object->template;
|
||||
$editor_settings['templateLock'] = ! empty( $post_type_object->template_lock ) ? $post_type_object->template_lock : false;
|
||||
$editor_settings['templates'] = array(
|
||||
'product' => $post_type_object->template,
|
||||
'product_variation' => $template_registry->get_registered( 'product-variation' )->get_formatted_template(),
|
||||
);
|
||||
}
|
||||
|
||||
$editor_settings = get_block_editor_settings( $editor_settings, $block_editor_context );
|
||||
$this->register_product_editor_templates();
|
||||
$editor_settings = $this->get_product_editor_settings();
|
||||
|
||||
$script_handle = 'wc-admin-edit-product';
|
||||
wp_register_script( $script_handle, '', array(), '0.1.0', true );
|
||||
@@ -161,26 +152,6 @@ class Init {
|
||||
return $link;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enqueue styles needed for the rich text editor.
|
||||
*
|
||||
* @param array $args Array of post type arguments.
|
||||
* @return array Array of post type arguments.
|
||||
*/
|
||||
public function add_product_template( $args ) {
|
||||
if ( ! isset( $args['template'] ) ) {
|
||||
// Get the template from the registry.
|
||||
$template_registry = wc_get_container()->get( BlockTemplateRegistry::class );
|
||||
$template = $template_registry->get_registered( 'simple-product' );
|
||||
|
||||
if ( isset( $template ) ) {
|
||||
$args['template_lock'] = 'all';
|
||||
$args['template'] = $template->get_formatted_template();
|
||||
}
|
||||
}
|
||||
return $args;
|
||||
}
|
||||
|
||||
/**
|
||||
* Enables variation post type in REST API.
|
||||
*
|
||||
@@ -230,4 +201,41 @@ 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' ),
|
||||
);
|
||||
|
||||
$block_editor_context = new WP_Block_Editor_Context( array( 'name' => self::EDITOR_CONTEXT_NAME ) );
|
||||
|
||||
return get_block_editor_settings( $editor_settings, $block_editor_context );
|
||||
}
|
||||
|
||||
/**
|
||||
* Register product editor templates.
|
||||
*/
|
||||
private function register_product_editor_templates() {
|
||||
$template_registry = wc_get_container()->get( BlockTemplateRegistry::class );
|
||||
|
||||
$template_registry->register( new SimpleProductTemplate() );
|
||||
$template_registry->register( new ProductVariationTemplate() );
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,65 +0,0 @@
|
||||
<?php
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\Features\ProductBlockEditor\ProductTemplates;
|
||||
|
||||
use Automattic\WooCommerce\Admin\BlockTemplates\BlockInterface;
|
||||
use Automattic\WooCommerce\Internal\Admin\BlockTemplates\AbstractBlockTemplate;
|
||||
|
||||
/**
|
||||
* Block template class.
|
||||
*/
|
||||
abstract class AbstractProductFormTemplate extends AbstractBlockTemplate implements ProductFormTemplateInterface {
|
||||
/**
|
||||
* Get the template area.
|
||||
*/
|
||||
public function get_area(): string {
|
||||
return 'product-form';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a group block by ID.
|
||||
*
|
||||
* @param string $group_id The group block ID.
|
||||
* @throws \UnexpectedValueException If block is not of type GroupInterface.
|
||||
*/
|
||||
public function get_group_by_id( string $group_id ): ?GroupInterface {
|
||||
$group = $this->get_block( $group_id );
|
||||
if ( $group && ! $group instanceof GroupInterface ) {
|
||||
throw new \UnexpectedValueException( 'Block with specified ID is not a group.' );
|
||||
}
|
||||
return $group;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a section block by ID.
|
||||
*
|
||||
* @param string $section_id The section block ID.
|
||||
* @throws \UnexpectedValueException If block is not of type SectionInterface.
|
||||
*/
|
||||
public function get_section_by_id( string $section_id ): ?SectionInterface {
|
||||
$section = $this->get_block( $section_id );
|
||||
if ( $section && ! $section instanceof SectionInterface ) {
|
||||
throw new \UnexpectedValueException( 'Block with specified ID is not a section.' );
|
||||
}
|
||||
return $section;
|
||||
}
|
||||
|
||||
/**
|
||||
* Get a block by ID.
|
||||
*
|
||||
* @param string $block_id The block block ID.
|
||||
*/
|
||||
public function get_block_by_id( string $block_id ): ?BlockInterface {
|
||||
return $this->get_block( $block_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a custom block type to this template.
|
||||
*
|
||||
* @param array $block_config The block data.
|
||||
*/
|
||||
public function add_group( array $block_config ): GroupInterface {
|
||||
$block = new Group( $block_config, $this->get_root_template(), $this );
|
||||
return $this->add_inner_block( $block );
|
||||
}
|
||||
}
|
||||
@@ -1,49 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* WooCommerce Product Group Block class.
|
||||
*/
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\Features\ProductBlockEditor\ProductTemplates;
|
||||
|
||||
use Automattic\WooCommerce\Admin\BlockTemplates\BlockTemplateInterface;
|
||||
use Automattic\WooCommerce\Admin\BlockTemplates\ContainerInterface;
|
||||
use Automattic\WooCommerce\Internal\Admin\BlockTemplates\BlockContainerTrait;
|
||||
|
||||
/**
|
||||
* Class for Group block.
|
||||
*/
|
||||
class Group extends ProductBlock implements GroupInterface {
|
||||
use BlockContainerTrait;
|
||||
|
||||
/**
|
||||
* Group Block constructor.
|
||||
*
|
||||
* @param array $config The block configuration.
|
||||
* @param BlockTemplateInterface $root_template The block template that this block belongs to.
|
||||
* @param ContainerInterface|null $parent The parent block container.
|
||||
*
|
||||
* @throws \ValueError If the block configuration is invalid.
|
||||
* @throws \ValueError If the parent block container does not belong to the same template as the block.
|
||||
* @throws \InvalidArgumentException If blockName key and value are passed into block configuration.
|
||||
*/
|
||||
public function __construct( array $config, BlockTemplateInterface &$root_template, ContainerInterface &$parent = null ) {
|
||||
if ( ! empty( $config['blockName'] ) ) {
|
||||
throw new \InvalidArgumentException( 'Unexpected key "blockName", this defaults to "woocommerce/product-tab".' );
|
||||
}
|
||||
if ( $config['id'] && ( empty( $config['attributes'] ) || empty( $config['attributes']['id'] ) ) ) {
|
||||
$config['attributes'] = empty( $config['attributes'] ) ? [] : $config['attributes'];
|
||||
$config['attributes']['id'] = $config['id'];
|
||||
}
|
||||
parent::__construct( array_merge( array( 'blockName' => 'woocommerce/product-tab' ), $config ), $root_template, $parent );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a section block type to this template.
|
||||
*
|
||||
* @param array $block_config The block data.
|
||||
*/
|
||||
public function add_section( array $block_config ): SectionInterface {
|
||||
$block = new Section( $block_config, $this->get_root_template(), $this );
|
||||
return $this->add_inner_block( $block );
|
||||
}
|
||||
}
|
||||
@@ -1,27 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* WooCommerce Product Block class.
|
||||
*/
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\Features\ProductBlockEditor\ProductTemplates;
|
||||
|
||||
use Automattic\WooCommerce\Admin\BlockTemplates\BlockInterface;
|
||||
use Automattic\WooCommerce\Admin\BlockTemplates\ContainerInterface;
|
||||
use Automattic\WooCommerce\Internal\Admin\BlockTemplates\AbstractBlock;
|
||||
use Automattic\WooCommerce\Internal\Admin\BlockTemplates\BlockContainerTrait;
|
||||
|
||||
/**
|
||||
* Class for Product block.
|
||||
*/
|
||||
class ProductBlock extends AbstractBlock implements ContainerInterface {
|
||||
use BlockContainerTrait;
|
||||
/**
|
||||
* Adds block to the section block.
|
||||
*
|
||||
* @param array $block_config The block data.
|
||||
*/
|
||||
public function &add_block( array $block_config ): BlockInterface {
|
||||
$block = new ProductBlock( $block_config, $this->get_root_template(), $this );
|
||||
return $this->add_inner_block( $block );
|
||||
}
|
||||
}
|
||||
@@ -14,7 +14,7 @@ interface ProductFormTemplateInterface extends BlockTemplateInterface {
|
||||
* Adds a new group block.
|
||||
*
|
||||
* @param array $block_config block config.
|
||||
* @return BlockInterface new block section.
|
||||
* @return GroupInterface new group block.
|
||||
*/
|
||||
public function add_group( array $block_config ): GroupInterface;
|
||||
|
||||
|
||||
@@ -1,528 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* ProductVariationTemplate
|
||||
*/
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\Features\ProductBlockEditor\ProductTemplates;
|
||||
|
||||
use Automattic\WooCommerce\Admin\Features\Features;
|
||||
|
||||
/**
|
||||
* Simple Product Template.
|
||||
*/
|
||||
class ProductVariationTemplate extends AbstractProductFormTemplate implements ProductFormTemplateInterface {
|
||||
/**
|
||||
* The context name used to identify the editor.
|
||||
*/
|
||||
const GROUP_IDS = array(
|
||||
'GENERAL' => 'general',
|
||||
'PRICING' => 'pricing',
|
||||
'INVENTORY' => 'inventory',
|
||||
'SHIPPING' => 'shipping',
|
||||
);
|
||||
|
||||
/**
|
||||
* The option name used check whether the single variation notice has been dismissed.
|
||||
*/
|
||||
const SINGLE_VARIATION_NOTICE_DISMISSED_OPTION = 'woocommerce_single_variation_notice_dismissed';
|
||||
|
||||
/**
|
||||
* SimpleProductTemplate constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->add_group_blocks();
|
||||
$this->add_general_group_blocks();
|
||||
$this->add_pricing_group_blocks();
|
||||
$this->add_inventory_group_blocks();
|
||||
$this->add_shipping_group_blocks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the template ID.
|
||||
*/
|
||||
public function get_id(): string {
|
||||
return 'product-variation';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the template title.
|
||||
*/
|
||||
public function get_title(): string {
|
||||
return __( 'Product Variation Template', 'woocommerce' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the template description.
|
||||
*/
|
||||
public function get_description(): string {
|
||||
return __( 'Template for the product variation form', 'woocommerce' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the group blocks to the template.
|
||||
*/
|
||||
private function add_group_blocks() {
|
||||
$this->add_group(
|
||||
[
|
||||
'id' => $this::GROUP_IDS['GENERAL'],
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'title' => __( 'General', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
$this->add_group(
|
||||
[
|
||||
'id' => $this::GROUP_IDS['PRICING'],
|
||||
'order' => 20,
|
||||
'attributes' => [
|
||||
'title' => __( 'Pricing', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
$this->add_group(
|
||||
[
|
||||
'id' => $this::GROUP_IDS['INVENTORY'],
|
||||
'order' => 30,
|
||||
'attributes' => [
|
||||
'title' => __( 'Inventory', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
$this->add_group(
|
||||
[
|
||||
'id' => $this::GROUP_IDS['SHIPPING'],
|
||||
'order' => 40,
|
||||
'attributes' => [
|
||||
'title' => __( 'Shipping', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the general group blocks to the template.
|
||||
*/
|
||||
private function add_general_group_blocks() {
|
||||
$general_group = $this->get_group_by_id( $this::GROUP_IDS['GENERAL'] );
|
||||
$general_group->add_block(
|
||||
[
|
||||
'id' => 'general-single-variation-notice',
|
||||
'blockName' => 'woocommerce/product-single-variation-notice',
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'content' => __( '<strong>You’re editing details specific to this variation.</strong> Some information, like description and images, will be inherited from the main product, <noticeLink><parentProductName/></noticeLink>.', 'woocommerce' ),
|
||||
'type' => 'info',
|
||||
'isDismissible' => true,
|
||||
'name' => $this::SINGLE_VARIATION_NOTICE_DISMISSED_OPTION,
|
||||
],
|
||||
]
|
||||
);
|
||||
// Basic Details Section.
|
||||
$basic_details = $general_group->add_section(
|
||||
[
|
||||
'id' => 'product-variation-details-section',
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'title' => __( 'Variation details', 'woocommerce' ),
|
||||
'description' => __( 'This info will be displayed on the product page, category pages, social media, and search results.', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
$basic_details->add_block(
|
||||
[
|
||||
'id' => 'product-variation-note',
|
||||
'blockName' => 'woocommerce/product-summary-field',
|
||||
'order' => 20,
|
||||
'attributes' => [
|
||||
'property' => 'description',
|
||||
'label' => __( 'Note <optional />', 'woocommerce' ),
|
||||
'helpText' => 'Enter an optional note displayed on the product page when customers select this variation.',
|
||||
],
|
||||
]
|
||||
);
|
||||
$basic_details->add_block(
|
||||
[
|
||||
'id' => 'product-variation-visibility',
|
||||
'blockName' => 'woocommerce/product-checkbox-field',
|
||||
'order' => 30,
|
||||
'attributes' => [
|
||||
'property' => 'status',
|
||||
'label' => __( 'Hide in product catalog', 'woocommerce' ),
|
||||
'checkedValue' => 'private',
|
||||
'uncheckedValue' => 'publish',
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
// Images section.
|
||||
$images_section = $general_group->add_section(
|
||||
[
|
||||
'id' => 'product-variation-images-section',
|
||||
'order' => 30,
|
||||
'attributes' => [
|
||||
'title' => __( 'Image', 'woocommerce' ),
|
||||
'description' => sprintf(
|
||||
/* translators: %1$s: Images guide link opening tag. %2$s: Images guide link closing tag. */
|
||||
__( 'Drag images, upload new ones or select files from your library. For best results, use JPEG files that are 1000 by 1000 pixels or larger. %1$sHow to prepare images?%2$s', 'woocommerce' ),
|
||||
'<a href="https://woocommerce.com/posts/how-to-take-professional-product-photos-top-tips" target="_blank" rel="noreferrer">',
|
||||
'</a>'
|
||||
),
|
||||
],
|
||||
]
|
||||
);
|
||||
$images_section->add_block(
|
||||
[
|
||||
'id' => 'product-variation-image',
|
||||
'blockName' => 'woocommerce/product-images-field',
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'property' => 'image',
|
||||
'multiple' => false,
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
// Downloads section.
|
||||
if ( Features::is_enabled( 'product-virtual-downloadable' ) ) {
|
||||
$general_group->add_section(
|
||||
[
|
||||
'id' => 'product-variation-downloads-section',
|
||||
'order' => 40,
|
||||
'attributes' => [
|
||||
'title' => __( 'Downloads', 'woocommerce' ),
|
||||
'description' => __( "Add any files you'd like to make available for the customer to download after purchasing, such as instructions or warranty info.", 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
)->add_block(
|
||||
[
|
||||
'id' => 'product-variation-downloads',
|
||||
'blockName' => 'woocommerce/product-downloads-field',
|
||||
'order' => 10,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the pricing group blocks to the template.
|
||||
*/
|
||||
private function add_pricing_group_blocks() {
|
||||
$pricing_group = $this->get_group_by_id( $this::GROUP_IDS['PRICING'] );
|
||||
$pricing_group->add_block(
|
||||
[
|
||||
'id' => 'pricing-single-variation-notice',
|
||||
'blockName' => 'woocommerce/product-single-variation-notice',
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'content' => __( '<strong>You’re editing details specific to this variation.</strong> Some information, like description and images, will be inherited from the main product, <noticeLink><parentProductName/></noticeLink>.', 'woocommerce' ),
|
||||
'type' => 'info',
|
||||
'isDismissible' => true,
|
||||
'name' => $this::SINGLE_VARIATION_NOTICE_DISMISSED_OPTION,
|
||||
],
|
||||
]
|
||||
);
|
||||
// Product Pricing Section.
|
||||
$product_pricing_section = $pricing_group->add_section(
|
||||
[
|
||||
'id' => 'product-pricing-section',
|
||||
'order' => 20,
|
||||
'attributes' => [
|
||||
'title' => __( 'Pricing', 'woocommerce' ),
|
||||
'description' => sprintf(
|
||||
/* translators: %1$s: Images guide link opening tag. %2$s: Images guide link closing tag.*/
|
||||
__( 'Set a competitive price, put the product on sale, and manage tax calculations. %1$sHow to price your product?%2$s', 'woocommerce' ),
|
||||
'<a href="https://woocommerce.com/posts/how-to-price-products-strategies-expert-tips/" target="_blank" rel="noreferrer">',
|
||||
'</a>'
|
||||
),
|
||||
'blockGap' => 'unit-40',
|
||||
],
|
||||
]
|
||||
);
|
||||
$pricing_columns = $product_pricing_section->add_block(
|
||||
[
|
||||
'id' => 'product-pricing-group-pricing-columns',
|
||||
'blockName' => 'core/columns',
|
||||
'order' => 10,
|
||||
]
|
||||
);
|
||||
$pricing_column_1 = $pricing_columns->add_block(
|
||||
[
|
||||
'id' => 'product-pricing-group-pricing-column-1',
|
||||
'blockName' => 'core/column',
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'templateLock' => 'all',
|
||||
],
|
||||
]
|
||||
);
|
||||
$pricing_column_1->add_block(
|
||||
[
|
||||
'id' => 'product-pricing-regular-price',
|
||||
'blockName' => 'woocommerce/product-regular-price-field',
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'name' => 'regular_price',
|
||||
'label' => __( 'Regular price', 'woocommerce' ),
|
||||
'isRequired' => true,
|
||||
],
|
||||
]
|
||||
);
|
||||
$pricing_column_2 = $pricing_columns->add_block(
|
||||
[
|
||||
'id' => 'product-pricing-group-pricing-column-2',
|
||||
'blockName' => 'core/column',
|
||||
'order' => 20,
|
||||
'attributes' => [
|
||||
'templateLock' => 'all',
|
||||
],
|
||||
]
|
||||
);
|
||||
$pricing_column_2->add_block(
|
||||
[
|
||||
'id' => 'product-pricing-sale-price',
|
||||
'blockName' => 'woocommerce/product-sale-price-field',
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'label' => __( 'Sale price', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_pricing_section->add_block(
|
||||
[
|
||||
'id' => 'product-pricing-schedule-sale-fields',
|
||||
'blockName' => 'woocommerce/product-schedule-sale-fields',
|
||||
'order' => 20,
|
||||
]
|
||||
);
|
||||
|
||||
$product_pricing_section->add_block(
|
||||
[
|
||||
'id' => 'product-tax-class',
|
||||
'blockName' => 'woocommerce/product-radio-field',
|
||||
'order' => 40,
|
||||
'attributes' => [
|
||||
'title' => __( 'Tax class', 'woocommerce' ),
|
||||
'description' => sprintf(
|
||||
/* translators: %1$s: Learn more link opening tag. %2$s: Learn more link closing tag.*/
|
||||
__( 'Apply a tax rate if this product qualifies for tax reduction or exemption. %1$sLearn more%2$s.', 'woocommerce' ),
|
||||
'<a href="https://woocommerce.com/document/setting-up-taxes-in-woocommerce/#shipping-tax-class" target="_blank" rel="noreferrer">',
|
||||
'</a>'
|
||||
),
|
||||
'property' => 'tax_class',
|
||||
'options' => [
|
||||
[
|
||||
'label' => __( 'Same as main product', 'woocommerce' ),
|
||||
'value' => 'parent',
|
||||
],
|
||||
[
|
||||
'label' => __( 'Standard', 'woocommerce' ),
|
||||
'value' => '',
|
||||
],
|
||||
[
|
||||
'label' => __( 'Reduced rate', 'woocommerce' ),
|
||||
'value' => 'reduced-rate',
|
||||
],
|
||||
[
|
||||
'label' => __( 'Zero rate', 'woocommerce' ),
|
||||
'value' => 'zero-rate',
|
||||
],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the inventory group blocks to the template.
|
||||
*/
|
||||
private function add_inventory_group_blocks() {
|
||||
$inventory_group = $this->get_group_by_id( $this::GROUP_IDS['INVENTORY'] );
|
||||
$inventory_group->add_block(
|
||||
[
|
||||
'id' => 'inventory-single-variation-notice',
|
||||
'blockName' => 'woocommerce/product-single-variation-notice',
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'content' => __( '<strong>You’re editing details specific to this variation.</strong> Some information, like description and images, will be inherited from the main product, <noticeLink><parentProductName/></noticeLink>.', 'woocommerce' ),
|
||||
'type' => 'info',
|
||||
'isDismissible' => true,
|
||||
'name' => $this::SINGLE_VARIATION_NOTICE_DISMISSED_OPTION,
|
||||
],
|
||||
]
|
||||
);
|
||||
// Product Inventory Section.
|
||||
$product_inventory_section = $inventory_group->add_section(
|
||||
[
|
||||
'id' => 'product-variation-inventory-section',
|
||||
'order' => 20,
|
||||
'attributes' => [
|
||||
'title' => __( 'Inventory', 'woocommerce' ),
|
||||
'description' => sprintf(
|
||||
/* translators: %1$s: Inventory settings link opening tag. %2$s: Inventory settings link closing tag.*/
|
||||
__( 'Set up and manage inventory for this product, including status and available quantity. %1$sManage store inventory settings%2$s', 'woocommerce' ),
|
||||
'<a href="' . admin_url( 'admin.php?page=wc-settings&tab=products§ion=inventory' ) . '" target="_blank" rel="noreferrer">',
|
||||
'</a>'
|
||||
),
|
||||
'blockGap' => 'unit-40',
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_inventory_inner_section = $product_inventory_section->add_section(
|
||||
[
|
||||
'id' => 'product-variation-inventory-inner-section',
|
||||
'order' => 10,
|
||||
]
|
||||
);
|
||||
$product_inventory_inner_section->add_block(
|
||||
[
|
||||
'id' => 'product-variation-sku-field',
|
||||
'blockName' => 'woocommerce/product-sku-field',
|
||||
'order' => 10,
|
||||
]
|
||||
);
|
||||
$product_inventory_inner_section->add_block(
|
||||
[
|
||||
'id' => 'product-variation-track-stock',
|
||||
'blockName' => 'woocommerce/product-toggle-field',
|
||||
'order' => 20,
|
||||
'attributes' => [
|
||||
'label' => __( 'Track stock quantity for this product', 'woocommerce' ),
|
||||
'property' => 'manage_stock',
|
||||
'disabled' => 'yes' !== get_option( 'woocommerce_manage_stock' ),
|
||||
'disabledCopy' => sprintf(
|
||||
/* translators: %1$s: Learn more link opening tag. %2$s: Learn more link closing tag.*/
|
||||
__( 'Per your %1$sstore settings%2$s, inventory management is <strong>disabled</strong>.', 'woocommerce' ),
|
||||
'<a href="' . admin_url( 'admin.php?page=wc-settings&tab=products§ion=inventory' ) . '" target="_blank" rel="noreferrer">',
|
||||
'</a>'
|
||||
),
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_inventory_quantity_conditional = $product_inventory_inner_section->add_block(
|
||||
[
|
||||
'id' => 'product-variation-inventory-quantity-conditional-wrapper',
|
||||
'blockName' => 'woocommerce/conditional',
|
||||
'order' => 30,
|
||||
'attributes' => [
|
||||
'mustMatch' => [
|
||||
'manage_stock' => [ true ],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_inventory_quantity_conditional->add_block(
|
||||
[
|
||||
'id' => 'product-variation-inventory-quantity',
|
||||
'blockName' => 'woocommerce/product-inventory-quantity-field',
|
||||
'order' => 10,
|
||||
]
|
||||
);
|
||||
$product_stock_status_conditional = $product_inventory_section->add_block(
|
||||
[
|
||||
'id' => 'product-variation-stock-status-conditional-wrapper',
|
||||
'blockName' => 'woocommerce/conditional',
|
||||
'order' => 20,
|
||||
'attributes' => [
|
||||
'mustMatch' => [
|
||||
'manage_stock' => [ false ],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_stock_status_conditional->add_block(
|
||||
[
|
||||
'id' => 'product-variation-stock-status',
|
||||
'blockName' => 'woocommerce/product-radio-field',
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'title' => __( 'Stock status', 'woocommerce' ),
|
||||
'property' => 'stock_status',
|
||||
'options' => [
|
||||
[
|
||||
'label' => __( 'In stock', 'woocommerce' ),
|
||||
'value' => 'instock',
|
||||
],
|
||||
[
|
||||
'label' => __( 'Out of stock', 'woocommerce' ),
|
||||
'value' => 'outofstock',
|
||||
],
|
||||
[
|
||||
'label' => __( 'On backorder', 'woocommerce' ),
|
||||
'value' => 'onbackorder',
|
||||
],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the shipping group blocks to the template.
|
||||
*/
|
||||
private function add_shipping_group_blocks() {
|
||||
$shipping_group = $this->get_group_by_id( $this::GROUP_IDS['SHIPPING'] );
|
||||
$shipping_group->add_block(
|
||||
[
|
||||
'id' => 'shipping-single-variation-notice',
|
||||
'blockName' => 'woocommerce/product-single-variation-notice',
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'content' => __( '<strong>You’re editing details specific to this variation.</strong> Some information, like description and images, will be inherited from the main product, <noticeLink><parentProductName/></noticeLink>.', 'woocommerce' ),
|
||||
'type' => 'info',
|
||||
'isDismissible' => true,
|
||||
'name' => $this::SINGLE_VARIATION_NOTICE_DISMISSED_OPTION,
|
||||
],
|
||||
]
|
||||
);
|
||||
// Virtual section.
|
||||
$shipping_group->add_section(
|
||||
[
|
||||
'id' => 'product-variation-virtual-section',
|
||||
'order' => 20,
|
||||
]
|
||||
)->add_block(
|
||||
[
|
||||
'id' => 'product-variation-virtual',
|
||||
'blockName' => 'woocommerce/product-toggle-field',
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'property' => 'virtual',
|
||||
'checkedValue' => false,
|
||||
'uncheckedValue' => true,
|
||||
'label' => __( 'This variation requires shipping or pickup', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
// Product Shipping Section.
|
||||
$product_fee_and_dimensions_section = $shipping_group->add_section(
|
||||
[
|
||||
'id' => 'product-variation-fee-and-dimensions-section',
|
||||
'order' => 30,
|
||||
'attributes' => [
|
||||
'title' => __( 'Fees & dimensions', 'woocommerce' ),
|
||||
'description' => sprintf(
|
||||
/* translators: %1$s: How to get started? link opening tag. %2$s: How to get started? link closing tag.*/
|
||||
__( 'Set up shipping costs and enter dimensions used for accurate rate calculations. %1$sHow to get started?%2$s.', 'woocommerce' ),
|
||||
'<a href="https://woocommerce.com/posts/how-to-calculate-shipping-costs-for-your-woocommerce-store/" target="_blank" rel="noreferrer">',
|
||||
'</a>'
|
||||
),
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_fee_and_dimensions_section->add_block(
|
||||
[
|
||||
'id' => 'product-variation-shipping-class',
|
||||
'blockName' => 'woocommerce/product-shipping-class-field',
|
||||
'order' => 10,
|
||||
]
|
||||
);
|
||||
$product_fee_and_dimensions_section->add_block(
|
||||
[
|
||||
'id' => 'product-variation-shipping-dimensions',
|
||||
'blockName' => 'woocommerce/product-shipping-dimensions-fields',
|
||||
'order' => 20,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -1,43 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* WooCommerce Section Block class.
|
||||
*/
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\Features\ProductBlockEditor\ProductTemplates;
|
||||
|
||||
use Automattic\WooCommerce\Admin\BlockTemplates\BlockTemplateInterface;
|
||||
use Automattic\WooCommerce\Admin\BlockTemplates\ContainerInterface;
|
||||
|
||||
/**
|
||||
* Class for Section block.
|
||||
*/
|
||||
class Section extends ProductBlock implements SectionInterface {
|
||||
|
||||
/**
|
||||
* Section Block constructor.
|
||||
*
|
||||
* @param array $config The block configuration.
|
||||
* @param BlockTemplateInterface $root_template The block template that this block belongs to.
|
||||
* @param ContainerInterface|null $parent The parent block container.
|
||||
*
|
||||
* @throws \ValueError If the block configuration is invalid.
|
||||
* @throws \ValueError If the parent block container does not belong to the same template as the block.
|
||||
* @throws \InvalidArgumentException If blockName key and value are passed into block configuration.
|
||||
*/
|
||||
public function __construct( array $config, BlockTemplateInterface &$root_template, ContainerInterface &$parent = null ) {
|
||||
if ( ! empty( $config['blockName'] ) ) {
|
||||
throw new \InvalidArgumentException( 'Unexpected key "blockName", this defaults to "woocommerce/product-section".' );
|
||||
}
|
||||
parent::__construct( array_merge( array( 'blockName' => 'woocommerce/product-section' ), $config ), $root_template, $parent );
|
||||
}
|
||||
|
||||
/**
|
||||
* Add a section block type to this template.
|
||||
*
|
||||
* @param array $block_config The block data.
|
||||
*/
|
||||
public function add_section( array $block_config ): SectionInterface {
|
||||
$block = new Section( $block_config, $this->get_root_template(), $this );
|
||||
return $this->add_inner_block( $block );
|
||||
}
|
||||
}
|
||||
@@ -1,878 +0,0 @@
|
||||
<?php
|
||||
/**
|
||||
* SimpleProductTemplate
|
||||
*/
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\Features\ProductBlockEditor\ProductTemplates;
|
||||
|
||||
use Automattic\WooCommerce\Admin\Features\Features;
|
||||
|
||||
/**
|
||||
* Simple Product Template.
|
||||
*/
|
||||
class SimpleProductTemplate extends AbstractProductFormTemplate implements ProductFormTemplateInterface {
|
||||
/**
|
||||
* The context name used to identify the editor.
|
||||
*/
|
||||
const GROUP_IDS = array(
|
||||
'GENERAL' => 'general',
|
||||
'ORGANIZATION' => 'organization',
|
||||
'PRICING' => 'pricing',
|
||||
'INVENTORY' => 'inventory',
|
||||
'SHIPPING' => 'shipping',
|
||||
'VARIATIONS' => 'variations',
|
||||
);
|
||||
|
||||
/**
|
||||
* SimpleProductTemplate constructor.
|
||||
*/
|
||||
public function __construct() {
|
||||
$this->add_group_blocks();
|
||||
$this->add_general_group_blocks();
|
||||
$this->add_organization_group_blocks();
|
||||
$this->add_pricing_group_blocks();
|
||||
$this->add_inventory_group_blocks();
|
||||
$this->add_shipping_group_blocks();
|
||||
$this->add_variation_group_blocks();
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the template ID.
|
||||
*/
|
||||
public function get_id(): string {
|
||||
return 'simple-product';
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the template title.
|
||||
*/
|
||||
public function get_title(): string {
|
||||
return __( 'Simple Product Template', 'woocommerce' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get the template description.
|
||||
*/
|
||||
public function get_description(): string {
|
||||
return __( 'Template for the simple product form', 'woocommerce' );
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the group blocks to the template.
|
||||
*/
|
||||
private function add_group_blocks() {
|
||||
$this->add_group(
|
||||
[
|
||||
'id' => $this::GROUP_IDS['GENERAL'],
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'title' => __( 'General', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
$this->add_group(
|
||||
[
|
||||
'id' => $this::GROUP_IDS['ORGANIZATION'],
|
||||
'order' => 15,
|
||||
'attributes' => [
|
||||
'title' => __( 'Organization', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
$this->add_group(
|
||||
[
|
||||
'id' => $this::GROUP_IDS['PRICING'],
|
||||
'order' => 20,
|
||||
'attributes' => [
|
||||
'title' => __( 'Pricing', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
$this->add_group(
|
||||
[
|
||||
'id' => $this::GROUP_IDS['INVENTORY'],
|
||||
'order' => 30,
|
||||
'attributes' => [
|
||||
'title' => __( 'Inventory', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
$this->add_group(
|
||||
[
|
||||
'id' => $this::GROUP_IDS['SHIPPING'],
|
||||
'order' => 40,
|
||||
'attributes' => [
|
||||
'title' => __( 'Shipping', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
if ( Features::is_enabled( 'product-variation-management' ) ) {
|
||||
$this->add_group(
|
||||
[
|
||||
'id' => $this::GROUP_IDS['VARIATIONS'],
|
||||
'order' => 50,
|
||||
'attributes' => [
|
||||
'title' => __( 'Variations', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the general group blocks to the template.
|
||||
*/
|
||||
private function add_general_group_blocks() {
|
||||
$general_group = $this->get_group_by_id( $this::GROUP_IDS['GENERAL'] );
|
||||
// Basic Details Section.
|
||||
$basic_details = $general_group->add_section(
|
||||
[
|
||||
'id' => 'basic-details',
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'title' => __( 'Basic details', 'woocommerce' ),
|
||||
'description' => __( 'This info will be displayed on the product page, category pages, social media, and search results.', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
$basic_details->add_block(
|
||||
[
|
||||
'id' => 'product-name',
|
||||
'blockName' => 'woocommerce/product-name-field',
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'name' => 'Product name',
|
||||
'autoFocus' => true,
|
||||
],
|
||||
]
|
||||
);
|
||||
$basic_details->add_block(
|
||||
[
|
||||
'id' => 'product-summary',
|
||||
'blockName' => 'woocommerce/product-summary-field',
|
||||
'order' => 20,
|
||||
'attributes' => [
|
||||
'property' => 'short_description',
|
||||
],
|
||||
]
|
||||
);
|
||||
$pricing_columns = $basic_details->add_block(
|
||||
[
|
||||
'id' => 'product-pricing-columns',
|
||||
'blockName' => 'core/columns',
|
||||
'order' => 30,
|
||||
]
|
||||
);
|
||||
$pricing_column_1 = $pricing_columns->add_block(
|
||||
[
|
||||
'id' => 'product-pricing-column-1',
|
||||
'blockName' => 'core/column',
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'templateLock' => 'all',
|
||||
],
|
||||
]
|
||||
);
|
||||
$pricing_column_1->add_block(
|
||||
[
|
||||
'id' => 'product-regular-price',
|
||||
'blockName' => 'woocommerce/product-regular-price-field',
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'name' => 'regular_price',
|
||||
'label' => __( 'List price', 'woocommerce' ),
|
||||
/* translators: PricingTab: This is a link tag to the pricing tab. */
|
||||
'help' => __( 'Manage more settings in <PricingTab>Pricing.</PricingTab>', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
$pricing_column_2 = $pricing_columns->add_block(
|
||||
[
|
||||
'id' => 'product-pricing-column-2',
|
||||
'blockName' => 'core/column',
|
||||
'order' => 20,
|
||||
'attributes' => [
|
||||
'templateLock' => 'all',
|
||||
],
|
||||
]
|
||||
);
|
||||
$pricing_column_2->add_block(
|
||||
[
|
||||
'id' => 'product-sale-price',
|
||||
'blockName' => 'woocommerce/product-sale-price-field',
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'label' => __( 'Sale price', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
// Description section.
|
||||
$description_section = $general_group->add_section(
|
||||
[
|
||||
'id' => 'product-description-section',
|
||||
'order' => 20,
|
||||
'attributes' => [
|
||||
'title' => __( 'Description', 'woocommerce' ),
|
||||
'description' => __( 'What makes this product unique? What are its most important features? Enrich the product page by adding rich content using blocks.', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
$description_section->add_block(
|
||||
[
|
||||
'id' => 'product-description',
|
||||
'blockName' => 'woocommerce/product-description-field',
|
||||
'order' => 10,
|
||||
]
|
||||
);
|
||||
// Images section.
|
||||
$images_section = $general_group->add_section(
|
||||
[
|
||||
'id' => 'product-images-section',
|
||||
'order' => 30,
|
||||
'attributes' => [
|
||||
'title' => __( 'Images', 'woocommerce' ),
|
||||
'description' => sprintf(
|
||||
/* translators: %1$s: Images guide link opening tag. %2$s: Images guide link closing tag. */
|
||||
__( 'Drag images, upload new ones or select files from your library. For best results, use JPEG files that are 1000 by 1000 pixels or larger. %1$sHow to prepare images?%2$s', 'woocommerce' ),
|
||||
'<a href="https://woocommerce.com/posts/how-to-take-professional-product-photos-top-tips" target="_blank" rel="noreferrer">',
|
||||
'</a>'
|
||||
),
|
||||
],
|
||||
]
|
||||
);
|
||||
$images_section->add_block(
|
||||
[
|
||||
'id' => 'product-images',
|
||||
'blockName' => 'woocommerce/product-images-field',
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'images' => [],
|
||||
'property' => 'images',
|
||||
],
|
||||
]
|
||||
);
|
||||
// Downloads section.
|
||||
if ( Features::is_enabled( 'product-virtual-downloadable' ) ) {
|
||||
$general_group->add_section(
|
||||
[
|
||||
'id' => 'product-downloads-section',
|
||||
'order' => 40,
|
||||
'attributes' => [
|
||||
'title' => __( 'Downloads', 'woocommerce' ),
|
||||
'description' => __( "Add any files you'd like to make available for the customer to download after purchasing, such as instructions or warranty info.", 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
)->add_block(
|
||||
[
|
||||
'id' => 'product-downloads',
|
||||
'blockName' => 'woocommerce/product-downloads-field',
|
||||
'order' => 10,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the organization group blocks to the template.
|
||||
*/
|
||||
private function add_organization_group_blocks() {
|
||||
$organization_group = $this->get_group_by_id( $this::GROUP_IDS['ORGANIZATION'] );
|
||||
// Product Catalog Section.
|
||||
$product_catalog_section = $organization_group->add_section(
|
||||
[
|
||||
'id' => 'product-catalog-section',
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'title' => __( 'Product catalog', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_catalog_section->add_block(
|
||||
[
|
||||
'id' => 'product-categories',
|
||||
'blockName' => 'woocommerce/product-taxonomy-field',
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'slug' => 'product_cat',
|
||||
'property' => 'categories',
|
||||
'label' => __( 'Categories', 'woocommerce' ),
|
||||
'createTitle' => __( 'Create new category', 'woocommerce' ),
|
||||
'dialogNameHelpText' => __( 'Shown to customers on the product page.', 'woocommerce' ),
|
||||
'parentTaxonomyText' => __( 'Parent category', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_catalog_section->add_block(
|
||||
[
|
||||
'id' => 'product-tags',
|
||||
'blockName' => 'woocommerce/product-tag-field',
|
||||
'attributes' => [
|
||||
'name' => 'tags',
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_catalog_section->add_block(
|
||||
[
|
||||
'id' => 'product-catalog-search-visibility',
|
||||
'blockName' => 'woocommerce/product-catalog-visibility-field',
|
||||
'order' => 20,
|
||||
'attributes' => [
|
||||
'label' => __( 'Hide in product catalog', 'woocommerce' ),
|
||||
'visibility' => 'search',
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_catalog_section->add_block(
|
||||
[
|
||||
'id' => 'product-catalog-catalog-visibility',
|
||||
'blockName' => 'woocommerce/product-catalog-visibility-field',
|
||||
'order' => 30,
|
||||
'attributes' => [
|
||||
'label' => __( 'Hide from search results', 'woocommerce' ),
|
||||
'visibility' => 'catalog',
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_catalog_section->add_block(
|
||||
[
|
||||
'id' => 'product-enable-product-reviews',
|
||||
'blockName' => 'woocommerce/product-checkbox-field',
|
||||
'order' => 40,
|
||||
'attributes' => [
|
||||
'label' => __( 'Enable product reviews', 'woocommerce' ),
|
||||
'property' => 'reviews_allowed',
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_catalog_section->add_block(
|
||||
[
|
||||
'id' => 'product-post-password',
|
||||
'blockName' => 'woocommerce/product-password-field',
|
||||
'order' => 50,
|
||||
'attributes' => [
|
||||
'label' => __( 'Require a password', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
// Attributes section.
|
||||
$product_catalog_section = $organization_group->add_section(
|
||||
[
|
||||
'id' => 'product-attributes-section',
|
||||
'order' => 20,
|
||||
'attributes' => [
|
||||
'title' => __( 'Attributes', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_catalog_section->add_block(
|
||||
[
|
||||
'id' => 'product-attributes',
|
||||
'blockName' => 'woocommerce/product-attributes-field',
|
||||
'order' => 10,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the pricing group blocks to the template.
|
||||
*/
|
||||
private function add_pricing_group_blocks() {
|
||||
$pricing_group = $this->get_group_by_id( $this::GROUP_IDS['PRICING'] );
|
||||
$pricing_group->add_block(
|
||||
[
|
||||
'id' => 'pricing-has-variations-notice',
|
||||
'blockName' => 'woocommerce/product-has-variations-notice',
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'content' => __( 'This product has options, such as size or color. You can now manage each variation\'s price and other details individually.', 'woocommerce' ),
|
||||
'buttonText' => __( 'Go to Variations', 'woocommerce' ),
|
||||
'type' => 'info',
|
||||
],
|
||||
]
|
||||
);
|
||||
// Product Pricing Section.
|
||||
$product_pricing_section = $pricing_group->add_section(
|
||||
[
|
||||
'id' => 'product-pricing-section',
|
||||
'order' => 20,
|
||||
'attributes' => [
|
||||
'title' => __( 'Pricing', 'woocommerce' ),
|
||||
'description' => sprintf(
|
||||
/* translators: %1$s: Images guide link opening tag. %2$s: Images guide link closing tag.*/
|
||||
__( 'Set a competitive price, put the product on sale, and manage tax calculations. %1$sHow to price your product?%2$s', 'woocommerce' ),
|
||||
'<a href="https://woocommerce.com/posts/how-to-price-products-strategies-expert-tips/" target="_blank" rel="noreferrer">',
|
||||
'</a>'
|
||||
),
|
||||
'blockGap' => 'unit-40',
|
||||
],
|
||||
]
|
||||
);
|
||||
$pricing_columns = $product_pricing_section->add_block(
|
||||
[
|
||||
'id' => 'product-pricing-group-pricing-columns',
|
||||
'blockName' => 'core/columns',
|
||||
'order' => 10,
|
||||
]
|
||||
);
|
||||
$pricing_column_1 = $pricing_columns->add_block(
|
||||
[
|
||||
'id' => 'product-pricing-group-pricing-column-1',
|
||||
'blockName' => 'core/column',
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'templateLock' => 'all',
|
||||
],
|
||||
]
|
||||
);
|
||||
$pricing_column_1->add_block(
|
||||
[
|
||||
'id' => 'product-pricing-regular-price',
|
||||
'blockName' => 'woocommerce/product-regular-price-field',
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'name' => 'regular_price',
|
||||
'label' => __( 'List price', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
$pricing_column_2 = $pricing_columns->add_block(
|
||||
[
|
||||
'id' => 'product-pricing-group-pricing-column-2',
|
||||
'blockName' => 'core/column',
|
||||
'order' => 20,
|
||||
'attributes' => [
|
||||
'templateLock' => 'all',
|
||||
],
|
||||
]
|
||||
);
|
||||
$pricing_column_2->add_block(
|
||||
[
|
||||
'id' => 'product-pricing-sale-price',
|
||||
'blockName' => 'woocommerce/product-sale-price-field',
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'label' => __( 'Sale price', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_pricing_section->add_block(
|
||||
[
|
||||
'id' => 'product-pricing-schedule-sale-fields',
|
||||
'blockName' => 'woocommerce/product-schedule-sale-fields',
|
||||
'order' => 20,
|
||||
]
|
||||
);
|
||||
$product_pricing_section->add_block(
|
||||
[
|
||||
'id' => 'product-sale-tax',
|
||||
'blockName' => 'woocommerce/product-radio-field',
|
||||
'order' => 30,
|
||||
'attributes' => [
|
||||
'title' => __( 'Charge sales tax on', 'woocommerce' ),
|
||||
'property' => 'tax_status',
|
||||
'options' => [
|
||||
[
|
||||
'label' => __( 'Product and shipping', 'woocommerce' ),
|
||||
'value' => 'taxable',
|
||||
],
|
||||
[
|
||||
'label' => __( 'Only shipping', 'woocommerce' ),
|
||||
'value' => 'shipping',
|
||||
],
|
||||
[
|
||||
'label' => __( "Don't charge tax", 'woocommerce' ),
|
||||
'value' => 'none',
|
||||
],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
$pricing_advanced_block = $product_pricing_section->add_block(
|
||||
[
|
||||
'id' => 'product-pricing-advanced',
|
||||
'blockName' => 'woocommerce/product-collapsible',
|
||||
'order' => 40,
|
||||
'attributes' => [
|
||||
'toggleText' => __( 'Advanced', 'woocommerce' ),
|
||||
'initialCollapsed' => true,
|
||||
'persistRender' => true,
|
||||
],
|
||||
]
|
||||
);
|
||||
$pricing_advanced_block->add_block(
|
||||
[
|
||||
'id' => 'product-tax-class',
|
||||
'blockName' => 'woocommerce/product-radio-field',
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'title' => __( 'Tax class', 'woocommerce' ),
|
||||
'description' => sprintf(
|
||||
/* translators: %1$s: Learn more link opening tag. %2$s: Learn more link closing tag.*/
|
||||
__( 'Apply a tax rate if this product qualifies for tax reduction or exemption. %1$sLearn more%2$s.', 'woocommerce' ),
|
||||
'<a href="https://woocommerce.com/document/setting-up-taxes-in-woocommerce/#shipping-tax-class" target="_blank" rel="noreferrer">',
|
||||
'</a>'
|
||||
),
|
||||
'property' => 'tax_class',
|
||||
'options' => [
|
||||
[
|
||||
'label' => __( 'Standard', 'woocommerce' ),
|
||||
'value' => '',
|
||||
],
|
||||
[
|
||||
'label' => __( 'Reduced rate', 'woocommerce' ),
|
||||
'value' => 'reduced-rate',
|
||||
],
|
||||
[
|
||||
'label' => __( 'Zero rate', 'woocommerce' ),
|
||||
'value' => 'zero-rate',
|
||||
],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the inventory group blocks to the template.
|
||||
*/
|
||||
private function add_inventory_group_blocks() {
|
||||
$inventory_group = $this->get_group_by_id( $this::GROUP_IDS['INVENTORY'] );
|
||||
$inventory_group->add_block(
|
||||
[
|
||||
'id' => 'product_variation_notice_inventory_tab',
|
||||
'blockName' => 'woocommerce/product-has-variations-notice',
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'content' => __( 'This product has options, such as size or color. You can now manage each variation\'s price and other details individually.', 'woocommerce' ),
|
||||
'buttonText' => __( 'Go to Variations', 'woocommerce' ),
|
||||
'type' => 'info',
|
||||
],
|
||||
]
|
||||
);
|
||||
// Product Pricing Section.
|
||||
$product_inventory_section = $inventory_group->add_section(
|
||||
[
|
||||
'id' => 'product-inventory-section',
|
||||
'order' => 20,
|
||||
'attributes' => [
|
||||
'title' => __( 'Inventory', 'woocommerce' ),
|
||||
'description' => sprintf(
|
||||
/* translators: %1$s: Inventory settings link opening tag. %2$s: Inventory settings link closing tag.*/
|
||||
__( 'Set up and manage inventory for this product, including status and available quantity. %1$sManage store inventory settings%2$s', 'woocommerce' ),
|
||||
'<a href="' . admin_url( 'admin.php?page=wc-settings&tab=products§ion=inventory' ) . '" target="_blank" rel="noreferrer">',
|
||||
'</a>'
|
||||
),
|
||||
'blockGap' => 'unit-40',
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_inventory_inner_section = $product_inventory_section->add_section(
|
||||
[
|
||||
'id' => 'product-inventory-inner-section',
|
||||
'order' => 10,
|
||||
]
|
||||
);
|
||||
$product_inventory_inner_section->add_block(
|
||||
[
|
||||
'id' => 'product-sku-field',
|
||||
'blockName' => 'woocommerce/product-sku-field',
|
||||
'order' => 10,
|
||||
]
|
||||
);
|
||||
$product_inventory_inner_section->add_block(
|
||||
[
|
||||
'id' => 'product-track-stock',
|
||||
'blockName' => 'woocommerce/product-toggle-field',
|
||||
'order' => 20,
|
||||
'attributes' => [
|
||||
'label' => __( 'Track stock quantity for this product', 'woocommerce' ),
|
||||
'property' => 'manage_stock',
|
||||
'disabled' => 'yes' !== get_option( 'woocommerce_manage_stock' ),
|
||||
'disabledCopy' => sprintf(
|
||||
/* translators: %1$s: Learn more link opening tag. %2$s: Learn more link closing tag.*/
|
||||
__( 'Per your %1$sstore settings%2$s, inventory management is <strong>disabled</strong>.', 'woocommerce' ),
|
||||
'<a href="' . admin_url( 'admin.php?page=wc-settings&tab=products§ion=inventory' ) . '" target="_blank" rel="noreferrer">',
|
||||
'</a>'
|
||||
),
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_inventory_quantity_conditional = $product_inventory_inner_section->add_block(
|
||||
[
|
||||
'id' => 'product-inventory-quantity-conditional-wrapper',
|
||||
'blockName' => 'woocommerce/conditional',
|
||||
'order' => 30,
|
||||
'attributes' => [
|
||||
'mustMatch' => [
|
||||
'manage_stock' => [ true ],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_inventory_quantity_conditional->add_block(
|
||||
[
|
||||
'id' => 'product-inventory-quantity',
|
||||
'blockName' => 'woocommerce/product-inventory-quantity-field',
|
||||
'order' => 10,
|
||||
]
|
||||
);
|
||||
$product_stock_status_conditional = $product_inventory_section->add_block(
|
||||
[
|
||||
'id' => 'product-stock-status-conditional-wrapper',
|
||||
'blockName' => 'woocommerce/conditional',
|
||||
'order' => 20,
|
||||
'attributes' => [
|
||||
'mustMatch' => [
|
||||
'manage_stock' => [ false ],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_stock_status_conditional->add_block(
|
||||
[
|
||||
'id' => 'product-stock-status',
|
||||
'blockName' => 'woocommerce/product-radio-field',
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'title' => __( 'Stock status', 'woocommerce' ),
|
||||
'property' => 'stock_status',
|
||||
'options' => [
|
||||
[
|
||||
'label' => __( 'In stock', 'woocommerce' ),
|
||||
'value' => 'instock',
|
||||
],
|
||||
[
|
||||
'label' => __( 'Out of stock', 'woocommerce' ),
|
||||
'value' => 'outofstock',
|
||||
],
|
||||
[
|
||||
'label' => __( 'On backorder', 'woocommerce' ),
|
||||
'value' => 'onbackorder',
|
||||
],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_inventory_advanced = $product_inventory_section->add_block(
|
||||
[
|
||||
'id' => 'product-inventory-advanced',
|
||||
'blockName' => 'woocommerce/product-collapsible',
|
||||
'order' => 30,
|
||||
'attributes' => [
|
||||
'toggleText' => __( 'Advanced', 'woocommerce' ),
|
||||
'initialCollapsed' => true,
|
||||
'persistRender' => true,
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_inventory_advanced_wrapper = $product_inventory_advanced->add_block(
|
||||
[
|
||||
'blockName' => 'woocommerce/product-section',
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'blockGap' => 'unit-40',
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_out_of_stock_conditional = $product_inventory_advanced_wrapper->add_block(
|
||||
[
|
||||
'id' => 'product-out-of-stock-conditional-wrapper',
|
||||
'blockName' => 'woocommerce/conditional',
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'mustMatch' => [
|
||||
'manage_stock' => [ true ],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_out_of_stock_conditional->add_block(
|
||||
[
|
||||
'id' => 'product-out-of-stock',
|
||||
'blockName' => 'woocommerce/product-radio-field',
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'title' => __( 'When out of stock', 'woocommerce' ),
|
||||
'property' => 'backorders',
|
||||
'options' => [
|
||||
[
|
||||
'label' => __( 'Allow purchases', 'woocommerce' ),
|
||||
'value' => 'yes',
|
||||
],
|
||||
[
|
||||
'label' => __(
|
||||
'Allow purchases, but notify customers',
|
||||
'woocommerce'
|
||||
),
|
||||
'value' => 'notify',
|
||||
],
|
||||
[
|
||||
'label' => __( "Don't allow purchases", 'woocommerce' ),
|
||||
'value' => 'no',
|
||||
],
|
||||
],
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_out_of_stock_conditional->add_block(
|
||||
[
|
||||
'id' => 'product-inventory-email',
|
||||
'blockName' => 'woocommerce/product-inventory-email-field',
|
||||
'order' => 20,
|
||||
]
|
||||
);
|
||||
|
||||
$product_inventory_advanced_wrapper->add_block(
|
||||
[
|
||||
'id' => 'product-limit-purchase',
|
||||
'blockName' => 'woocommerce/product-checkbox-field',
|
||||
'order' => 20,
|
||||
'attributes' => [
|
||||
'title' => __(
|
||||
'Restrictions',
|
||||
'woocommerce'
|
||||
),
|
||||
'label' => __(
|
||||
'Limit purchases to 1 item per order',
|
||||
'woocommerce'
|
||||
),
|
||||
'property' => 'sold_individually',
|
||||
'tooltip' => __(
|
||||
'When checked, customers will be able to purchase only 1 item in a single order. This is particularly useful for items that have limited quantity, like art or handmade goods.',
|
||||
'woocommerce'
|
||||
),
|
||||
],
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the shipping group blocks to the template.
|
||||
*/
|
||||
private function add_shipping_group_blocks() {
|
||||
$shipping_group = $this->get_group_by_id( $this::GROUP_IDS['SHIPPING'] );
|
||||
$shipping_group->add_block(
|
||||
[
|
||||
'id' => 'product_variation_notice_shipping_tab',
|
||||
'blockName' => 'woocommerce/product-has-variations-notice',
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'content' => __( 'This product has options, such as size or color. You can now manage each variation\'s price and other details individually.', 'woocommerce' ),
|
||||
'buttonText' => __( 'Go to Variations', 'woocommerce' ),
|
||||
'type' => 'info',
|
||||
],
|
||||
]
|
||||
);
|
||||
// Virtual section.
|
||||
$shipping_group->add_section(
|
||||
[
|
||||
'id' => 'product-virtual-section',
|
||||
'order' => 10,
|
||||
]
|
||||
)->add_block(
|
||||
[
|
||||
'id' => 'product-virtual',
|
||||
'blockName' => 'woocommerce/product-toggle-field',
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'property' => 'virtual',
|
||||
'checkedValue' => false,
|
||||
'uncheckedValue' => true,
|
||||
'label' => __( 'This product requires shipping or pickup', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
// Product Shipping Section.
|
||||
$product_fee_and_dimensions_section = $shipping_group->add_section(
|
||||
[
|
||||
'id' => 'product-fee-and-dimensions-section',
|
||||
'order' => 20,
|
||||
'attributes' => [
|
||||
'title' => __( 'Fees & dimensions', 'woocommerce' ),
|
||||
'description' => sprintf(
|
||||
/* translators: %1$s: How to get started? link opening tag. %2$s: How to get started? link closing tag.*/
|
||||
__( 'Set up shipping costs and enter dimensions used for accurate rate calculations. %1$sHow to get started?%2$s.', 'woocommerce' ),
|
||||
'<a href="https://woocommerce.com/posts/how-to-calculate-shipping-costs-for-your-woocommerce-store/" target="_blank" rel="noreferrer">',
|
||||
'</a>'
|
||||
),
|
||||
],
|
||||
]
|
||||
);
|
||||
$product_fee_and_dimensions_section->add_block(
|
||||
[
|
||||
'id' => 'product-shipping-class',
|
||||
'blockName' => 'woocommerce/product-shipping-class-field',
|
||||
'order' => 10,
|
||||
]
|
||||
);
|
||||
$product_fee_and_dimensions_section->add_block(
|
||||
[
|
||||
'id' => 'product-shipping-dimensions',
|
||||
'blockName' => 'woocommerce/product-shipping-dimensions-fields',
|
||||
'order' => 20,
|
||||
]
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Adds the variation group blocks to the template.
|
||||
*/
|
||||
private function add_variation_group_blocks() {
|
||||
$variation_group = $this->get_group_by_id( $this::GROUP_IDS['VARIATIONS'] );
|
||||
if ( ! $variation_group ) {
|
||||
return;
|
||||
}
|
||||
$variation_fields = $variation_group->add_block(
|
||||
[
|
||||
'id' => 'product_variation-field-group',
|
||||
'blockName' => 'woocommerce/product-variations-fields',
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'description' => sprintf(
|
||||
/* translators: %1$s: Sell your product in multiple variations like size or color. strong opening tag. %2$s: Sell your product in multiple variations like size or color. strong closing tag.*/
|
||||
__( '%1$sSell your product in multiple variations like size or color.%2$s Get started by adding options for the buyers to choose on the product page.', 'woocommerce' ),
|
||||
'<strong>',
|
||||
'</strong>'
|
||||
),
|
||||
],
|
||||
]
|
||||
);
|
||||
$variation_options_section = $variation_fields->add_block(
|
||||
[
|
||||
'id' => 'product-variation-options-section',
|
||||
'blockName' => 'woocommerce/product-section',
|
||||
'order' => 10,
|
||||
'attributes' => [
|
||||
'title' => __( 'Variation options', 'woocommerce' ),
|
||||
'description' => __( 'Add and manage attributes used for product options, such as size and color.', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
$variation_options_section->add_block(
|
||||
[
|
||||
'id' => 'product-variation-options',
|
||||
'blockName' => 'woocommerce/product-variations-options-field',
|
||||
]
|
||||
);
|
||||
$variation_section = $variation_fields->add_block(
|
||||
[
|
||||
'id' => 'product-variation-section',
|
||||
'blockName' => 'woocommerce/product-section',
|
||||
'order' => 20,
|
||||
'attributes' => [
|
||||
'title' => __( 'Variations', 'woocommerce' ),
|
||||
'description' => __( 'Manage individual product combinations created from options.', 'woocommerce' ),
|
||||
],
|
||||
]
|
||||
);
|
||||
|
||||
$variation_section->add_block(
|
||||
[
|
||||
'id' => 'product-variation-items',
|
||||
'blockName' => 'woocommerce/product-variation-items-field',
|
||||
'order' => 10,
|
||||
]
|
||||
);
|
||||
}
|
||||
}
|
||||
@@ -111,7 +111,7 @@ class DefaultShippingPartners {
|
||||
'image' => $asset_base_url . 'envia-column.svg',
|
||||
'features' => $column_layout_features,
|
||||
),
|
||||
'learn_more_link' => 'https://woocommerce.com/products/envia-shipping-and-fulfillment/',
|
||||
'learn_more_link' => 'https://woo.com/products/envia-shipping-and-fulfillment/',
|
||||
'is_visible' => array(
|
||||
self::get_rules_for_countries( array( 'CL', 'AR', 'PE', 'BR', 'UY', 'GT' ) ),
|
||||
),
|
||||
@@ -233,7 +233,7 @@ class DefaultShippingPartners {
|
||||
),
|
||||
),
|
||||
),
|
||||
'learn_more_link' => 'https://woocommerce.com/products/shipping/',
|
||||
'learn_more_link' => 'https://woo.com/products/shipping/',
|
||||
'is_visible' => array(
|
||||
self::get_rules_for_countries( array( 'US' ) ),
|
||||
),
|
||||
|
||||
@@ -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://woocommerce.com/document/pinterest-for-woocommerce/?utm_medium=product';
|
||||
$data['docsUrl'] = 'https://woo.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://woocommerce.com/document/google-listings-and-ads/?utm_medium=product';
|
||||
$data['docsUrl'] = 'https://woo.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://woocommerce.com/document/multichannel-for-woocommerce-google-amazon-ebay-walmart-integration/?utm_medium=product';
|
||||
$data['docsUrl'] = 'https://woo.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://woocommerce.com/document/tiktok-for-woocommerce/';
|
||||
$data['docsUrl'] = 'https://woo.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://woocommerce.com/document/salesforce-integration/';
|
||||
$data['docsUrl'] = 'https://woo.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://woocommerce.com/document/vimeo/';
|
||||
$data['docsUrl'] = 'https://woo.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://woocommerce.com/document/trustpilot-reviews/';
|
||||
$data['docsUrl'] = 'https://woo.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://woocommerce.com/my-account/create-a-ticket/?utm_medium=product',
|
||||
'supportUrl' => 'https://woo.com/my-account/create-a-ticket/?utm_medium=product',
|
||||
];
|
||||
}
|
||||
|
||||
|
||||
@@ -48,6 +48,8 @@ class GetRuleProcessor {
|
||||
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':
|
||||
|
||||
@@ -0,0 +1,69 @@
|
||||
<?php
|
||||
/**
|
||||
* Rule processor that passes (or fails) when the site is on a Woo Express plan.
|
||||
*
|
||||
* @package WooCommerce\Admin\Classes
|
||||
*/
|
||||
|
||||
namespace Automattic\WooCommerce\Admin\RemoteInboxNotifications;
|
||||
|
||||
defined( 'ABSPATH' ) || exit;
|
||||
|
||||
/**
|
||||
* 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.
|
||||
*/
|
||||
class IsWooExpressRuleProcessor implements RuleProcessorInterface {
|
||||
/**
|
||||
* Passes (or fails) based on whether the site is a Woo Express plan.
|
||||
*
|
||||
* @param object $rule The 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 ) {
|
||||
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;
|
||||
}
|
||||
|
||||
/**
|
||||
* Validate 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->plan ) ) {
|
||||
if ( ! function_exists( 'wc_calypso_bridge_is_woo_express_plan' ) ) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user