commerce_product_bundles-8.x-1.0/commerce_product_bundles.module
commerce_product_bundles.module
<?php
use Drupal\Core\Render\Element\RenderElement;
use Drupal\commerce_product_bundles\Form\AddToCartBundleForm;;
use Drupal\Core\Form\FormStateInterface;
use Drupal\Core\Render\Element;
use Drupal\Core\Template\Attribute;
use Drupal\commerce_product_bundles\Entity\ProductBundleVariationTypeInterface;
use Drupal\entity\BundleFieldDefinition;
use Drupal\Core\Entity\EntityForm;
use Drupal\Core\Plugin\PluginBase;
use Drupal\commerce_product_bundles\Plugin\Block\BundleVariationFieldBlock;
/**
* Adds the default bundle image field to a product bundle type.
*
* @param \Drupal\commerce_product_bundles\Entity\ProductBundleVariationTypeInterface $product_bundle_variation_type
*/
function commerce_product_bundles_add_variations_field(ProductBundleVariationTypeInterface $product_bundle_variation_type) {
$field_definition = BundleFieldDefinition::create('bundle_image')
->setLabel(t('Bundle Variation Image'))
->setName('field_bundle_image')
->setDescription(t('The products bundle variation image.'))
->setTargetEntityTypeId('commerce_bundle_variation')
->setTargetBundle($product_bundle_variation_type->id())
->setSetting('handler', 'default:file')
->setSetting('handler_settings', [])
->setDisplayOptions('view', [
'label' => 'above',
'type' => 'bundle_image',
'settings' => [
'image_style' => '',
'image_link' => ''
],
'weight' => 0,
])
->setDisplayOptions('form', [
'type' => 'bundle_image_image',
'settings' => [
'progress_indicator' => 'throbber',
'preview_image_style' => 'thumbnail'
],
])
->setCardinality(BundleFieldDefinition::CARDINALITY_UNLIMITED)
->setRequired(FALSE)
->setDisplayConfigurable('form', TRUE)
->setDisplayConfigurable('view', TRUE);
$configurable_field_manager = \Drupal::service('commerce.configurable_field_manager');
$configurable_field_manager->createField($field_definition);
}
/**
* Implements hook_form_BASE_FORM_ID_alter() for 'commerce_order_item_type_form'.
*/
function commerce_product_bundles_form_commerce_order_item_type_form_alter(array &$form, FormStateInterface $form_state) {
$form['actions']['submit']['#submit'][] = 'commerce_product_bundles_order_item_type_form_submit';
}
/**
* Form submission handler for 'commerce_order_item_type_form'.
*/
function commerce_product_bundles_order_item_type_form_submit($form, FormStateInterface $form_state) {
$form_object = $form_state->getFormObject();
assert($form_object instanceof EntityForm);
if ($form_object->getOperation() == 'add') {
// Add 'add_to_cart_bundle' form display.
$storage = \Drupal::entityTypeManager()->getStorage('entity_form_display');
/** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $form_display */
$form_display = $storage->create([
'targetEntityType' => 'commerce_order_item',
'bundle' => $form_object->getEntity()->id(),
'mode' => 'add_to_cart_bundle',
'status' => TRUE,
]);
$form_display->removeComponent('unit_price');
$form_display->save();
}
}
/**
* Implements hook_entity_bundle_create().
*
* Creates an 'add_to_cart_bundle' form display for each new order item type.
*/
function commerce_product_bundles_entity_bundle_create($entity_type_id, $bundle) {
if ($entity_type_id == 'commerce_order_item' && !\Drupal::isConfigSyncing()) {
$entity_storage = \Drupal::entityTypeManager()->getStorage('commerce_order_item_type');
$entity = $entity_storage->load($bundle);
// Add 'field_product_variation_ref' to bundle order items.
if ($entity->getPurchasableEntityTypeId() === 'commerce_bundle_variation') {
$field_definition = BundleFieldDefinition::create('bundle_ref_var_field')
->setLabel(t('Product Variation Reference'))
->setName('field_product_variation_ref')
->setDescription(t('The products bundle variation image.'))
->setTargetEntityTypeId($entity_type_id)
->setTargetBundle($bundle)
->setSetting('handler', 'default')
->setSetting('handler_settings', [])
->setDisplayOptions('view', [
'label' => 'above',
'type' => 'bundle_ref_var_field_formatter',
'settings' => []
])
->setCardinality(BundleFieldDefinition::CARDINALITY_UNLIMITED)
->setRequired(TRUE)
->setDisplayConfigurable('form', FALSE)
->setDisplayConfigurable('view', FALSE);
$configurable_field_manager = \Drupal::service('commerce.configurable_field_manager');
$configurable_field_manager->createField($field_definition, TRUE);
}
}
}
/**
* Implements hook_theme_registry_alter().
*
* @see commerce_product_theme_registry_alter()
*/
function commerce_product_bundles_theme_registry_alter(&$theme_registry) {
$theme_registry['field']['preprocess functions'][] = 'commerce_product_bundles_remove_quickedit';
}
/**
* Turn off Quick Edit for injected bundle variation fields, to avoid warnings.
*
* @see commerce_product_remove_quickedit()
*/
function commerce_product_bundles_remove_quickedit(&$variables) {
$entity_type_id = $variables['element']['#entity_type'];
if ($entity_type_id != 'commerce_bundle_variation' || empty($variables['element']['#ajax_replace_class'])) {
return;
}
if (isset($variables['attributes']['data-quickedit-field-id'])) {
unset($variables['attributes']['data-quickedit-field-id']);
$context_key = array_search('user.permissions', $variables['#cache']['contexts']);
unset($variables['#cache']['contexts'][$context_key]);
}
}
/**
* Implements hook_entity_type_build().
*/
function commerce_product_bundles_entity_type_build(array &$entity_types) {
$entity_types['commerce_order_item']->setFormClass('add_to_cart_bundle', AddToCartBundleForm::class);
}
/**
* Implements hook_form_FORM_ID_alter() for 'entity_form_display_edit_form'.
*
* Hides irrelevant purchased_entity widgets on the add_to_cart order item
* form display.
*/
function commerce_product_bundles_form_entity_form_display_edit_form_alter(array &$form, FormStateInterface $form_state) {
/** @var \Drupal\Core\Entity\Display\EntityFormDisplayInterface $entity */
$entity = $form_state->getFormObject()->getEntity();
if ($form['#entity_type'] == 'commerce_order_item' && ($entity->getMode() == 'add_to_cart_bundle')) {
$options = &$form['fields']['purchased_entity']['plugin']['type']['#options'];
unset($options['commerce_entity_select']);
unset($options['entity_reference_autocomplete_tags']);
unset($options['entity_reference_autocomplete']);
unset($options['inline_entity_form_complex']);
unset($options['options_buttons']);
unset($options['options_select']);
}
}
/**
* Implements hook_theme().
*/
function commerce_product_bundles_theme() {
return [
'commerce_product_bundles_form' => [
'render element' => 'form',
],
'commerce_product_bundles' => [
'render element' => 'elements',
],
'commerce_product_bundles_variation' => [
'render element' => 'elements',
],
'commerce_bundle_price_calculated' => [
'variables' => [
'bundle_price' => NULL,
'original_price' => NULL,
'savings_price' => NULL
],
],
'commerce_original_price_calculated' => [
'variables' => [
'result' => NULL,
'base_price' => NULL,
'calculated_price' => NULL,
'adjustments' => [],
],
],
'commerce_bundle_bundle_price_calculated' => [
'variables' => [
'result' => NULL,
'base_price' => NULL,
'calculated_price' => NULL,
'adjustments' => [],
],
],
'commerce_savings_price_calculated' => [
'variables' => [
'result' => NULL,
'base_price' => NULL,
'calculated_price' => NULL,
'adjustments' => [],
],
],
'bundle_ref_default_select' => [
'render element' => 'element',
],
'bundle_ref_default_select_wrapper' => [
'render element' => 'element',
],
'commerce_bundle_savings_label' => [
'variables' => [
'savings' => NULL,
'label' => NULL,
],
],
];
}
/**
* Implements hook_theme_suggestions_commerce_product().
*/
function commerce_product_bundles_theme_suggestions_commerce_product_bundles(array $variables) {
return _commerce_entity_theme_suggestions('commerce_product_bundles', $variables);
}
/**
* Implements hook_theme_suggestions_commerce_product_variation().
*/
function commerce_product_bundles_theme_suggestions_commerce_product_bundles_variation(array $variables) {
return _commerce_entity_theme_suggestions('commerce_product_bundles_variation', $variables);
}
/**
* Prepares variables for product bundle templates.
*
* @param array $variables
*
* @throws \Drupal\Core\Entity\EntityMalformedException
*/
function template_preprocess_commerce_product_bundles(array &$variables) {
/** @var Drupal\commerce_product_bundles\Entity\ProductBundleInterface $product_bundle */
$product_bundle = $variables['elements']['#commerce_product_bundles'];
$variables['product_bundle_entity'] = $product_bundle;
$variables['product_bundle_url'] = $product_bundle->isNew() ? '' : $product_bundle->toUrl();
$variables['product_bundle'] = [];
foreach (Element::children($variables['elements']) as $key) {
$variables['product_bundle'][$key] = $variables['elements'][$key];
}
}
/**
* Prepares variables for product bundle variations templates.
*
* @param array $variables
*
* @throws \Drupal\Core\Entity\EntityMalformedException
*/
function template_preprocess_commerce_product_bundles_variation(array &$variables) {
/** @var Drupal\commerce_product_bundles\Entity\ProductBundleVariationInterface $product_bundle_variation */
$product_bundle_variation = $variables['elements']['#bundle_variation'];
$product_bundle = $product_bundle_variation->getBundleProduct();
$variables['product_bundle_variation_entity'] = $product_bundle_variation;
$variables['product_bundle_url'] = '';
if ($product_bundle && !$product_bundle->isNew()) {
$variables['product_bundle_url'] = $product_bundle->toUrl();
}
$variables['product_bundle_variation'] = [];
foreach (Element::children($variables['elements']) as $key) {
$variables['product_bundle_variation'][$key] = $variables['elements'][$key];
}
}
/**
* Implements hook_preprocess().
* see template_preprocess_fieldset()
*/
function template_preprocess_bundle_ref_default_select(&$variables, $hook) {
$element = $variables['element'];
Element::setAttributes($element, ['id']);
RenderElement::setAttributes($element);
$variables['attributes'] = isset($element['#attributes']) ? $element['#attributes'] : [];
$variables['prefix'] = isset($element['#field_prefix']) ? $element['#field_prefix'] : NULL;
$variables['suffix'] = isset($element['#field_suffix']) ? $element['#field_suffix'] : NULL;
$variables['title_display'] = isset($element['#title_display']) ? $element['#title_display'] : NULL;
$variables['children'] = $element['#children'];
$variables['required'] = !empty($element['#required']) ? $element['#required'] : NULL;
$variables['attribute_title'] = !empty($element['#attribute_title']) ? $element['#attribute_title'] : NULL;
if (isset($element['#title']) && $element['#title'] !== '') {
$variables['legend']['title'] = ['#markup' => $element['#title']];
}
$variables['legend']['attributes'] = new Attribute();
// Add 'visually-hidden' class to legend span.
if ($variables['title_display'] == 'invisible') {
$variables['legend_span']['attributes'] = new Attribute(['class' => ['visually-hidden']]);
}
else {
$variables['legend_span']['attributes'] = new Attribute();
}
if (!empty($element['#description'])) {
$description_id = $element['#attributes']['id'] . '--description';
$description_attributes['id'] = $description_id;
$variables['description']['attributes'] = new Attribute($description_attributes);
$variables['description']['content'] = $element['#description'];
// Add the description's id to the fieldset aria attributes.
$variables['attributes']['aria-describedby'] = $description_id;
}
// Suppress error messages.
$variables['errors'] = NULL;
}
/**
* Implements hook_block_alter().
*/
function commerce_product_bundles_block_alter(array &$info) {
if (\Drupal::moduleHandler()->moduleExists('layout_builder')) {
$base_plugin_id = 'field_block' . PluginBase::DERIVATIVE_SEPARATOR . 'commerce_bundle_variation' . PluginBase::DERIVATIVE_SEPARATOR;
foreach ($info as $block_plugin_id => $block_definition) {
if (strpos($block_plugin_id, $base_plugin_id) !== FALSE) {
$info[$block_plugin_id]['class'] = BundleVariationFieldBlock::class;
}
}
}
}
