Automattic\WooCommerce\Internal\CLI\Migrator\Platforms\Shopify

ShopifyMapper::map_variable_product_dataprivateWC 1.0

Maps variable product data (attributes and variations) from Shopify.

Method of the class: ShopifyMapper{}

No Hooks.

Returns

Array. Variable product data mappings.

Usage

// private - for code of main (parent) class only
$result = $this->map_variable_product_data( $shopify_product, $is_variable ): array;
$shopify_product(object) (required)
The Shopify product data.
$is_variable(true|false) (required)
Whether this is a variable product.

ShopifyMapper::map_variable_product_data() code WC 10.8.1

private function map_variable_product_data( object $shopify_product, bool $is_variable ): array {
	$variable_data = array();

	// Attributes (Variable Only).
	$variable_data['attributes'] = array();
	if ( $is_variable && property_exists( $shopify_product, 'options' ) && ! empty( $shopify_product->options ) ) {
		foreach ( $shopify_product->options as $option ) {
			$variable_data['attributes'][] = array(
				'name'         => wc_clean( $option->name ),
				'options'      => array_map( 'wc_clean', $option->values ),
				'position'     => $option->position,
				'is_visible'   => true,
				'is_variation' => true,
			);
		}
	}

	// Variations (Variable Only).
	$variable_data['variations'] = array();
	if ( $is_variable && property_exists( $shopify_product, 'variants' ) && ! empty( $shopify_product->variants->edges ) ) {
		foreach ( $shopify_product->variants->edges as $variant_edge ) {
			$variant_node                  = $variant_edge->node;
			$variation_data                = array();
			$variation_data['original_id'] = ! empty( $variant_node->id ) ? basename( $variant_node->id ) : null;

			if ( $this->should_process( 'price' ) ) {
				if ( $variant_node->compareAtPrice && (float) $variant_node->compareAtPrice > (float) $variant_node->price ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase -- GraphQL uses camelCase.
					$variation_data['regular_price'] = $variant_node->compareAtPrice; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase -- GraphQL uses camelCase.
					$variation_data['sale_price']    = $variant_node->price;
				} else {
					$variation_data['regular_price'] = $variant_node->price;
					$variation_data['sale_price']    = null;
				}
			}

			if ( $this->should_process( 'sku' ) ) {
				$variation_data['sku'] = wc_clean( $variant_node->sku ?? '' );
			}

			if ( $this->should_process( 'stock' ) ) {
				$manage_stock                     = property_exists( $variant_node, 'inventoryItem' ) && $variant_node->inventoryItem->tracked; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase -- GraphQL uses camelCase.
				$variation_data['manage_stock']   = $manage_stock;
				$stock_quantity                   = $variant_node->inventoryQuantity ?? 0; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase -- GraphQL uses camelCase.
				$allow_oversell                   = $manage_stock && 'CONTINUE' === $variant_node->inventoryPolicy; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase -- GraphQL uses camelCase.
				$variation_data['stock_status']   = ( $stock_quantity > 0 || $allow_oversell ) ? 'instock' : 'outofstock';
				$variation_data['stock_quantity'] = $stock_quantity;
			}

			if ( $this->should_process( 'weight' ) ) {
				$weight_data = null;
				if ( property_exists( $variant_node, 'inventoryItem' ) && is_object( $variant_node->inventoryItem ) && // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase -- GraphQL uses camelCase.
					property_exists( $variant_node->inventoryItem, 'measurement' ) && is_object( $variant_node->inventoryItem->measurement ) && // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase -- GraphQL uses camelCase.
					property_exists( $variant_node->inventoryItem->measurement, 'weight' ) && is_object( $variant_node->inventoryItem->measurement->weight ) // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase -- GraphQL uses camelCase.
				) {
					$weight_data = $variant_node->inventoryItem->measurement->weight; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase -- GraphQL uses camelCase.
				}
				$weight                   = $weight_data ? $weight_data->value : null;
				$weight_unit              = $weight_data ? $weight_data->unit : null;
				$variation_data['weight'] = $this->get_converted_weight( $weight, $weight_unit );
			}

			if ( property_exists( $variant_node, 'inventoryItem' ) && is_object( $variant_node->inventoryItem ) && // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase -- GraphQL uses camelCase.
				property_exists( $variant_node->inventoryItem, 'unitCost' ) && is_object( $variant_node->inventoryItem->unitCost ) // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase -- GraphQL uses camelCase.
			) {
				$variation_data['cost_of_goods'] = $variant_node->inventoryItem->unitCost->amount; // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase -- GraphQL uses camelCase.
			}

			if ( property_exists( $variant_node, 'taxable' ) ) {
				$variation_data['tax_status'] = $variant_node->taxable ? 'taxable' : 'none';
			}

			if ( $this->should_process( 'attributes' ) ) {
				$variation_data['attributes'] = array();
				if ( ! empty( $variant_node->selectedOptions ) ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase -- GraphQL uses camelCase.
					foreach ( $variant_node->selectedOptions as $selectedOption ) { // phpcs:ignore WordPress.NamingConventions.ValidVariableName.UsedPropertyNotSnakeCase,WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase -- GraphQL uses camelCase.
						$variation_data['attributes'][ wc_clean( $selectedOption->name ) ] = wc_clean( $selectedOption->value ); // phpcs:ignore WordPress.NamingConventions.ValidVariableName.VariableNotSnakeCase -- GraphQL uses camelCase.
					}
				}
			}

			if ( $this->should_process( 'images' ) ) {
				$variation_data['image_original_id'] = null;
				if ( ! empty( $variant_node->media->edges ) ) {
					$variant_media_node = $variant_node->media->edges[0]->node ?? null;
					if ( $variant_media_node && property_exists( $variant_media_node, 'image' ) && is_object( $variant_media_node->image ) && ! empty( $variant_media_node->id ) ) {
						$variation_data['image_original_id'] = $variant_media_node->id;
					}
				}
			}

			// Menu Order / Position.
			$variation_data['menu_order'] = $variant_node->position;

			$variable_data['variations'][] = $variation_data;
		}
	}

	return $variable_data;
}