WC_REST_Products_Controller::prepare_object_for_database()protectedWC 1.0

Prepare a single product for create or update.

Method of the class: WC_REST_Products_Controller{}

Return

WP_Error|WC_Data.

Usage

// protected - for code of main (parent) or child class
$result = $this->prepare_object_for_database( $request, $creating );
$request(WP_REST_Request) (required)
Request object.
$creating(true|false)
If is creating a new object.
Default: false

WC_REST_Products_Controller::prepare_object_for_database() code WC 9.4.2

protected function prepare_object_for_database( $request, $creating = false ) {
	$id = isset( $request['id'] ) ? absint( $request['id'] ) : 0;

	// Type is the most important part here because we need to be using the correct class and methods.
	if ( isset( $request['type'] ) ) {
		$classname = WC_Product_Factory::get_classname_from_product_type( $request['type'] );

		if ( ! class_exists( $classname ) ) {
			$classname = 'WC_Product_Simple';
		}

		$product = new $classname( $id );
	} elseif ( isset( $request['id'] ) ) {
		$product = wc_get_product( $id );
	} else {
		$product = new WC_Product_Simple();
	}

	if ( 'variation' === $product->get_type() ) {
		return new WP_Error(
			"woocommerce_rest_invalid_{$this->post_type}_id",
			__( 'To manipulate product variations you should use the /products/<product_id>/variations/<id> endpoint.', 'woocommerce' ),
			array(
				'status' => 404,
			)
		);
	}

	// Post title.
	if ( isset( $request['name'] ) ) {
		$product->set_name( wp_filter_post_kses( $request['name'] ) );
	}

	// Post content.
	if ( isset( $request['description'] ) ) {
		$product->set_description( wp_filter_post_kses( $request['description'] ) );
	}

	// Post excerpt.
	if ( isset( $request['short_description'] ) ) {
		$product->set_short_description( wp_filter_post_kses( $request['short_description'] ) );
	}

	// Post status.
	if ( isset( $request['status'] ) ) {
		$product->set_status( get_post_status_object( $request['status'] ) ? $request['status'] : 'draft' );
	}

	// Post slug.
	if ( isset( $request['slug'] ) ) {
		$product->set_slug( $request['slug'] );
	}

	// Menu order.
	if ( isset( $request['menu_order'] ) ) {
		$product->set_menu_order( $request['menu_order'] );
	}

	// Comment status.
	if ( isset( $request['reviews_allowed'] ) ) {
		$product->set_reviews_allowed( $request['reviews_allowed'] );
	}

	// Post password.
	if ( isset( $request['post_password'] ) ) {
		$product->set_post_password( $request['post_password'] );
	}

	// 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( wp_kses_post( wp_unslash( $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'] ) );
	}

	// 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();

		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_from_gmt'] ) ) {
			$product->set_date_on_sale_from( $request['date_on_sale_from_gmt'] ? strtotime( $request['date_on_sale_from_gmt'] ) : null );
		}

		if ( isset( $request['date_on_sale_to'] ) ) {
			$product->set_date_on_sale_to( $request['date_on_sale_to'] );
		}

		if ( isset( $request['date_on_sale_to_gmt'] ) ) {
			$product->set_date_on_sale_to( $request['date_on_sale_to_gmt'] ? strtotime( $request['date_on_sale_to_gmt'] ) : null );
		}
	}

	// Product parent ID.
	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; stock_status has priority over in_stock.
	if ( isset( $request['stock_status'] ) ) {
		$stock_status = $request['stock_status'];
	} 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( $stock_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_quantity() );
				$stock_quantity += wc_stock_amount( $request['inventory_delta'] );
				$product->set_stock_quantity( wc_stock_amount( $stock_quantity ) );
			}

			// Low stock amount.
			// isset() returns false for value null, thus we need to check whether the value has been sent by the request.
			if ( array_key_exists( 'low_stock_amount', $request->get_params() ) ) {
				if ( null === $request['low_stock_amount'] ) {
					$product->set_low_stock_amount( '' );
				} else {
					$product->set_low_stock_amount( wc_stock_amount( $request['low_stock_amount'] ) );
				}
			}
		} else {
			// Don't manage stock.
			$product->set_manage_stock( 'no' );
			$product->set_stock_quantity( '' );
			$product->set_stock_status( $stock_status );
			$product->set_low_stock_amount( '' );
		}
	} 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'] ) ) {
		$new_tags = array();

		foreach ( $request['tags'] as $tag ) {
			if ( ! isset( $tag['name'] ) ) {
				$new_tags[] = $tag;
				continue;
			}

			if ( ! term_exists( $tag['name'], 'product_tag' ) ) {
				// Create the tag if it doesn't exist.
				$term = wp_insert_term( $tag['name'], 'product_tag' );

				if ( ! is_wp_error( $term ) ) {
					$new_tags[] = array(
						'id' => $term['term_id'],
					);

					continue;
				}
			} else {
				// Tag exists, assume user wants to set the product with this tag.
				$new_tags[] = array(
					'id' => get_term_by( 'name', $tag['name'], 'product_tag' )->term_id,
				);
			}
		}

		$product = $this->save_taxonomy_terms( $product, $new_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 );
	}

	// Set children for a grouped product.
	if ( $product->is_type( 'grouped' ) && isset( $request['grouped_products'] ) ) {
		$product->set_children( $request['grouped_products'] );
	}

	// Check for featured/gallery images, upload it and set it.
	if ( isset( $request['images'] ) ) {
		$product = $this->set_product_images( $product, $request['images'] );
	}

	// Allow set meta_data.
	if ( is_array( $request['meta_data'] ) ) {
		foreach ( $request['meta_data'] as $meta ) {
			$product->update_meta_data( $meta['key'], $meta['value'], isset( $meta['id'] ) ? $meta['id'] : '' );
		}
	}

	if ( ! empty( $request['date_created'] ) ) {
		$date = rest_parse_date( $request['date_created'] );

		if ( $date ) {
			$product->set_date_created( $date );
		}
	}

	if ( ! empty( $request['date_created_gmt'] ) ) {
		$date = rest_parse_date( $request['date_created_gmt'], true );

		if ( $date ) {
			$product->set_date_created( $date );
		}
	}

	/**
	 * Filters an object before it is inserted via the REST API.
	 *
	 * The dynamic portion of the hook name, `$this->post_type`,
	 * refers to the object type slug.
	 *
	 * @param WC_Data         $product  Object object.
	 * @param WP_REST_Request $request  Request object.
	 * @param bool            $creating If is creating a new object.
	 */
	return apply_filters( "woocommerce_rest_pre_insert_{$this->post_type}_object", $product, $request, $creating );
}