Add unique_id field to product (#47364)
* Add unique_id field to product * Fix documentation * Fix wrong comment * Update description * Add unique_id for variations * Update lint * Update tests * Add changelog * Update variations unit test * Add unique_id to wc_product_meta_lookup * Add unique_id methods to cpt interface * Add new methods for unique_id and add it to lookup table * Add unique_id functions to product functions * Throw error when unique_id is duplicated * Handle error message for unique_id on the front-end * Add changelog * Rename unique_id description in REST API * Fix lint issues * Add unique_id tracking for product publish * Rename to 'global_unique_id' * Fix lint * Fix lint * Bump documentation version * Update controller description of fields
This commit is contained in:
parent
496df1b7a2
commit
85cedf2d2b
|
@ -0,0 +1,4 @@
|
|||
Significance: patch
|
||||
Type: update
|
||||
|
||||
Handle unique id error message
|
|
@ -7,6 +7,7 @@ export type WPErrorCode =
|
|||
| 'variable_product_no_variation_prices'
|
||||
| 'product_form_field_error'
|
||||
| 'product_invalid_sku'
|
||||
| 'product_invalid_global_unique_id'
|
||||
| 'product_create_error'
|
||||
| 'product_publish_error'
|
||||
| 'product_preview_error';
|
||||
|
@ -56,6 +57,15 @@ export function getProductErrorMessageAndProps(
|
|||
response.errorProps = { explicitDismiss: true };
|
||||
}
|
||||
break;
|
||||
case 'product_invalid_global_unique_id':
|
||||
response.message = __(
|
||||
'Invalid or duplicated GTIN, UPC, EAN or ISBN.',
|
||||
'woocommerce'
|
||||
);
|
||||
if ( visibleTab !== 'inventory' ) {
|
||||
response.errorProps = { explicitDismiss: true };
|
||||
}
|
||||
break;
|
||||
case 'product_create_error':
|
||||
response.message = __( 'Failed to create product.', 'woocommerce' );
|
||||
break;
|
||||
|
|
|
@ -0,0 +1,4 @@
|
|||
Significance: minor
|
||||
Type: add
|
||||
|
||||
Adds global_unique_id field to product and product variations
|
|
@ -65,6 +65,7 @@ class WC_Product extends WC_Abstract_Legacy_Product {
|
|||
'description' => '',
|
||||
'short_description' => '',
|
||||
'sku' => '',
|
||||
'global_unique_id' => '',
|
||||
'price' => '',
|
||||
'regular_price' => '',
|
||||
'sale_price' => '',
|
||||
|
@ -251,7 +252,7 @@ class WC_Product extends WC_Abstract_Legacy_Product {
|
|||
}
|
||||
|
||||
/**
|
||||
* Get SKU (Stock-keeping unit) - product unique ID.
|
||||
* Get SKU (Stock-keeping unit).
|
||||
*
|
||||
* @param string $context What the value is for. Valid values are view and edit.
|
||||
* @return string
|
||||
|
@ -260,6 +261,17 @@ class WC_Product extends WC_Abstract_Legacy_Product {
|
|||
return $this->get_prop( 'sku', $context );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get Unique ID.
|
||||
*
|
||||
* @since 9.1.0
|
||||
* @param string $context What the value is for. Valid values are view and edit.
|
||||
* @return string
|
||||
*/
|
||||
public function get_global_unique_id( $context = 'view' ) {
|
||||
return $this->get_prop( 'global_unique_id', $context );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the product's active price.
|
||||
*
|
||||
|
@ -835,6 +847,29 @@ class WC_Product extends WC_Abstract_Legacy_Product {
|
|||
$this->set_prop( 'sku', $sku );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set global_unique_id
|
||||
*
|
||||
* @since 9.1.0
|
||||
* @param string $global_unique_id Unique ID.
|
||||
*/
|
||||
public function set_global_unique_id( $global_unique_id ) {
|
||||
$global_unique_id = (string) $global_unique_id;
|
||||
if ( $this->get_object_read() && ! empty( $global_unique_id ) && ! wc_product_has_global_unique_id( $this->get_id(), $global_unique_id ) ) {
|
||||
$global_unique_id_found = wc_get_product_id_by_global_unique_id( $global_unique_id );
|
||||
|
||||
$this->error(
|
||||
'product_invalid_global_unique_id',
|
||||
__( 'Invalid or duplicated Unique ID.', 'woocommerce' ),
|
||||
400,
|
||||
array(
|
||||
'resource_id' => $global_unique_id_found,
|
||||
)
|
||||
);
|
||||
}
|
||||
$this->set_prop( 'global_unique_id', $global_unique_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Set the product's active price.
|
||||
*
|
||||
|
|
|
@ -1635,6 +1635,7 @@ CREATE TABLE {$wpdb->prefix}wc_download_log (
|
|||
CREATE TABLE {$wpdb->prefix}wc_product_meta_lookup (
|
||||
`product_id` bigint(20) NOT NULL,
|
||||
`sku` varchar(100) NULL default '',
|
||||
`global_unique_id` varchar(100) NULL default '',
|
||||
`virtual` tinyint(1) NULL default 0,
|
||||
`downloadable` tinyint(1) NULL default 0,
|
||||
`min_price` decimal(19,4) NULL default NULL,
|
||||
|
|
|
@ -29,6 +29,7 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da
|
|||
protected $internal_meta_keys = array(
|
||||
'_visibility',
|
||||
'_sku',
|
||||
'_global_unique_id',
|
||||
'_price',
|
||||
'_regular_price',
|
||||
'_sale_price',
|
||||
|
@ -386,6 +387,7 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da
|
|||
$post_meta_values = get_post_meta( $id );
|
||||
$meta_key_to_props = array(
|
||||
'_sku' => 'sku',
|
||||
'_global_unique_id' => 'global_unique_id',
|
||||
'_regular_price' => 'regular_price',
|
||||
'_sale_price' => 'sale_price',
|
||||
'_price' => 'price',
|
||||
|
@ -577,6 +579,7 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da
|
|||
protected function update_post_meta( &$product, $force = false ) {
|
||||
$meta_key_to_props = array(
|
||||
'_sku' => 'sku',
|
||||
'_global_unique_id' => 'global_unique_id',
|
||||
'_regular_price' => 'regular_price',
|
||||
'_sale_price' => 'sale_price',
|
||||
'_sale_price_dates_from' => 'date_on_sale_from',
|
||||
|
@ -743,7 +746,7 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da
|
|||
}
|
||||
}
|
||||
|
||||
if ( array_intersect( $this->updated_props, array( 'sku', 'regular_price', 'sale_price', 'date_on_sale_from', 'date_on_sale_to', 'total_sales', 'average_rating', 'stock_quantity', 'stock_status', 'manage_stock', 'downloadable', 'virtual', 'tax_status', 'tax_class' ) ) ) {
|
||||
if ( array_intersect( $this->updated_props, array( 'sku', 'global_unique_id', 'regular_price', 'sale_price', 'date_on_sale_from', 'date_on_sale_to', 'total_sales', 'average_rating', 'stock_quantity', 'stock_status', 'manage_stock', 'downloadable', 'virtual', 'tax_status', 'tax_class' ) ) ) {
|
||||
$this->update_lookup_table( $product->get_id(), 'wc_product_meta_lookup' );
|
||||
}
|
||||
|
||||
|
@ -1069,6 +1072,37 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da
|
|||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if product sku is found for any other product IDs.
|
||||
*
|
||||
* @since 9.1.0
|
||||
* @param int $product_id Product ID.
|
||||
* @param string $global_unique_id Will be slashed to work around https://core.trac.wordpress.org/ticket/27421.
|
||||
* @return bool
|
||||
*/
|
||||
public function is_existing_global_unique_id( $product_id, $global_unique_id ) {
|
||||
global $wpdb;
|
||||
|
||||
// phpcs:ignore WordPress.VIP.DirectDatabaseQuery.DirectQuery
|
||||
return (bool) $wpdb->get_var(
|
||||
$wpdb->prepare(
|
||||
"
|
||||
SELECT posts.ID
|
||||
FROM {$wpdb->posts} as posts
|
||||
INNER JOIN {$wpdb->wc_product_meta_lookup} AS lookup ON posts.ID = lookup.product_id
|
||||
WHERE
|
||||
posts.post_type IN ( 'product', 'product_variation' )
|
||||
AND posts.post_status != 'trash'
|
||||
AND lookup.global_unique_id = %s
|
||||
AND lookup.product_id <> %d
|
||||
LIMIT 1
|
||||
",
|
||||
wp_slash( $global_unique_id ),
|
||||
$product_id
|
||||
)
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return product ID based on SKU.
|
||||
*
|
||||
|
@ -1099,6 +1133,42 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da
|
|||
return (int) apply_filters( 'woocommerce_get_product_id_by_sku', $id, $sku );
|
||||
}
|
||||
|
||||
/**
|
||||
* Return product ID based on Unique ID.
|
||||
*
|
||||
* @since 9.1.0
|
||||
* @param string $global_unique_id Product Unique ID.
|
||||
* @return int
|
||||
*/
|
||||
public function get_product_id_by_global_unique_id( $global_unique_id ) {
|
||||
global $wpdb;
|
||||
|
||||
// phpcs:ignore WordPress.VIP.DirectDatabaseQuery.DirectQuery
|
||||
$id = $wpdb->get_var(
|
||||
$wpdb->prepare(
|
||||
"
|
||||
SELECT posts.ID
|
||||
FROM {$wpdb->posts} as posts
|
||||
INNER JOIN {$wpdb->wc_product_meta_lookup} AS lookup ON posts.ID = lookup.product_id
|
||||
WHERE
|
||||
posts.post_type IN ( 'product', 'product_variation' )
|
||||
AND posts.post_status != 'trash'
|
||||
AND lookup.global_unique_id = %s
|
||||
LIMIT 1
|
||||
",
|
||||
$global_unique_id
|
||||
)
|
||||
);
|
||||
/**
|
||||
* Hook woocommerce_get_product_id_by_global_unique_id.
|
||||
*
|
||||
* @since 9.1.0
|
||||
* @param mixed $id List of post statuses.
|
||||
* @param string $global_unique_id Unique ID.
|
||||
*/
|
||||
return (int) apply_filters( 'woocommerce_get_product_id_by_global_unique_id', $id, $global_unique_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns an array of IDs of products that have sales starting soon.
|
||||
*
|
||||
|
@ -2168,20 +2238,21 @@ class WC_Product_Data_Store_CPT extends WC_Data_Store_WP implements WC_Object_Da
|
|||
$price = wc_format_decimal( get_post_meta( $id, '_price', true ) );
|
||||
$sale_price = wc_format_decimal( get_post_meta( $id, '_sale_price', true ) );
|
||||
return array(
|
||||
'product_id' => absint( $id ),
|
||||
'sku' => get_post_meta( $id, '_sku', true ),
|
||||
'virtual' => 'yes' === get_post_meta( $id, '_virtual', true ) ? 1 : 0,
|
||||
'downloadable' => 'yes' === get_post_meta( $id, '_downloadable', true ) ? 1 : 0,
|
||||
'min_price' => reset( $price_meta ),
|
||||
'max_price' => end( $price_meta ),
|
||||
'onsale' => $sale_price && $price === $sale_price ? 1 : 0,
|
||||
'stock_quantity' => $stock,
|
||||
'stock_status' => get_post_meta( $id, '_stock_status', true ),
|
||||
'rating_count' => array_sum( array_map( 'intval', (array) get_post_meta( $id, '_wc_rating_count', true ) ) ),
|
||||
'average_rating' => get_post_meta( $id, '_wc_average_rating', true ),
|
||||
'total_sales' => get_post_meta( $id, 'total_sales', true ),
|
||||
'tax_status' => get_post_meta( $id, '_tax_status', true ),
|
||||
'tax_class' => get_post_meta( $id, '_tax_class', true ),
|
||||
'product_id' => absint( $id ),
|
||||
'sku' => get_post_meta( $id, '_sku', true ),
|
||||
'global_unique_id' => get_post_meta( $id, '_global_unique_id', true ),
|
||||
'virtual' => 'yes' === get_post_meta( $id, '_virtual', true ) ? 1 : 0,
|
||||
'downloadable' => 'yes' === get_post_meta( $id, '_downloadable', true ) ? 1 : 0,
|
||||
'min_price' => reset( $price_meta ),
|
||||
'max_price' => end( $price_meta ),
|
||||
'onsale' => $sale_price && $price === $sale_price ? 1 : 0,
|
||||
'stock_quantity' => $stock,
|
||||
'stock_status' => get_post_meta( $id, '_stock_status', true ),
|
||||
'rating_count' => array_sum( array_map( 'intval', (array) get_post_meta( $id, '_wc_rating_count', true ) ) ),
|
||||
'average_rating' => get_post_meta( $id, '_wc_average_rating', true ),
|
||||
'total_sales' => get_post_meta( $id, 'total_sales', true ),
|
||||
'tax_status' => get_post_meta( $id, '_tax_status', true ),
|
||||
'tax_class' => get_post_meta( $id, '_tax_class', true ),
|
||||
);
|
||||
}
|
||||
return array();
|
||||
|
|
|
@ -367,6 +367,7 @@ class WC_Product_Variation_Data_Store_CPT extends WC_Product_Data_Store_CPT impl
|
|||
'image_id' => get_post_thumbnail_id( $id ),
|
||||
'backorders' => get_post_meta( $id, '_backorders', true ),
|
||||
'sku' => get_post_meta( $id, '_sku', true ),
|
||||
'global_unique_id' => get_post_meta( $id, '_global_unique_id', true ),
|
||||
'stock_quantity' => get_post_meta( $id, '_stock', true ),
|
||||
'weight' => get_post_meta( $id, '_weight', true ),
|
||||
'length' => get_post_meta( $id, '_length', true ),
|
||||
|
@ -403,6 +404,7 @@ class WC_Product_Variation_Data_Store_CPT extends WC_Product_Data_Store_CPT impl
|
|||
'title' => $parent_object ? $parent_object->post_title : '',
|
||||
'status' => $parent_object ? $parent_object->post_status : '',
|
||||
'sku' => get_post_meta( $product->get_parent_id(), '_sku', true ),
|
||||
'global_unique_id' => get_post_meta( $product->get_parent_id(), '_global_unique_id', true ),
|
||||
'manage_stock' => get_post_meta( $product->get_parent_id(), '_manage_stock', true ),
|
||||
'backorders' => get_post_meta( $product->get_parent_id(), '_backorders', true ),
|
||||
'stock_quantity' => wc_stock_amount( get_post_meta( $product->get_parent_id(), '_stock', true ) ),
|
||||
|
|
|
@ -41,6 +41,15 @@ interface WC_Product_Data_Store_Interface {
|
|||
*/
|
||||
public function is_existing_sku( $product_id, $sku );
|
||||
|
||||
/**
|
||||
* Check if product unique ID is found for any other product IDs.
|
||||
*
|
||||
* @param int $product_id Product ID.
|
||||
* @param string $global_unique_id Unique ID.
|
||||
* @return bool
|
||||
*/
|
||||
public function is_existing_global_unique_id( $product_id, $global_unique_id );
|
||||
|
||||
/**
|
||||
* Return product ID based on SKU.
|
||||
*
|
||||
|
@ -49,6 +58,14 @@ interface WC_Product_Data_Store_Interface {
|
|||
*/
|
||||
public function get_product_id_by_sku( $sku );
|
||||
|
||||
/**
|
||||
* Return product ID based on Unique ID.
|
||||
*
|
||||
* @param string $global_unique_id Unique ID.
|
||||
* @return int
|
||||
*/
|
||||
public function get_product_id_by_global_unique_id( $global_unique_id );
|
||||
|
||||
/**
|
||||
* Returns an array of IDs of products that have sales starting soon.
|
||||
*
|
||||
|
|
|
@ -108,6 +108,7 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V
|
|||
'description' => wc_format_content( $object->get_description() ),
|
||||
'permalink' => $object->get_permalink(),
|
||||
'sku' => $object->get_sku(),
|
||||
'global_unique_id' => $object->get_global_unique_id(),
|
||||
'price' => $object->get_price(),
|
||||
'regular_price' => $object->get_regular_price(),
|
||||
'sale_price' => $object->get_sale_price(),
|
||||
|
@ -193,6 +194,11 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V
|
|||
$variation->set_sku( wc_clean( $request['sku'] ) );
|
||||
}
|
||||
|
||||
// Unique ID.
|
||||
if ( isset( $request['global_unique_id'] ) ) {
|
||||
$variation->set_global_unique_id( wc_clean( $request['global_unique_id'] ) );
|
||||
}
|
||||
|
||||
// Thumbnail.
|
||||
if ( isset( $request['image'] ) ) {
|
||||
if ( is_array( $request['image'] ) ) {
|
||||
|
@ -535,7 +541,12 @@ class WC_REST_Product_Variations_Controller extends WC_REST_Product_Variations_V
|
|||
'readonly' => true,
|
||||
),
|
||||
'sku' => array(
|
||||
'description' => __( 'Unique identifier.', 'woocommerce' ),
|
||||
'description' => __( 'Stock Keeping Unit.', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'global_unique_id' => array(
|
||||
'description' => __( 'GTIN, UPC, EAN or ISBN.', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
|
|
|
@ -561,6 +561,11 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller {
|
|||
$product->set_sku( wc_clean( $request['sku'] ) );
|
||||
}
|
||||
|
||||
// Unique ID.
|
||||
if ( isset( $request['global_unique_id'] ) ) {
|
||||
$product->set_global_unique_id( wc_clean( $request['global_unique_id'] ) );
|
||||
}
|
||||
|
||||
// Attributes.
|
||||
if ( isset( $request['attributes'] ) ) {
|
||||
$attributes = array();
|
||||
|
@ -987,7 +992,12 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller {
|
|||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'sku' => array(
|
||||
'description' => __( 'Unique identifier.', 'woocommerce' ),
|
||||
'description' => __( 'Stock Keeping Unit.', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
'global_unique_id' => array(
|
||||
'description' => __( 'GTIN, UPC, EAN or ISBN.', 'woocommerce' ),
|
||||
'type' => 'string',
|
||||
'context' => array( 'view', 'edit' ),
|
||||
),
|
||||
|
@ -1662,6 +1672,10 @@ class WC_REST_Products_Controller extends WC_REST_Products_V2_Controller {
|
|||
$data['post_password'] = $product->get_post_password( $context );
|
||||
}
|
||||
|
||||
if ( in_array( 'global_unique_id', $fields, true ) ) {
|
||||
$data['global_unique_id'] = $product->get_global_unique_id( $context );
|
||||
}
|
||||
|
||||
$post_type_obj = get_post_type_object( $this->post_type );
|
||||
if ( is_post_type_viewable( $post_type_obj ) && $post_type_obj->public ) {
|
||||
$permalink_template_requested = in_array( 'permalink_template', $fields, true );
|
||||
|
|
|
@ -344,6 +344,7 @@ class WC_Products_Tracking {
|
|||
'tags' => count( $product->get_tag_ids() ),
|
||||
'upsells' => ! empty( $product->get_upsell_ids() ) ? 'yes' : 'no',
|
||||
'weight' => $product->get_weight() ? 'yes' : 'no',
|
||||
'global_unique_id' => $product->get_global_unique_id() ? 'yes' : 'no',
|
||||
);
|
||||
|
||||
WC_Tracks::record_event( 'product_add_publish', $properties );
|
||||
|
|
|
@ -639,6 +639,47 @@ function wc_product_has_unique_sku( $product_id, $sku ) {
|
|||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Check if product unique ID is unique.
|
||||
*
|
||||
* @since 9.1.0
|
||||
* @param int $product_id Product ID.
|
||||
* @param string $global_unique_id Product Unique ID.
|
||||
* @return bool
|
||||
*/
|
||||
function wc_product_has_global_unique_id( $product_id, $global_unique_id ) {
|
||||
/**
|
||||
* Gives plugins an opportunity to verify Unique ID uniqueness themselves.
|
||||
*
|
||||
* @since 9.1.0
|
||||
*
|
||||
* @param bool|null $has_global_unique_id Set to a boolean value to short-circuit the default Unique ID check.
|
||||
* @param int $product_id The ID of the current product.
|
||||
* @param string $sku The Unique ID to check for uniqueness.
|
||||
*/
|
||||
$has_global_unique_id = apply_filters( 'wc_product_pre_has_global_unique_id', null, $product_id, $global_unique_id );
|
||||
if ( ! is_null( $has_global_unique_id ) ) {
|
||||
return boolval( $has_global_unique_id );
|
||||
}
|
||||
|
||||
$data_store = WC_Data_Store::load( 'product' );
|
||||
$global_unique_id_found = $data_store->is_existing_global_unique_id( $product_id, $global_unique_id );
|
||||
/**
|
||||
* Gives plugins an opportunity to verify Unique ID uniqueness themselves.
|
||||
*
|
||||
* @since 9.1.0
|
||||
*
|
||||
* @param boolean $global_unique_id_found Whether the Unique ID is found.
|
||||
* @param int $product_id The ID of the current product.
|
||||
* @param string $sku The Unique ID to check for uniqueness.
|
||||
*/
|
||||
if ( apply_filters( 'wc_product_has_global_unique_id', $global_unique_id_found, $product_id, $global_unique_id ) ) {
|
||||
return false;
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
/**
|
||||
* Force a unique SKU.
|
||||
*
|
||||
|
@ -692,6 +733,18 @@ function wc_get_product_id_by_sku( $sku ) {
|
|||
return $data_store->get_product_id_by_sku( $sku );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get product ID by Unique ID.
|
||||
*
|
||||
* @since 9.1.0
|
||||
* @param string $global_unique_id Product Unique ID.
|
||||
* @return int
|
||||
*/
|
||||
function wc_get_product_id_by_global_unique_id( $global_unique_id ) {
|
||||
$data_store = WC_Data_Store::load( 'product' );
|
||||
return $data_store->get_product_id_by_global_unique_id( $global_unique_id );
|
||||
}
|
||||
|
||||
/**
|
||||
* Get attributes/data for an individual variation from the database and maintain it's integrity.
|
||||
*
|
||||
|
@ -1421,6 +1474,7 @@ function wc_update_product_lookup_tables() {
|
|||
'min_max_price',
|
||||
'stock_quantity',
|
||||
'sku',
|
||||
'global_unique_id',
|
||||
'stock_status',
|
||||
'average_rating',
|
||||
'total_sales',
|
||||
|
|
|
@ -309,13 +309,41 @@ class ProductVariationTemplate extends AbstractProductFormTemplate implements Pr
|
|||
'order' => 10,
|
||||
)
|
||||
);
|
||||
$product_inventory_inner_section->add_block(
|
||||
$inventory_columns = $product_inventory_inner_section->add_block(
|
||||
array(
|
||||
'id' => 'product-inventory-inner-columns',
|
||||
'blockName' => 'core/columns',
|
||||
)
|
||||
);
|
||||
$inventory_columns->add_block(
|
||||
array(
|
||||
'id' => 'product-inventory-inner-column1',
|
||||
'blockName' => 'core/column',
|
||||
)
|
||||
)->add_block(
|
||||
array(
|
||||
'id' => 'product-variation-sku-field',
|
||||
'blockName' => 'woocommerce/product-sku-field',
|
||||
'order' => 10,
|
||||
)
|
||||
);
|
||||
$inventory_columns->add_block(
|
||||
array(
|
||||
'id' => 'product-inventory-inner-column2',
|
||||
'blockName' => 'core/column',
|
||||
)
|
||||
)->add_block(
|
||||
array(
|
||||
'id' => 'product-unique-id-field',
|
||||
'blockName' => 'woocommerce/product-text-field',
|
||||
'order' => 20,
|
||||
'attributes' => array(
|
||||
'property' => 'global_unique_id',
|
||||
'label' => __( 'GTIN, UPC, EAN or ISBN', 'woocommerce' ),
|
||||
'tooltip' => __( 'Enter a barcode or any other identifier unique to this product. It can help you list this product on other channels or marketplaces.', 'woocommerce' ),
|
||||
),
|
||||
)
|
||||
);
|
||||
$product_inventory_inner_section->add_block(
|
||||
array(
|
||||
'id' => 'product-variation-track-stock',
|
||||
|
|
|
@ -730,7 +730,18 @@ class SimpleProductTemplate extends AbstractProductFormTemplate implements Produ
|
|||
'order' => 10,
|
||||
)
|
||||
);
|
||||
$product_inventory_inner_section->add_block(
|
||||
$inventory_columns = $product_inventory_inner_section->add_block(
|
||||
array(
|
||||
'id' => 'product-inventory-inner-columns',
|
||||
'blockName' => 'core/columns',
|
||||
)
|
||||
);
|
||||
$inventory_columns->add_block(
|
||||
array(
|
||||
'id' => 'product-inventory-inner-column1',
|
||||
'blockName' => 'core/column',
|
||||
)
|
||||
)->add_block(
|
||||
array(
|
||||
'id' => 'product-sku-field',
|
||||
'blockName' => 'woocommerce/product-sku-field',
|
||||
|
@ -742,6 +753,28 @@ class SimpleProductTemplate extends AbstractProductFormTemplate implements Produ
|
|||
),
|
||||
)
|
||||
);
|
||||
$inventory_columns->add_block(
|
||||
array(
|
||||
'id' => 'product-inventory-inner-column2',
|
||||
'blockName' => 'core/column',
|
||||
)
|
||||
)->add_block(
|
||||
array(
|
||||
'id' => 'product-unique-id-field',
|
||||
'blockName' => 'woocommerce/product-text-field',
|
||||
'order' => 20,
|
||||
'attributes' => array(
|
||||
'property' => 'global_unique_id',
|
||||
'label' => __( 'GTIN, UPC, EAN or ISBN', 'woocommerce' ),
|
||||
'tooltip' => __( 'Enter a barcode or any other identifier unique to this product. It can help you list this product on other channels or marketplaces.', 'woocommerce' ),
|
||||
),
|
||||
'disableConditions' => array(
|
||||
array(
|
||||
'expression' => 'editedProduct.type === "variable"',
|
||||
),
|
||||
),
|
||||
)
|
||||
);
|
||||
|
||||
$manage_stock = 'yes' === get_option( 'woocommerce_manage_stock' );
|
||||
$product_inventory_inner_section->add_block(
|
||||
|
|
|
@ -400,13 +400,14 @@ class Product_Variations_API extends WC_REST_Unit_Test_Case {
|
|||
$data = $response->get_data();
|
||||
$properties = $data['schema']['properties'];
|
||||
|
||||
$this->assertEquals( 39, count( $properties ) );
|
||||
$this->assertEquals( 40, count( $properties ) );
|
||||
$this->assertArrayHasKey( 'id', $properties );
|
||||
$this->assertArrayHasKey( 'date_created', $properties );
|
||||
$this->assertArrayHasKey( 'date_modified', $properties );
|
||||
$this->assertArrayHasKey( 'description', $properties );
|
||||
$this->assertArrayHasKey( 'permalink', $properties );
|
||||
$this->assertArrayHasKey( 'sku', $properties );
|
||||
$this->assertArrayHasKey( 'global_unique_id', $properties );
|
||||
$this->assertArrayHasKey( 'price', $properties );
|
||||
$this->assertArrayHasKey( 'regular_price', $properties );
|
||||
$this->assertArrayHasKey( 'sale_price', $properties );
|
||||
|
|
|
@ -649,7 +649,7 @@ class WC_Tests_API_Product extends WC_REST_Unit_Test_Case {
|
|||
$response = $this->server->dispatch( $request );
|
||||
$data = $response->get_data();
|
||||
$properties = $data['schema']['properties'];
|
||||
$this->assertEquals( 70, count( $properties ) );
|
||||
$this->assertEquals( 71, count( $properties ) );
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
|
@ -97,6 +97,7 @@ class WC_REST_Products_Controller_Tests extends WC_REST_Unit_Test_Case {
|
|||
'description',
|
||||
'short_description',
|
||||
'sku',
|
||||
'global_unique_id',
|
||||
'price',
|
||||
'regular_price',
|
||||
'sale_price',
|
||||
|
|
Loading…
Reference in New Issue