private function ProductBundleItemsWidget::getBundleItemForm in Commerce Product Bundle 8
Gets the child form element for a given bundle item.
Parameters
\Drupal\commerce_product_bundle\Entity\BundleItemInterface $bundle_item: The bundle item.
array $form: The complete form array.
\Drupal\Core\Form\FormStateInterface $form_state: The current state of the form.
array $parents: The parents of the bundle item form element in the form structure.
Return value
array A renderable form array for the given bundle item.
1 call to ProductBundleItemsWidget::getBundleItemForm()
- ProductBundleItemsWidget::formElement in src/
Plugin/ Field/ FieldWidget/ ProductBundleItemsWidget.php - Returns the form for a single field widget.
File
- src/
Plugin/ Field/ FieldWidget/ ProductBundleItemsWidget.php, line 132
Class
- ProductBundleItemsWidget
- Plugin implementation of the 'commerce_product_bundle_items' widget.
Namespace
Drupal\commerce_product_bundle\Plugin\Field\FieldWidgetCode
private function getBundleItemForm(BundleItemInterface $bundle_item, array &$form, FormStateInterface $form_state, array $parents) {
$bundle_item_form = [
'bundle_item' => [
'#type' => 'value',
'#value' => $bundle_item,
],
];
/** @var \Drupal\commerce_product\Entity\ProductInterface $product */
$product = $bundle_item
->getProduct();
/** @var \Drupal\commerce_product\Entity\ProductVariationInterface[] $variations */
$variations = $bundle_item
->getVariations();
$min_qty = $bundle_item
->getMinimumQuantity();
$max_qty = $bundle_item
->getMaximumQuantity();
if ($min_qty === $max_qty) {
$bundle_item_form['qty'] = [
'#type' => 'value',
'#value' => $bundle_item
->getQuantity(),
];
}
else {
$bundle_item_form['qty'] = [
'#type' => 'number',
'#title' => $this
->t('Quantity'),
'#min' => $min_qty,
'#max' => $max_qty,
'#default_value' => $min_qty,
'#step' => 1,
];
}
if (count($variations) === 0) {
// Nothing to purchase, tell the parent form to hide itself.
$form_state
->set('hide_form', TRUE);
$bundle_item_form['variation'] = [
'#type' => 'value',
'#value' => 0,
];
return $bundle_item_form;
}
elseif (count($variations) === 1) {
/** @var \Drupal\commerce_product\Entity\ProductVariationInterface $selected_variation */
$selected_variation = reset($variations);
// For regular products, from which this logic was adapted, the variation
// form is only hidden (with simply this value stored) when the variation
// has no attribute fields (to show the customer which variation they are
// purchasing). But since the product bundle is expected to indicate the
// items in the bundle, and to avoid unnecessary UI clutter, we hide all
// attribute widgets when there is only one variation.
// Compare this with ProductVariationAttributesWidget::formElement.
$bundle_item_form['variation'] = [
'#type' => 'value',
'#value' => $selected_variation
->id(),
];
$bundle_item
->setCurrentVariation($selected_variation);
$bundle_item_form['title'] = [
'#type' => 'markup',
'#markup' => $bundle_item
->getTitle(),
'#prefix' => '<p>',
'#suffix' => '</p>',
];
return $bundle_item_form;
}
// Build the bundle item's full attribute form.
$wrapper_id = Html::getUniqueId('commerce-product-bundle-item-add-to-cart-form');
$bundle_item_form += [
'#wrapper_id' => $wrapper_id,
'#prefix' => '<div id="' . $wrapper_id . '">',
'#suffix' => '</div>',
];
$user_input = (array) NestedArray::getValue($form_state
->getUserInput(), $parents);
if (!empty($user_input)) {
$selected_variation = $this
->selectVariationFromUserInput($variations, $user_input);
}
else {
$selected_variation = $this->variationStorage
->loadFromContext($product);
// The returned variation must also be enabled.
if (!in_array($selected_variation, $variations)) {
$selected_variation = reset($variations);
}
}
$bundle_item_form['variation'] = [
'#type' => 'value',
'#value' => $selected_variation
->id(),
];
$bundle_item
->setCurrentVariation($selected_variation);
// Set the selected variation in the form state for our AJAX callback.
$form_state
->set('purchased_entity][widget][0][bundle_items][' . $bundle_item
->id() . '][selected_variation', $selected_variation
->id());
$bundle_item_form['attributes'] = [
'#type' => 'container',
'#attributes' => [
'class' => [
'attribute-widgets',
],
],
];
foreach ($this
->getItemAttributeInfo($selected_variation, $variations) as $field_name => $attribute) {
$bundle_item_form['attributes'][$field_name] = [
'#type' => $attribute['element_type'],
'#title' => $attribute['title'],
'#options' => $attribute['values'],
'#required' => $attribute['required'],
'#default_value' => $selected_variation
->getAttributeValueId($field_name),
'#ajax' => [
'callback' => [
get_class($this),
'ajaxRefresh',
],
'wrapper' => $bundle_item_form['#wrapper_id'],
],
];
// Convert the _none option into #empty_value.
if (isset($bundle_item_form['attributes'][$field_name]['#options']['_none'])) {
if (!$bundle_item_form['attributes'][$field_name]['#required']) {
$bundle_item_form['attributes'][$field_name]['#empty_value'] = '';
}
unset($bundle_item_form['attributes'][$field_name]['#options']['_none']);
}
// 1 required value -> Disable the bundle_item_variations to skip unneeded ajax calls.
if ($attribute['required'] && count($attribute['values']) === 1) {
$bundle_item_form['attributes'][$field_name]['#disabled'] = TRUE;
}
// Optimize the UX of optional attributes:
// - Hide attributes that have no values.
// - Require attributes that have a value on each variation.
if (empty($bundle_item_form['attributes'][$field_name]['#options'])) {
$bundle_item_form['attributes'][$field_name]['#access'] = FALSE;
}
if (!isset($bundle_item_form['attributes'][$field_name]['#empty_value'])) {
$bundle_item_form['attributes'][$field_name]['#required'] = TRUE;
}
}
return $bundle_item_form;
}