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',
'_sale_price_dates_to' => 'date_on_sale_to',
'total_sales' => 'total_sales',
'_tax_status' => 'tax_status',
'_tax_class' => 'tax_class',
'_manage_stock' => 'manage_stock',
'_backorders' => 'backorders',
'_low_stock_amount' => 'low_stock_amount',
'_sold_individually' => 'sold_individually',
'_weight' => 'weight',
'_length' => 'length',
'_width' => 'width',
'_height' => 'height',
'_upsell_ids' => 'upsell_ids',
'_crosssell_ids' => 'cross_sell_ids',
'_purchase_note' => 'purchase_note',
'_default_attributes' => 'default_attributes',
'_virtual' => 'virtual',
'_downloadable' => 'downloadable',
'_product_image_gallery' => 'gallery_image_ids',
'_download_limit' => 'download_limit',
'_download_expiry' => 'download_expiry',
'_thumbnail_id' => 'image_id',
'_stock' => 'stock_quantity',
'_stock_status' => 'stock_status',
'_wc_average_rating' => 'average_rating',
'_wc_rating_count' => 'rating_counts',
'_wc_review_count' => 'review_count',
);
// Make sure to take extra data (like product url or text for external products) into account.
$extra_data_keys = $product->get_extra_data_keys();
foreach ( $extra_data_keys as $key ) {
$meta_key_to_props[ '_' . $key ] = $key;
}
$props_to_update = $force ? $meta_key_to_props : $this->get_props_to_update( $product, $meta_key_to_props );
foreach ( $props_to_update as $meta_key => $prop ) {
$value = $product->{"get_$prop"}( 'edit' );
$value = is_string( $value ) ? wp_slash( $value ) : $value;
switch ( $prop ) {
case 'virtual':
case 'downloadable':
case 'manage_stock':
case 'sold_individually':
$value = wc_bool_to_string( $value );
break;
case 'gallery_image_ids':
$value = implode( ',', $value );
break;
case 'date_on_sale_from':
case 'date_on_sale_to':
$value = $value ? $value->getTimestamp() : '';
break;
case 'stock_quantity':
// Fire actions to let 3rd parties know the stock is about to be changed.
if ( $product->is_type( ProductType::VARIATION ) ) {
/**
* Action to signal that the value of 'stock_quantity' for a variation is about to change.
*
* @since 4.9
*
* @param int $product The variation whose stock is about to change.
*/
do_action( 'woocommerce_variation_before_set_stock', $product );
} else {
/**
* Action to signal that the value of 'stock_quantity' for a product is about to change.
*
* @since 4.9
*
* @param int $product The product whose stock is about to change.
*/
do_action( 'woocommerce_product_before_set_stock', $product );
}
break;
}
$updated = $this->update_or_delete_post_meta( $product, $meta_key, $value );
if ( $updated ) {
$this->updated_props[] = $prop;
}
}
if ( $this->cogs_feature_is_enabled() ) {
$cogs_value = $product->get_cogs_value();
/**
* Filter to customize the Cost of Goods Sold value that gets saved for a given product,
* or to suppress the saving of the value (so that custom storage can be used).
*
* @since 9.5.0
*
* @param float|null|false $cogs_value The value to be written to the database. If returned as false, nothing will be written.
* @param WC_Product $product The product for which the value is being saved.
*/
$cogs_value = apply_filters( 'woocommerce_save_product_cogs_value', $cogs_value, $product );
if ( false !== $cogs_value ) {
$updated = $this->update_or_delete_post_meta( $product, '_cogs_total_value', is_null( $cogs_value ) ? '' : $cogs_value );
if ( $updated ) {
$this->updated_props[] = 'cogs_value';
}
}
}
// Update extra data associated with the product like button text or product URL for external products.
if ( ! $this->extra_data_saved ) {
foreach ( $extra_data_keys as $key ) {
$meta_key = '_' . $key;
$function = 'get_' . $key;
if ( ! array_key_exists( $meta_key, $props_to_update ) ) {
continue;
}
if ( is_callable( array( $product, $function ) ) ) {
$value = $product->{$function}( 'edit' );
$value = is_string( $value ) ? wp_slash( $value ) : $value;
$updated = $this->update_or_delete_post_meta( $product, $meta_key, $value );
if ( $updated ) {
$this->updated_props[] = $key;
}
}
}
}
if ( $this->update_downloads( $product, $force ) ) {
$this->updated_props[] = 'downloads';
}
}