class CombinationOffer in Commerce Core 8.2
Provides the 'combination_offer' offer plugin.
This provides support for combining/stacking multiple promotion offers.
Plugin annotation
@CommercePromotionOffer(
id = "combination_offer",
label = @Translation("Combination offer"),
entity_type = "commerce_order",
)
Hierarchy
- class \Drupal\Component\Plugin\PluginBase implements DerivativeInspectionInterface, PluginInspectionInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
- class \Drupal\commerce_promotion\Plugin\Commerce\PromotionOffer\PromotionOfferBase implements PromotionOfferInterface, ContainerFactoryPluginInterface
- class \Drupal\commerce_promotion\Plugin\Commerce\PromotionOffer\OrderPromotionOfferBase implements OrderPromotionOfferInterface
- class \Drupal\commerce_promotion\Plugin\Commerce\PromotionOffer\CombinationOffer implements CombinationOfferInterface
- class \Drupal\commerce_promotion\Plugin\Commerce\PromotionOffer\OrderPromotionOfferBase implements OrderPromotionOfferInterface
- class \Drupal\commerce_promotion\Plugin\Commerce\PromotionOffer\PromotionOfferBase implements PromotionOfferInterface, ContainerFactoryPluginInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
Expanded class hierarchy of CombinationOffer
1 file declares its use of CombinationOffer
- PromotionTest.php in modules/
promotion/ tests/ src/ FunctionalJavascript/ PromotionTest.php
File
- modules/
promotion/ src/ Plugin/ Commerce/ PromotionOffer/ CombinationOffer.php, line 26
Namespace
Drupal\commerce_promotion\Plugin\Commerce\PromotionOfferView source
class CombinationOffer extends OrderPromotionOfferBase implements CombinationOfferInterface {
/**
* The inline form manager.
*
* @var \Drupal\commerce\InlineFormManager
*/
protected $inlineFormManager;
/**
* The promotion offer manager.
*
* @var \Drupal\commerce_promotion\PromotionOfferManager
*/
protected $offerManager;
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
$instance = parent::create($container, $configuration, $plugin_id, $plugin_definition);
$instance->inlineFormManager = $container
->get('plugin.manager.commerce_inline_form');
$instance->offerManager = $container
->get('plugin.manager.commerce_promotion_offer');
return $instance;
}
/**
* {@inheritdoc}
*/
public function defaultConfiguration() {
return [
'offers' => [],
] + parent::defaultConfiguration();
}
/**
* {@inheritdoc}
*/
public function buildConfigurationForm(array $form, FormStateInterface $form_state) {
$form += parent::buildConfigurationForm($form, $form_state);
// Remove the main fieldset.
$form['#type'] = 'container';
$wrapper_id = Html::getUniqueId('combination-offer-ajax-wrapper');
$form['#prefix'] = '<div id="' . $wrapper_id . '">';
$form['#suffix'] = '</div>';
// Remove the combination offer from the allowed plugins.
$definitions = array_diff_key($this->offerManager
->getDefinitions(), [
$this->pluginId => '',
]);
$plugins = array_map(static function ($definition) {
return $definition['label'];
}, $definitions);
asort($plugins);
$user_input = (array) NestedArray::getValue($form_state
->getUserInput(), $form['#parents']);
// Initialize the offers form.
if (!$form_state
->get('offers_form_initialized')) {
$offers = $this->configuration['offers'] ?: [
NULL,
];
// Initialize the offers with the user input if present.
if (isset($user_input['offers'])) {
$offers = $user_input['offers'];
}
$form_state
->set('offers', $offers);
$form_state
->set('offers_form_initialized', TRUE);
}
$class = get_class($this);
foreach ($form_state
->get('offers') as $index => $offer) {
// Override the offer with the user input if present.
if (!empty($user_input['offers'][$index])) {
$offer = $user_input['offers'][$index];
}
$offer_form =& $form['offers'][$index];
$offer_form['configuration'] = [
'#type' => 'fieldset',
'#title' => $this
->t('Offer #@index', [
'@index' => $index + 1,
]),
'#tree' => FALSE,
];
$offer_form['configuration']['target_plugin_id'] = [
'#type' => 'select',
'#title' => $this
->t('Type'),
'#options' => $plugins,
'#default_value' => $offer['target_plugin_id'] ?? '',
// Force the user to select a value.
'#empty_value' => '',
// Only require at least an offer.
'#required' => $index === 0,
'#ajax' => [
'callback' => [
$class,
'ajaxCallback',
],
'wrapper' => $wrapper_id,
],
'#parents' => array_merge($form['#parents'], [
'offers',
$index,
'target_plugin_id',
]),
];
// When a target plugin ID is selected, embed the offer configuration
// form.
if (!empty($offer['target_plugin_id'])) {
$inline_form = $this->inlineFormManager
->createInstance('plugin_configuration', [
'plugin_type' => 'commerce_promotion_offer',
'plugin_id' => $offer['target_plugin_id'],
'plugin_configuration' => $offer['target_plugin_configuration'] ?? [],
]);
$offer_form['configuration']['target_plugin_configuration'] = [
'#inline_form' => $inline_form,
'#parents' => array_merge($form['#parents'], [
'offers',
$index,
'target_plugin_configuration',
]),
];
$offer_form['configuration']['target_plugin_configuration'] = $inline_form
->buildInlineForm($offer_form['configuration']['target_plugin_configuration'], $form_state);
}
// Don't allow removing the first offer.
if ($index > 0) {
$offer_form['configuration']['remove'] = [
'#type' => 'submit',
'#name' => 'remove_offer' . $index,
'#value' => $this
->t('Remove'),
'#limit_validation_errors' => [],
'#submit' => [
[
$class,
'removeOfferSubmit',
],
],
'#offer_index' => $index,
'#parents' => array_merge($form['#parents'], [
'offers',
$index,
'remove',
]),
'#ajax' => [
'callback' => [
$class,
'ajaxCallback',
],
'wrapper' => $wrapper_id,
],
];
}
}
$form['offers'][] = [
'add_offer' => [
'#type' => 'submit',
'#value' => $this
->t('Add another offer'),
'#submit' => [
[
$class,
'addOfferSubmit',
],
],
'#limit_validation_errors' => [
array_merge($form['#parents'], [
'offers',
]),
],
'#ajax' => [
'callback' => [
$class,
'ajaxCallback',
],
'wrapper' => $wrapper_id,
],
],
];
return $form;
}
/**
* {@inheritdoc}
*/
public function validateConfigurationForm(array &$form, FormStateInterface $form_state) {
$values = $form_state
->getValue($form['#parents']);
// Filter out the button rows.
$values['offers'] = array_filter($values['offers'], function ($offer) {
return !empty($offer['target_plugin_id']) && !empty($offer['target_plugin_configuration']) && !isset($offer['add_offer']);
});
$form_state
->setValue($form['#parents'], $values);
if (empty($values['offers'])) {
$form_state
->setError($form['offers'], $this
->t('Please configure at least one offer.'));
}
}
/**
* {@inheritdoc}
*/
public function submitConfigurationForm(array &$form, FormStateInterface $form_state) {
parent::submitConfigurationForm($form, $form_state);
if (!$form_state
->getErrors()) {
$this->configuration['offers'] = [];
$values = $form_state
->getValue($form['#parents']);
foreach (array_filter($values['offers']) as $offer) {
$this->configuration['offers'][] = $offer;
}
}
}
/**
* Ajax callback.
*/
public static function ajaxCallback(array $form, FormStateInterface $form_state) {
$triggering_element = $form_state
->getTriggeringElement();
$parents = $triggering_element['#array_parents'];
$form_index = array_search('form', $parents, TRUE);
$parents = array_splice($parents, 0, $form_index + 1);
return NestedArray::getValue($form, $parents);
}
/**
* Submit callback for adding a new offer.
*/
public static function addOfferSubmit(array $form, FormStateInterface $form_state) {
$offers = $form_state
->get('offers');
$offers[] = [];
$form_state
->set('offers', $offers);
$form_state
->setRebuild();
}
/**
* Submit callback for removing an offer.
*/
public static function removeOfferSubmit(array $form, FormStateInterface $form_state) {
$offers = $form_state
->get('offers');
$index = $form_state
->getTriggeringElement()['#offer_index'];
unset($offers[$index]);
$form_state
->set('offers', $offers);
$form_state
->setRebuild();
}
/**
* {@inheritdoc}
*/
public function apply(EntityInterface $entity, PromotionInterface $promotion) {
assert($entity instanceof OrderInterface);
// This is copied from Promotion::apply().
foreach ($this
->getOffers() as $offer) {
if ($offer instanceof OrderItemPromotionOfferInterface) {
$offer_conditions = new ConditionGroup($offer
->getConditions(), $offer
->getConditionOperator());
// Apply the offer to order items that pass the conditions.
foreach ($entity
->getItems() as $order_item) {
// Skip order items with a null unit price or with a quantity = 0.
if (!$order_item
->getUnitPrice() || Calculator::compare($order_item
->getQuantity(), '0') === 0) {
continue;
}
if ($offer_conditions
->evaluate($order_item)) {
$offer
->apply($order_item, $promotion);
}
}
}
else {
$offer
->apply($entity, $promotion);
}
}
}
/**
* {@inheritdoc}
*/
public function getOffers() {
$offers = [];
foreach ($this->configuration['offers'] as $offer) {
$offers[] = $this->offerManager
->createInstance($offer['target_plugin_id'], $offer['target_plugin_configuration']);
}
return $offers;
}
}
Members
Name![]() |
Modifiers | Type | Description | Overrides |
---|---|---|---|---|
CombinationOffer:: |
protected | property | The inline form manager. | |
CombinationOffer:: |
protected | property | The promotion offer manager. | |
CombinationOffer:: |
public static | function | Submit callback for adding a new offer. | |
CombinationOffer:: |
public static | function | Ajax callback. | |
CombinationOffer:: |
public | function |
Applies the offer to the given entity. Overrides PromotionOfferInterface:: |
|
CombinationOffer:: |
public | function |
Form constructor. Overrides PromotionOfferBase:: |
|
CombinationOffer:: |
public static | function |
Creates an instance of the plugin. Overrides OrderPromotionOfferBase:: |
|
CombinationOffer:: |
public | function |
Gets default configuration for this plugin. Overrides PromotionOfferBase:: |
|
CombinationOffer:: |
public | function |
Gets the offers configured. Overrides CombinationOfferInterface:: |
|
CombinationOffer:: |
public static | function | Submit callback for removing an offer. | |
CombinationOffer:: |
public | function |
Form submission handler. Overrides PromotionOfferBase:: |
|
CombinationOffer:: |
public | function |
Form validation handler. Overrides PromotionOfferBase:: |
|
DependencySerializationTrait:: |
protected | property | An array of entity type IDs keyed by the property name of their storages. | |
DependencySerializationTrait:: |
protected | property | An array of service IDs keyed by property name used for serialization. | |
DependencySerializationTrait:: |
public | function | 1 | |
DependencySerializationTrait:: |
public | function | 2 | |
MessengerTrait:: |
protected | property | The messenger. | 29 |
MessengerTrait:: |
public | function | Gets the messenger. | 29 |
MessengerTrait:: |
public | function | Sets the messenger. | |
OrderPromotionOfferBase:: |
protected | property | The price splitter. | |
OrderPromotionOfferBase:: |
public | function |
Constructs a new OrderPromotionOfferBase object. Overrides PromotionOfferBase:: |
1 |
PluginBase:: |
protected | property | Configuration information passed into the plugin. | 1 |
PluginBase:: |
protected | property | The plugin implementation definition. | 1 |
PluginBase:: |
protected | property | The plugin_id. | |
PluginBase:: |
constant | A string which is used to separate base plugin IDs from the derivative ID. | ||
PluginBase:: |
public | function |
Gets the base_plugin_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the derivative_id of the plugin instance. Overrides DerivativeInspectionInterface:: |
|
PluginBase:: |
public | function |
Gets the definition of the plugin implementation. Overrides PluginInspectionInterface:: |
3 |
PluginBase:: |
public | function |
Gets the plugin_id of the plugin instance. Overrides PluginInspectionInterface:: |
|
PluginBase:: |
public | function | Determines if the plugin is configurable. | |
PromotionOfferBase:: |
protected | property | The rounder. | |
PromotionOfferBase:: |
protected | function | Asserts that the given entity is of the expected type. | |
PromotionOfferBase:: |
public | function |
Allows an offer to clean up any modifications done to the given entity. Overrides PromotionOfferInterface:: |
1 |
PromotionOfferBase:: |
public | function |
Gets this plugin's configuration. Overrides ConfigurableInterface:: |
|
PromotionOfferBase:: |
public | function |
Gets the offer entity type ID. Overrides PromotionOfferInterface:: |
|
PromotionOfferBase:: |
public | function |
Sets the configuration for this plugin instance. Overrides ConfigurableInterface:: |
|
StringTranslationTrait:: |
protected | property | The string translation service. | 1 |
StringTranslationTrait:: |
protected | function | Formats a string containing a count of items. | |
StringTranslationTrait:: |
protected | function | Returns the number of plurals supported by a given language. | |
StringTranslationTrait:: |
protected | function | Gets the string translation service. | |
StringTranslationTrait:: |
public | function | Sets the string translation service to use. | 2 |
StringTranslationTrait:: |
protected | function | Translates a string to the current language or to a given language. |