WC_Product_Variable_Data_Store_CPT::read_variation_attributespublicWC 1.0

Loads an array of attributes used for variations, as well as their possible values.

Method of the class: WC_Product_Variable_Data_Store_CPT{}

No Hooks.

Returns

array.

Usage

$WC_Product_Variable_Data_Store_CPT = new WC_Product_Variable_Data_Store_CPT();
$WC_Product_Variable_Data_Store_CPT->read_variation_attributes( $product );
$product(WC_Product) (required) (passed by reference — &)
Product object.

WC_Product_Variable_Data_Store_CPT::read_variation_attributes() code WC 11.1.1

public function read_variation_attributes( &$product ) {
	global $wpdb;

	$product_id  = $product->get_id();
	$cache_key   = WC_Cache_Helper::get_cache_prefix( 'product_' . $product_id ) . 'product_variation_attributes_' . $product_id;
	$cached_data = wp_cache_get( $cache_key, 'products' );

	if ( false !== $cached_data ) {
		return $cached_data;
	}

	$variation_attributes = array();
	$attributes           = $product->get_attributes();

	if ( ! empty( $attributes ) ) {
		$child_ids  = $product->get_children();
		$attributes = array_values( array_filter( $attributes, static fn ( $attribute ) => ! empty( $attribute['is_variation'] ) ) );

		$attributes_values = array();
		if ( ! empty( $child_ids ) && ! empty( $attributes ) ) {
			// Performance note: for optimal performance, retrieve attribute values using a single SQL query.
			$attributes_placeholders = implode( ', ', array_fill( 0, count( $attributes ), '%s' ) );
			$children_placeholders   = implode( ', ', array_fill( 0, count( $child_ids ), '%d' ) );
			$prefetch                = $wpdb->get_results(
				$wpdb->prepare(
					// Performance: DISTINCT + CAST(meta_value AS BINARY(200)) is feasible but forces a temp table — keep array_unique.
					// phpcs:ignore WordPress.DB.PreparedSQL.InterpolatedNotPrepared, WordPress.DB.PreparedSQLPlaceholders.UnfinishedPrepare
					"SELECT meta_key, meta_value FROM {$wpdb->postmeta} WHERE post_id IN ( {$children_placeholders} ) AND meta_key IN ( {$attributes_placeholders} )",
					...$child_ids,
					...array_map( static fn( $attribute ) => wc_variation_attribute_name( $attribute['name'] ), $attributes )
				)
			);
			foreach ( $prefetch as $row ) {
				// Defensive: normalize non-canonical meta_key casing (e.g. attribute_pa_Size → attribute_pa_size).
				// sanitize_title over wc_variation_attribute_name as the latter adds 'attribute_' prefix.
				$attributes_values[ sanitize_title( $row->meta_key ) ][] = $row->meta_value;
			}
		}

		foreach ( $attributes as $attribute ) {
			$values = $attributes_values[ wc_variation_attribute_name( $attribute['name'] ) ] ?? array();

			// Empty value indicates that all options for given attribute are available.
			if ( empty( $values ) || in_array( null, $values, true ) || in_array( '', $values, true ) ) {
				$values = $attribute['is_taxonomy'] ? wc_get_object_terms( $product_id, $attribute['name'], 'slug' ) : wc_get_text_attributes( $attribute['value'] );
				// Get custom attributes (non taxonomy) as defined.
			} elseif ( ! $attribute['is_taxonomy'] ) {
				$text_attributes          = wc_get_text_attributes( $attribute['value'] );
				$assigned_text_attributes = $values;
				$values                   = array();

				// Pre 2.4 handling where 'slugs' were saved instead of the full text attribute.
				if ( version_compare( get_post_meta( $product_id, '_product_version', true ), '2.4.0', '<' ) ) {
					$assigned_text_attributes = array_map( 'sanitize_title', $assigned_text_attributes );
					foreach ( $text_attributes as $text_attribute ) {
						if ( in_array( sanitize_title( $text_attribute ), $assigned_text_attributes, true ) ) {
							$values[] = $text_attribute;
						}
					}
				} else {
					foreach ( $text_attributes as $text_attribute ) {
						if ( in_array( $text_attribute, $assigned_text_attributes, true ) ) {
							$values[] = $text_attribute;
						}
					}
				}
			}
			$variation_attributes[ $attribute['name'] ] = array_unique( $values );
		}
	}

	wp_cache_set( $cache_key, $variation_attributes, 'products' );

	return $variation_attributes;
}