/**
* Save product meta.
*
* @throws WC_REST_Exception REST API exceptions.
* @param WC_Product $product Product instance.
* @param WP_REST_Request $request Request data.
* @return WC_Product
*/
protected function save_product_meta($product, $request)
{
global $wpdb;
// Virtual.
if (isset($request['virtual'])) {
$product->set_virtual($request['virtual']);
}
// Tax status.
if (isset($request['tax_status'])) {
$product->set_tax_status($request['tax_status']);
}
// Tax Class.
if (isset($request['tax_class'])) {
$product->set_tax_class($request['tax_class']);
}
// Catalog Visibility.
if (isset($request['catalog_visibility'])) {
$product->set_catalog_visibility($request['catalog_visibility']);
}
// Purchase Note.
if (isset($request['purchase_note'])) {
$product->set_purchase_note(wc_clean($request['purchase_note']));
}
// Featured Product.
if (isset($request['featured'])) {
$product->set_featured($request['featured']);
}
// Shipping data.
$product = $this->save_product_shipping_data($product, $request);
// SKU.
if (isset($request['sku'])) {
$product->set_sku(wc_clean($request['sku']));
}
// Attributes.
if (isset($request['attributes'])) {
$attributes = array();
foreach ($request['attributes'] as $attribute) {
$attribute_id = 0;
$attribute_name = '';
// Check ID for global attributes or name for product attributes.
if (!empty($attribute['id'])) {
$attribute_id = absint($attribute['id']);
$attribute_name = wc_attribute_taxonomy_name_by_id($attribute_id);
} elseif (!empty($attribute['name'])) {
$attribute_name = wc_clean($attribute['name']);
}
if (!$attribute_id && !$attribute_name) {
continue;
}
if ($attribute_id) {
if (isset($attribute['options'])) {
$options = $attribute['options'];
if (!is_array($attribute['options'])) {
// Text based attributes - Posted values are term names.
$options = explode(WC_DELIMITER, $options);
}
$values = array_map('wc_sanitize_term_text_based', $options);
$values = array_filter($values, 'strlen');
} else {
$values = array();
}
if (!empty($values)) {
// Add attribute to array, but don't set values.
$attribute_object = new WC_Product_Attribute();
$attribute_object->set_id($attribute_id);
$attribute_object->set_name($attribute_name);
$attribute_object->set_options($values);
$attribute_object->set_position(isset($attribute['position']) ? (string) absint($attribute['position']) : '0');
$attribute_object->set_visible(isset($attribute['visible']) && $attribute['visible'] ? 1 : 0);
$attribute_object->set_variation(isset($attribute['variation']) && $attribute['variation'] ? 1 : 0);
$attributes[] = $attribute_object;
}
} elseif (isset($attribute['options'])) {
// Custom attribute - Add attribute to array and set the values.
if (is_array($attribute['options'])) {
$values = $attribute['options'];
} else {
$values = explode(WC_DELIMITER, $attribute['options']);
}
$attribute_object = new WC_Product_Attribute();
$attribute_object->set_name($attribute_name);
$attribute_object->set_options($values);
$attribute_object->set_position(isset($attribute['position']) ? (string) absint($attribute['position']) : '0');
$attribute_object->set_visible(isset($attribute['visible']) && $attribute['visible'] ? 1 : 0);
$attribute_object->set_variation(isset($attribute['variation']) && $attribute['variation'] ? 1 : 0);
$attributes[] = $attribute_object;
}
}
$product->set_attributes($attributes);
}
// Sales and prices.
if (in_array($product->get_type(), array('variable', 'grouped'), true)) {
$product->set_regular_price('');
$product->set_sale_price('');
$product->set_date_on_sale_to('');
$product->set_date_on_sale_from('');
$product->set_price('');
} else {
// Regular Price.
if (isset($request['regular_price'])) {
$product->set_regular_price($request['regular_price']);
}
// Sale Price.
if (isset($request['sale_price'])) {
$product->set_sale_price($request['sale_price']);
}
if (isset($request['date_on_sale_from'])) {
$product->set_date_on_sale_from($request['date_on_sale_from']);
}
if (isset($request['date_on_sale_to'])) {
$product->set_date_on_sale_to($request['date_on_sale_to']);
}
}
// Product parent ID for groups.
if (isset($request['parent_id'])) {
$product->set_parent_id($request['parent_id']);
}
// Sold individually.
if (isset($request['sold_individually'])) {
$product->set_sold_individually($request['sold_individually']);
}
// Stock status.
if (isset($request['in_stock'])) {
$stock_status = true === $request['in_stock'] ? 'instock' : 'outofstock';
} else {
$stock_status = $product->get_stock_status();
}
// Stock data.
if ('yes' === get_option('woocommerce_manage_stock')) {
// Manage stock.
if (isset($request['manage_stock'])) {
$product->set_manage_stock($request['manage_stock']);
}
// Backorders.
if (isset($request['backorders'])) {
$product->set_backorders($request['backorders']);
}
if ($product->is_type('grouped')) {
$product->set_manage_stock('no');
$product->set_backorders('no');
$product->set_stock_quantity('');
$product->set_stock_status($status);
} elseif ($product->is_type('external')) {
$product->set_manage_stock('no');
$product->set_backorders('no');
$product->set_stock_quantity('');
$product->set_stock_status('instock');
} elseif ($product->get_manage_stock()) {
// Stock status is always determined by children so sync later.
if (!$product->is_type('variable')) {
$product->set_stock_status($stock_status);
}
// Stock quantity.
if (isset($request['stock_quantity'])) {
$product->set_stock_quantity(wc_stock_amount($request['stock_quantity']));
} elseif (isset($request['inventory_delta'])) {
$stock_quantity = wc_stock_amount($product->get_stock_amount());
$stock_quantity += wc_stock_amount($request['inventory_delta']);
$product->set_stock_quantity(wc_stock_amount($stock_quantity));
}
} else {
// Don't manage stock.
$product->set_manage_stock('no');
$product->set_stock_quantity('');
$product->set_stock_status($stock_status);
}
} elseif (!$product->is_type('variable')) {
$product->set_stock_status($stock_status);
}
// Upsells.
if (isset($request['upsell_ids'])) {
$upsells = array();
$ids = $request['upsell_ids'];
if (!empty($ids)) {
foreach ($ids as $id) {
if ($id && $id > 0) {
$upsells[] = $id;
}
}
}
$product->set_upsell_ids($upsells);
}
// Cross sells.
if (isset($request['cross_sell_ids'])) {
$crosssells = array();
$ids = $request['cross_sell_ids'];
if (!empty($ids)) {
foreach ($ids as $id) {
if ($id && $id > 0) {
$crosssells[] = $id;
}
}
}
$product->set_cross_sell_ids($crosssells);
}
// Product categories.
if (isset($request['categories']) && is_array($request['categories'])) {
$product = $this->save_taxonomy_terms($product, $request['categories']);
}
// Product tags.
if (isset($request['tags']) && is_array($request['tags'])) {
$product = $this->save_taxonomy_terms($product, $request['tags'], 'tag');
}
// Downloadable.
if (isset($request['downloadable'])) {
$product->set_downloadable($request['downloadable']);
}
// Downloadable options.
if ($product->get_downloadable()) {
// Downloadable files.
if (isset($request['downloads']) && is_array($request['downloads'])) {
$product = $this->save_downloadable_files($product, $request['downloads']);
}
// Download limit.
if (isset($request['download_limit'])) {
$product->set_download_limit($request['download_limit']);
}
// Download expiry.
if (isset($request['download_expiry'])) {
$product->set_download_expiry($request['download_expiry']);
}
}
// Product url and button text for external products.
if ($product->is_type('external')) {
if (isset($request['external_url'])) {
$product->set_product_url($request['external_url']);
}
if (isset($request['button_text'])) {
$product->set_button_text($request['button_text']);
}
}
// Save default attributes for variable products.
if ($product->is_type('variable')) {
$product = $this->save_default_attributes($product, $request);
}
return $product;
}