public function ProductVariationAttributeMapper::prepareAttributes in Commerce Core 8.2
Prepares the available attributes for the selected product variation.
The attribute and its values are retrieved in the language of the variation. Values not corresponding to any variation are removed.
Parameters
\Drupal\commerce_product\Entity\ProductVariationInterface $selected_variation: The selected product variation.
\Drupal\commerce_product\Entity\ProductVariationInterface[] $variations: The available product variations.
Return value
\Drupal\commerce_product\PreparedAttribute[] The prepared attributes, keyed by field name.
Overrides ProductVariationAttributeMapperInterface::prepareAttributes
File
- modules/
product/ src/ ProductVariationAttributeMapper.php, line 77
Class
Namespace
Drupal\commerce_productCode
public function prepareAttributes(ProductVariationInterface $selected_variation, array $variations) {
$attributes = [];
$field_definitions = $this->attributeFieldManager
->getFieldDefinitions($selected_variation
->bundle());
$field_map = $this->attributeFieldManager
->getFieldMap($selected_variation
->bundle());
$field_names = array_column($field_map, 'field_name');
$attribute_ids = array_column($field_map, 'attribute_id');
$index = 0;
foreach ($field_names as $field_name) {
$field = $field_definitions[$field_name];
/** @var \Drupal\commerce_product\Entity\ProductAttributeInterface $attribute */
$attribute = $this->attributeStorage
->load($attribute_ids[$index]);
// Make sure we have translation for attribute.
$attribute = $this->entityRepository
->getTranslationFromContext($attribute, $selected_variation
->language()
->getId());
$definition = [
'id' => $attribute
->id(),
'label' => $attribute
->label(),
'element_type' => $attribute
->getElementType(),
'required' => $field
->isRequired(),
];
// The first attribute gets all values. Every next attribute gets only
// the values from variations matching the previous attribute value.
// For 'Color' and 'Size' attributes that means getting the colors of all
// variations, but only the sizes of variations with the selected color.
$callback = NULL;
if ($index > 0) {
$index_limit = $index - 1;
// Get all previous field values.
$previous_variation_field_values = [];
for ($i = 0; $i <= $index_limit; $i++) {
$previous_variation_field_values[$field_names[$i]] = $selected_variation
->getAttributeValueId($field_names[$i]);
}
$callback = function (ProductVariationInterface $variation) use ($previous_variation_field_values) {
$results = [];
foreach ($previous_variation_field_values as $previous_field_name => $previous_field_value) {
$results[] = $variation
->getAttributeValueId($previous_field_name) == $previous_field_value;
}
return !in_array(FALSE, $results, TRUE);
};
}
$definition['values'] = $this
->getAttributeValues($variations, $field_name, $callback);
// Return the attribute only if it has at least one value.
if (!empty($definition['values'])) {
$attributes[$field_name] = new PreparedAttribute($definition);
}
$index++;
}
return $attributes;
}