/**
  * Save product images.
  *
  * @throws WC_REST_Exception REST API exceptions.
  * @param WC_Product $product Product instance.
  * @param array      $images  Images data.
  * @return WC_Product
  */
 protected function save_product_images($product, $images)
 {
     if (is_array($images)) {
         $gallery = array();
         foreach ($images as $image) {
             $attachment_id = isset($image['id']) ? absint($image['id']) : 0;
             if (0 === $attachment_id && isset($image['src'])) {
                 $upload = wc_rest_upload_image_from_url(esc_url_raw($image['src']));
                 if (is_wp_error($upload)) {
                     if (!apply_filters('woocommerce_rest_suppress_image_upload_error', false, $upload, $product->get_id(), $images)) {
                         throw new WC_REST_Exception('woocommerce_product_image_upload_error', $upload->get_error_message(), 400);
                     } else {
                         continue;
                     }
                 }
                 $attachment_id = wc_rest_set_uploaded_image_as_attachment($upload, $product->get_id());
             }
             if (isset($image['position']) && 0 === $image['position']) {
                 $product->set_image_id($attachment_id);
             } else {
                 $gallery[] = $attachment_id;
             }
             // Set the image alt if present.
             if (!empty($image['alt'])) {
                 update_post_meta($attachment_id, '_wp_attachment_image_alt', wc_clean($image['alt']));
             }
             // Set the image name if present.
             if (!empty($image['name'])) {
                 wp_update_post(array('ID' => $attachment_id, 'post_title' => $image['name']));
             }
         }
         if (!empty($gallery)) {
             $product->set_gallery_image_ids($gallery);
         }
     } else {
         $product->set_image_id('');
         $product->set_gallery_image_ids(array());
     }
     return $product;
 }
 /**
  * Save variations.
  *
  * @param WC_Product $product
  * @param WP_REST_Request $request
  * @return bool
  * @throws WC_REST_Exception
  */
 protected function save_variations_data($product, $request)
 {
     global $wpdb;
     $variations = $request['variations'];
     $attributes = $product->get_attributes();
     foreach ($variations as $menu_order => $variation) {
         $variation_id = isset($variation['id']) ? absint($variation['id']) : 0;
         // Generate a useful post title.
         $variation_post_title = sprintf(__('Variation #%s of %s', 'woocommerce'), $variation_id, esc_html(get_the_title($product->id)));
         // Update or Add post.
         if (!$variation_id) {
             $post_status = isset($variation['visible']) && false === $variation['visible'] ? 'private' : 'publish';
             $new_variation = array('post_title' => $variation_post_title, 'post_content' => '', 'post_status' => $post_status, 'post_author' => get_current_user_id(), 'post_parent' => $product->id, 'post_type' => 'product_variation', 'menu_order' => $menu_order);
             $variation_id = wp_insert_post($new_variation);
             do_action('woocommerce_create_product_variation', $variation_id);
         } else {
             $update_variation = array('post_title' => $variation_post_title, 'menu_order' => $menu_order);
             if (isset($variation['visible'])) {
                 $post_status = false === $variation['visible'] ? 'private' : 'publish';
                 $update_variation['post_status'] = $post_status;
             }
             $wpdb->update($wpdb->posts, $update_variation, array('ID' => $variation_id));
             do_action('woocommerce_update_product_variation', $variation_id);
         }
         // Stop with we don't have a variation ID.
         if (is_wp_error($variation_id)) {
             throw new WC_REST_Exception('woocommerce_rest_cannot_save_product_variation', $variation_id->get_error_message(), 400);
         }
         // SKU.
         if (isset($variation['sku'])) {
             $sku = get_post_meta($variation_id, '_sku', true);
             $new_sku = wc_clean($variation['sku']);
             if ('' === $new_sku) {
                 update_post_meta($variation_id, '_sku', '');
             } elseif ($new_sku !== $sku) {
                 if (!empty($new_sku)) {
                     $unique_sku = wc_product_has_unique_sku($variation_id, $new_sku);
                     if (!$unique_sku) {
                         throw new WC_REST_Exception('woocommerce_rest_product_sku_already_exists', __('The SKU already exists on another product.', 'woocommerce'), 400);
                     } else {
                         update_post_meta($variation_id, '_sku', $new_sku);
                     }
                 } else {
                     update_post_meta($variation_id, '_sku', '');
                 }
             }
         }
         // Thumbnail.
         if (isset($variation['image']) && is_array($variation['image'])) {
             $image = current($variation['image']);
             if ($image && is_array($image)) {
                 if (isset($image['position']) && 0 === $image['position']) {
                     $attachment_id = isset($image['id']) ? absint($image['id']) : 0;
                     if (0 === $attachment_id && isset($image['src'])) {
                         $upload = wc_rest_upload_image_from_url(wc_clean($image['src']));
                         if (is_wp_error($upload)) {
                             throw new WC_REST_Exception('woocommerce_product_image_upload_error', $upload->get_error_message(), 400);
                         }
                         $attachment_id = wc_rest_set_uploaded_image_as_attachment($upload, $product->id);
                     }
                     // Set the image alt if present.
                     if (!empty($image['alt'])) {
                         update_post_meta($attachment_id, '_wp_attachment_image_alt', wc_clean($image['alt']));
                     }
                     // Set the image name if present.
                     if (!empty($image['name'])) {
                         wp_update_post(array('ID' => $attachment_id, 'post_title' => $image['name']));
                     }
                     update_post_meta($variation_id, '_thumbnail_id', $attachment_id);
                 }
             } else {
                 delete_post_meta($variation_id, '_thumbnail_id');
             }
         }
         // Virtual variation.
         if (isset($variation['virtual'])) {
             $is_virtual = true === $variation['virtual'] ? 'yes' : 'no';
             update_post_meta($variation_id, '_virtual', $is_virtual);
         }
         // Downloadable variation.
         if (isset($variation['downloadable'])) {
             $is_downloadable = true === $variation['downloadable'] ? 'yes' : 'no';
             update_post_meta($variation_id, '_downloadable', $is_downloadable);
         } else {
             $is_downloadable = get_post_meta($variation_id, '_downloadable', true);
         }
         // Shipping data.
         $this->save_product_shipping_data($variation_id, $variation);
         // Stock handling.
         if (isset($variation['manage_stock'])) {
             $manage_stock = true === $variation['manage_stock'] ? 'yes' : 'no';
         } else {
             $manage_stock = get_post_meta($variation_id, '_manage_stock', true);
         }
         update_post_meta($variation_id, '_manage_stock', '' === $manage_stock ? 'no' : $manage_stock);
         if (isset($variation['in_stock'])) {
             $stock_status = true === $variation['in_stock'] ? 'instock' : 'outofstock';
         } else {
             $stock_status = get_post_meta($variation_id, '_stock_status', true);
         }
         wc_update_product_stock_status($variation_id, '' === $stock_status ? 'instock' : $stock_status);
         if ('yes' === $manage_stock) {
             $backorders = get_post_meta($variation_id, '_backorders', true);
             if (isset($variation['backorders'])) {
                 $backorders = $variation['backorders'];
             }
             update_post_meta($variation_id, '_backorders', '' === $backorders ? 'no' : $backorders);
             if (isset($variation['stock_quantity'])) {
                 wc_update_product_stock($variation_id, wc_stock_amount($variation['stock_quantity']));
             } elseif (isset($request['inventory_delta'])) {
                 $stock_quantity = wc_stock_amount(get_post_meta($variation_id, '_stock', true));
                 $stock_quantity += wc_stock_amount($request['inventory_delta']);
                 wc_update_product_stock($variation_id, wc_stock_amount($stock_quantity));
             }
         } else {
             delete_post_meta($variation_id, '_backorders');
             delete_post_meta($variation_id, '_stock');
         }
         // Regular Price.
         if (isset($variation['regular_price'])) {
             $regular_price = '' === $variation['regular_price'] ? '' : $variation['regular_price'];
         } else {
             $regular_price = get_post_meta($variation_id, '_regular_price', true);
         }
         // Sale Price.
         if (isset($variation['sale_price'])) {
             $sale_price = '' === $variation['sale_price'] ? '' : $variation['sale_price'];
         } else {
             $sale_price = get_post_meta($variation_id, '_sale_price', true);
         }
         if (isset($variation['date_on_sale_from'])) {
             $date_from = $variation['date_on_sale_from'];
         } else {
             $date_from = get_post_meta($variation_id, '_sale_price_dates_from', true);
             $date_from = '' === $date_from ? '' : date('Y-m-d', $date_from);
         }
         if (isset($variation['date_on_sale_to'])) {
             $date_to = $variation['date_on_sale_to'];
         } else {
             $date_to = get_post_meta($variation_id, '_sale_price_dates_to', true);
             $date_to = '' === $date_to ? '' : date('Y-m-d', $date_to);
         }
         _wc_save_product_price($variation_id, $regular_price, $sale_price, $date_from, $date_to);
         // Tax class.
         if (isset($variation['tax_class'])) {
             if ($variation['tax_class'] !== 'parent') {
                 update_post_meta($variation_id, '_tax_class', wc_clean($variation['tax_class']));
             } else {
                 delete_post_meta($variation_id, '_tax_class');
             }
         }
         // Downloads.
         if ('yes' === $is_downloadable) {
             // Downloadable files.
             if (isset($variation['downloads']) && is_array($variation['downloads'])) {
                 $this->save_downloadable_files($product->id, $variation['downloads'], $variation_id);
             }
             // Download limit.
             if (isset($variation['download_limit'])) {
                 update_post_meta($variation_id, '_download_limit', -1 === $variation['download_limit'] ? '' : absint($variation['download_limit']));
             }
             // Download expiry.
             if (isset($variation['download_expiry'])) {
                 update_post_meta($variation_id, '_download_expiry', -1 === $variation['download_expiry'] ? '' : absint($variation['download_expiry']));
             }
         } else {
             update_post_meta($variation_id, '_download_limit', '');
             update_post_meta($variation_id, '_download_expiry', '');
             update_post_meta($variation_id, '_downloadable_files', '');
         }
         // Description.
         if (isset($variation['description'])) {
             update_post_meta($variation_id, '_variation_description', wp_kses_post($variation['description']));
         }
         // Update taxonomies.
         if (isset($variation['attributes'])) {
             $updated_attribute_keys = array();
             foreach ($variation['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 = sanitize_title($attribute['name']);
                 }
                 if (!$attribute_id && !$attribute_name) {
                     continue;
                 }
                 if (isset($attributes[$attribute_name])) {
                     $_attribute = $attributes[$attribute_name];
                 }
                 if (isset($_attribute['is_variation']) && $_attribute['is_variation']) {
                     $_attribute_key = 'attribute_' . sanitize_title($_attribute['name']);
                     $updated_attribute_keys[] = $_attribute_key;
                     if (isset($_attribute['is_taxonomy']) && $_attribute['is_taxonomy']) {
                         // Don't use wc_clean as it destroys sanitized characters
                         $_attribute_value = isset($attribute['option']) ? sanitize_title(stripslashes($attribute['option'])) : '';
                     } else {
                         $_attribute_value = isset($attribute['option']) ? wc_clean(stripslashes($attribute['option'])) : '';
                     }
                     update_post_meta($variation_id, $_attribute_key, $_attribute_value);
                 }
             }
             // Remove old taxonomies attributes so data is kept up to date - first get attribute key names.
             $delete_attribute_keys = $wpdb->get_col($wpdb->prepare("SELECT meta_key FROM {$wpdb->postmeta} WHERE meta_key LIKE 'attribute_%%' AND meta_key NOT IN ( '" . implode("','", $updated_attribute_keys) . "' ) AND post_id = %d;", $variation_id));
             foreach ($delete_attribute_keys as $key) {
                 delete_post_meta($variation_id, $key);
             }
         }
         do_action('woocommerce_rest_save_product_variation', $variation_id, $menu_order, $variation);
     }
     // Update parent if variable so price sorting works and stays in sync with the cheapest child.
     WC_Product_Variable::sync($product->id);
     // Update default attributes options setting.
     if (isset($request['default_attribute'])) {
         $request['default_attributes'] = $request['default_attribute'];
     }
     if (isset($request['default_attributes']) && is_array($request['default_attributes'])) {
         $default_attributes = array();
         foreach ($request['default_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 = sanitize_title($attribute['name']);
             }
             if (!$attribute_id && !$attribute_name) {
                 continue;
             }
             if (isset($attributes[$attribute_name])) {
                 $_attribute = $attributes[$attribute_name];
                 if ($_attribute['is_variation']) {
                     $value = '';
                     if (isset($attribute['option'])) {
                         if ($_attribute['is_taxonomy']) {
                             // Don't use wc_clean as it destroys sanitized characters.
                             $value = sanitize_title(trim(stripslashes($attribute['option'])));
                         } else {
                             $value = wc_clean(trim(stripslashes($attribute['option'])));
                         }
                     }
                     if ($value) {
                         $default_attributes[$attribute_name] = $value;
                     }
                 }
             }
         }
         update_post_meta($product->id, '_default_attributes', $default_attributes);
     }
     return true;
 }
 /**
  * Update term meta fields.
  *
  * @param WP_Term $term
  * @param WP_REST_Request $request
  * @return bool|WP_Error
  */
 protected function update_term_meta_fields($term, $request)
 {
     $id = (int) $term->term_id;
     update_woocommerce_term_meta($id, 'display_type', $request['display']);
     if (!empty($request['image'])) {
         $upload = wc_rest_upload_image_from_url(esc_url_raw($request['image']));
         if (is_wp_error($upload)) {
             return $upload;
         }
         $image_id = wc_rest_set_uploaded_image_as_attachment($upload);
         // Check if image_id is a valid image attachment before updating the term meta.
         if ($image_id && wp_attachment_is_image($image_id)) {
             update_woocommerce_term_meta($id, 'thumbnail_id', $image_id);
         }
     }
     return true;
 }
 /**
  * Update term meta fields.
  *
  * @param WP_Term $term
  * @param WP_REST_Request $request
  * @return bool|WP_Error
  */
 protected function update_term_meta_fields($term, $request)
 {
     $id = (int) $term->term_id;
     update_woocommerce_term_meta($id, 'display_type', 'default' === $request['display'] ? '' : $request['display']);
     update_woocommerce_term_meta($id, 'order', $request['menu_order']);
     if (!empty($request['image'])) {
         if (empty($request['image']['id']) && !empty($request['image']['src'])) {
             $upload = wc_rest_upload_image_from_url(esc_url_raw($request['image']['src']));
             if (is_wp_error($upload)) {
                 return $upload;
             }
             $image_id = wc_rest_set_uploaded_image_as_attachment($upload);
         } else {
             $image_id = absint($request['image']['id']);
         }
         // Check if image_id is a valid image attachment before updating the term meta.
         if ($image_id && wp_attachment_is_image($image_id)) {
             update_woocommerce_term_meta($id, 'thumbnail_id', $image_id);
             // Set the image alt.
             if (!empty($request['image']['alt'])) {
                 update_post_meta($image_id, '_wp_attachment_image_alt', wc_clean($request['image']['alt']));
             }
             // Set the image title.
             if (!empty($request['image']['title'])) {
                 wp_update_post(array('ID' => $image_id, 'post_title' => wc_clean($request['image']['title'])));
             }
         }
     }
     return true;
 }
Ejemplo n.º 5
0
 /**
  * Test wc_rest_upload_image_from_url().
  *
  * @since 2.6.0
  */
 public function test_wc_rest_upload_image_from_url()
 {
     // Only test the error, no need to upload images.
     $this->assertIsWPError(wc_rest_upload_image_from_url('thing'));
 }