class CouponRedemption in Commerce Core 8.2
Same name in this branch
- 8.2 modules/promotion/src/Plugin/views/area/CouponRedemption.php \Drupal\commerce_promotion\Plugin\views\area\CouponRedemption
- 8.2 modules/promotion/src/Plugin/Commerce/CheckoutPane/CouponRedemption.php \Drupal\commerce_promotion\Plugin\Commerce\CheckoutPane\CouponRedemption
- 8.2 modules/promotion/src/Plugin/Commerce/InlineForm/CouponRedemption.php \Drupal\commerce_promotion\Plugin\Commerce\InlineForm\CouponRedemption
Provides an inline form for redeeming a coupon.
Plugin annotation
@CommerceInlineForm(
id = "coupon_redemption",
label = @Translation("Coupon redemption"),
)
Hierarchy
- class \Drupal\Component\Plugin\PluginBase implements DerivativeInspectionInterface, PluginInspectionInterface
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
- class \Drupal\commerce\Plugin\Commerce\InlineForm\InlineFormBase implements InlineFormInterface, ContainerFactoryPluginInterface uses AjaxFormTrait
- class \Drupal\commerce_promotion\Plugin\Commerce\InlineForm\CouponRedemption
- class \Drupal\commerce\Plugin\Commerce\InlineForm\InlineFormBase implements InlineFormInterface, ContainerFactoryPluginInterface uses AjaxFormTrait
- class \Drupal\Core\Plugin\PluginBase uses DependencySerializationTrait, MessengerTrait, StringTranslationTrait
Expanded class hierarchy of CouponRedemption
File
- modules/
promotion/ src/ Plugin/ Commerce/ InlineForm/ CouponRedemption.php, line 20
Namespace
Drupal\commerce_promotion\Plugin\Commerce\InlineFormView source
class CouponRedemption extends InlineFormBase {
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* Constructs a new CouponRedemption object.
*
* @param array $configuration
* A configuration array containing information about the plugin instance.
* @param string $plugin_id
* The plugin_id for the plugin instance.
* @param mixed $plugin_definition
* The plugin implementation definition.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
*/
public function __construct(array $configuration, $plugin_id, $plugin_definition, EntityTypeManagerInterface $entity_type_manager) {
parent::__construct($configuration, $plugin_id, $plugin_definition);
$this->entityTypeManager = $entity_type_manager;
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) {
return new static($configuration, $plugin_id, $plugin_definition, $container
->get('entity_type.manager'));
}
/**
* {@inheritdoc}
*/
public function defaultConfiguration() {
return [
// The order_id is passed via configuration to avoid serializing the
// order, which is loaded from scratch in the submit handler to minimize
// chances of a conflicting save.
'order_id' => '',
// NULL for unlimited.
'max_coupons' => NULL,
];
}
/**
* {@inheritdoc}
*/
protected function requiredConfiguration() {
return [
'order_id',
];
}
/**
* {@inheritdoc}
*/
public function buildInlineForm(array $inline_form, FormStateInterface $form_state) {
$inline_form = parent::buildInlineForm($inline_form, $form_state);
$order = $this->entityTypeManager
->getStorage('commerce_order')
->load($this->configuration['order_id']);
if (!$order) {
throw new \RuntimeException('Invalid order_id given to the coupon_redemption inline form.');
}
assert($order instanceof OrderInterface);
/** @var \Drupal\commerce_promotion\Entity\CouponInterface[] $coupons */
$coupons = $order
->get('coupons')
->referencedEntities();
$inline_form = [
'#tree' => TRUE,
'#attached' => [
'library' => [
'commerce_promotion/coupon_redemption_form',
],
],
'#theme' => 'commerce_coupon_redemption_form',
'#configuration' => $this
->getConfiguration(),
] + $inline_form;
$inline_form['code'] = [
'#type' => 'textfield',
'#title' => $this
->t('Coupon code'),
// Chrome autofills this field with the address line 1, and ignores
// autocomplete => 'off', but respects 'new-password'.
'#attributes' => [
'autocomplete' => 'new-password',
],
];
$inline_form['apply'] = [
'#type' => 'submit',
'#value' => $this
->t('Apply coupon'),
'#name' => 'apply_coupon',
'#limit_validation_errors' => [
$inline_form['#parents'],
],
'#submit' => [
[
get_called_class(),
'applyCoupon',
],
],
'#ajax' => [
'callback' => [
get_called_class(),
'ajaxRefreshForm',
],
'element' => $inline_form['#parents'],
],
];
$max_coupons = $this->configuration['max_coupons'];
if ($max_coupons && count($coupons) >= $max_coupons) {
// Don't allow additional coupons to be added.
$inline_form['code']['#access'] = FALSE;
$inline_form['apply']['#access'] = FALSE;
}
foreach ($coupons as $index => $coupon) {
$inline_form['coupons'][$index]['code'] = [
'#plain_text' => $coupon
->getCode(),
];
$inline_form['coupons'][$index]['display_name'] = [
// @todo Use the promotion display name once added.
'#plain_text' => $coupon
->getPromotion()
->label(),
];
$inline_form['coupons'][$index]['remove_button'] = [
'#type' => 'submit',
'#value' => $this
->t('Remove coupon'),
'#name' => 'remove_coupon_' . $index,
'#ajax' => [
'callback' => [
get_called_class(),
'ajaxRefreshForm',
],
'element' => $inline_form['#parents'],
],
'#weight' => 50,
'#limit_validation_errors' => [
$inline_form['#parents'],
],
'#coupon_id' => $coupon
->id(),
'#submit' => [
[
get_called_class(),
'removeCoupon',
],
],
// Simplify ajaxRefresh() by having all triggering elements
// on the same level.
'#parents' => array_merge($inline_form['#parents'], [
'remove_coupon_' . $index,
]),
];
}
return $inline_form;
}
/**
* {@inheritdoc}
*/
public function validateInlineForm(array &$inline_form, FormStateInterface $form_state) {
parent::validateInlineForm($inline_form, $form_state);
// Runs if the 'Apply coupon' button was clicked, or the main form
// was submitted by the user clicking the primary submit button.
$triggering_element = $form_state
->getTriggeringElement();
$button_type = isset($triggering_element['#button_type']) ? $triggering_element['#button_type'] : NULL;
if ($triggering_element['#name'] != 'apply_coupon' && $button_type != 'primary') {
return;
}
$coupon_code_parents = array_merge($inline_form['#parents'], [
'code',
]);
$coupon_code = $form_state
->getValue($coupon_code_parents);
$coupon_code_path = implode('][', $coupon_code_parents);
if (empty($coupon_code)) {
if ($triggering_element['#name'] == 'apply_coupon') {
$form_state
->setErrorByName($coupon_code_path, t('Please provide a coupon code.'));
}
return;
}
/** @var \Drupal\commerce_promotion\CouponStorageInterface $coupon_storage */
$coupon_storage = $this->entityTypeManager
->getStorage('commerce_promotion_coupon');
$coupon = $coupon_storage
->loadEnabledByCode($coupon_code);
if (empty($coupon)) {
$form_state
->setErrorByName($coupon_code_path, t('The provided coupon code is invalid.'));
return;
}
$order_storage = $this->entityTypeManager
->getStorage('commerce_order');
/** @var \Drupal\commerce_order\Entity\OrderInterface $order */
$order = $order_storage
->load($this->configuration['order_id']);
foreach ($order
->get('coupons') as $item) {
if ($item->target_id == $coupon
->id()) {
// Coupon already applied. Error message not set for UX reasons.
return;
}
}
if (!$coupon
->available($order)) {
$form_state
->setErrorByName($coupon_code_path, t('The provided coupon code is not available. It may have expired or already been used.'));
return;
}
if (!$coupon
->getPromotion()
->applies($order)) {
$form_state
->setErrorByName($coupon_code_path, t('The provided coupon code cannot be applied to your order.'));
return;
}
// Save the coupon ID for applyCoupon.
$inline_form['code']['#coupon_id'] = $coupon
->id();
}
/**
* Submit callback for the "Apply coupon" button.
*/
public static function applyCoupon(array $form, FormStateInterface $form_state) {
$triggering_element = $form_state
->getTriggeringElement();
$parents = array_slice($triggering_element['#parents'], 0, -1);
$inline_form = NestedArray::getValue($form, $parents);
// Clear the coupon code input.
$user_input =& $form_state
->getUserInput();
NestedArray::setValue($user_input, array_merge($parents, [
'code',
]), '');
if (isset($inline_form['code']['#coupon_id'])) {
$order_storage = \Drupal::entityTypeManager()
->getStorage('commerce_order');
/** @var \Drupal\commerce_order\Entity\OrderInterface $order */
$order = $order_storage
->load($inline_form['#configuration']['order_id']);
$order
->get('coupons')
->appendItem($inline_form['code']['#coupon_id']);
$order
->save();
}
$form_state
->setRebuild();
}
/**
* Submit callback for the "Remove coupon" button.
*/
public static function removeCoupon(array $form, FormStateInterface $form_state) {
$triggering_element = $form_state
->getTriggeringElement();
$parents = array_slice($triggering_element['#parents'], 0, -1);
$inline_form = NestedArray::getValue($form, $parents);
$order_storage = \Drupal::entityTypeManager()
->getStorage('commerce_order');
/** @var \Drupal\commerce_order\Entity\OrderInterface $order */
$order = $order_storage
->load($inline_form['#configuration']['order_id']);
$coupon_ids = array_column($order
->get('coupons')
->getValue(), 'target_id');
$coupon_index = array_search($triggering_element['#coupon_id'], $coupon_ids);
$order
->get('coupons')
->removeItem($coupon_index);
$order
->save();
$form_state
->setRebuild();
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
AjaxFormTrait:: |
public static | function | Ajax handler for refreshing an entire form. | |
CouponRedemption:: |
protected | property | The entity type manager. | |
CouponRedemption:: |
public static | function | Submit callback for the "Apply coupon" button. | |
CouponRedemption:: |
public | function |
Builds the inline form. Overrides InlineFormBase:: |
|
CouponRedemption:: |
public static | function |
Creates an instance of the plugin. Overrides InlineFormBase:: |
|
CouponRedemption:: |
public | function |
Gets default configuration for this plugin. Overrides InlineFormBase:: |
|
CouponRedemption:: |
public static | function | Submit callback for the "Remove coupon" button. | |
CouponRedemption:: |
protected | function |
Gets the required configuration for this plugin. Overrides InlineFormBase:: |
|
CouponRedemption:: |
public | function |
Validates the inline form. Overrides InlineFormBase:: |
|
CouponRedemption:: |
public | function |
Constructs a new CouponRedemption object. Overrides InlineFormBase:: |
|
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 | |
InlineFormBase:: |
public | function |
Gets this plugin's configuration. Overrides ConfigurableInterface:: |
|
InlineFormBase:: |
public | function |
Gets the inline form label. Overrides InlineFormInterface:: |
|
InlineFormBase:: |
public static | function | Runs the inline form submission. | |
InlineFormBase:: |
public static | function | Runs the inline form validation. | |
InlineFormBase:: |
public | function |
Sets the configuration for this plugin instance. Overrides ConfigurableInterface:: |
|
InlineFormBase:: |
public | function |
Submits the inline form. Overrides InlineFormInterface:: |
4 |
InlineFormBase:: |
public static | function | Updates the page title based on the inline form's #page_title property. | |
InlineFormBase:: |
protected | function | Validates configuration. | 1 |
MessengerTrait:: |
protected | property | The messenger. | 29 |
MessengerTrait:: |
public | function | Gets the messenger. | 29 |
MessengerTrait:: |
public | function | Sets the messenger. | |
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. | |
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. |