class CouponGenerateForm in Commerce Core 8.2
Provides a form for bulk generating coupons.
Hierarchy
- class \Drupal\Core\Form\FormBase implements ContainerInjectionInterface, FormInterface uses DependencySerializationTrait, LoggerChannelTrait, MessengerTrait, LinkGeneratorTrait, RedirectDestinationTrait, UrlGeneratorTrait, StringTranslationTrait
- class \Drupal\commerce_promotion\Form\CouponGenerateForm
Expanded class hierarchy of CouponGenerateForm
1 string reference to 'CouponGenerateForm'
- commerce_promotion.routing.yml in modules/
promotion/ commerce_promotion.routing.yml - modules/promotion/commerce_promotion.routing.yml
File
- modules/
promotion/ src/ Form/ CouponGenerateForm.php, line 16
Namespace
Drupal\commerce_promotion\FormView source
class CouponGenerateForm extends FormBase {
/**
* The number of coupons to generate in each batch.
*
* @var int
*/
const BATCH_SIZE = 25;
/**
* The maximum code length.
*
* @var int
*/
const MAX_CODE_LENGTH = 255;
/**
* The coupon code generator.
*
* @var \Drupal\commerce_promotion\CouponCodeGeneratorInterface
*/
protected $couponCodeGenerator;
/**
* The promotion.
*
* @var \Drupal\commerce_promotion\Entity\PromotionInterface
*/
protected $promotion;
/**
* Constructs a new CouponGenerateForm object.
*
* @param \Drupal\commerce_promotion\CouponCodeGeneratorInterface $coupon_code_generator
* The coupon code generator.
* @param \Drupal\Core\Routing\CurrentRouteMatch $current_route_match
* The current route match.
*/
public function __construct(CouponCodeGeneratorInterface $coupon_code_generator, CurrentRouteMatch $current_route_match) {
$this->couponCodeGenerator = $coupon_code_generator;
$this->promotion = $current_route_match
->getParameter('commerce_promotion');
}
/**
* {@inheritdoc}
*/
public static function create(ContainerInterface $container) {
return new static($container
->get('commerce_promotion.coupon_code_generator'), $container
->get('current_route_match'));
}
/**
* {@inheritdoc}
*/
public function getFormId() {
return 'commerce_coupon_generate_form';
}
/**
* {@inheritdoc}
*/
public function buildForm(array $form, FormStateInterface $form_state) {
$form['quantity'] = [
'#type' => 'number',
'#title' => $this
->t('Number of coupons'),
'#required' => TRUE,
'#default_value' => '10',
'#min' => 1,
'#max' => 1000,
'#step' => 1,
];
$form['pattern'] = [
'#type' => 'fieldset',
'#title' => $this
->t('Coupon code pattern'),
];
$form['pattern']['format'] = [
'#type' => 'select',
'#title' => $this
->t('Format'),
'#required' => TRUE,
'#options' => [
'alphanumeric' => $this
->t('Alphanumeric'),
'alphabetic' => $this
->t('Alphabetic'),
'numeric' => $this
->t('Numeric'),
],
'#default_value' => 'alphanumeric',
];
$form['pattern']['prefix'] = [
'#type' => 'textfield',
'#title' => $this
->t('Prefix'),
'#size' => 20,
];
$form['pattern']['suffix'] = [
'#type' => 'textfield',
'#title' => $this
->t('Suffix'),
'#size' => 20,
];
$form['pattern']['length'] = [
'#type' => 'number',
'#title' => $this
->t('Length'),
'#description' => $this
->t('Length does not include prefix/suffix.'),
'#required' => TRUE,
'#default_value' => 8,
'#min' => 1,
];
$form['limit'] = [
'#type' => 'radios',
'#title' => $this
->t('Number of uses per coupon'),
'#options' => [
0 => $this
->t('Unlimited'),
1 => $this
->t('Limited number of uses'),
],
'#default_value' => 1,
];
$form['usage_limit'] = [
'#type' => 'number',
'#title' => $this
->t('Number of uses'),
'#title_display' => 'invisible',
'#default_value' => 1,
'#min' => 1,
'#states' => [
'invisible' => [
':input[name="limit"]' => [
'value' => 0,
],
],
],
];
$form['limit_customer'] = [
'#type' => 'radios',
'#title' => $this
->t('Number of uses per customer per coupon'),
'#options' => [
0 => $this
->t('Unlimited'),
1 => $this
->t('Limited number of uses'),
],
'#default_value' => 1,
];
$form['usage_limit_customer'] = [
'#type' => 'number',
'#title' => $this
->t('Number of uses per customer'),
'#title_display' => 'invisible',
'#default_value' => 1,
'#min' => 1,
'#states' => [
'invisible' => [
':input[name="limit_customer"]' => [
'value' => 0,
],
],
],
];
$form['actions']['#type'] = 'actions';
$form['actions']['submit'] = [
'#type' => 'submit',
'#value' => $this
->t('Generate'),
'#button_type' => 'primary',
];
return $form;
}
/**
* {@inheritdoc}
*/
public function validateForm(array &$form, FormStateInterface $form_state) {
$values = $form_state
->getValues();
// Make sure that the total length doesn't exceed the database limit.
$code_length = strlen($values['prefix']) + strlen($values['suffix']) + $values['length'];
if ($code_length > self::MAX_CODE_LENGTH) {
$form_state
->setError($form['pattern'], $this
->t('The total pattern length (@coupon_length) exceeds the maximum length allowed (@max_length).', [
'@coupon_length' => $code_length,
'@max_length' => self::MAX_CODE_LENGTH,
]));
}
// Validate that pattern for the given quantity.
$quantity = $values['quantity'];
$pattern = new CouponCodePattern($values['format'], $values['prefix'], $values['suffix'], $values['length']);
if (!$this->couponCodeGenerator
->validatePattern($pattern, $quantity)) {
$form_state
->setError($form['pattern'], $this
->t('This pattern cannot be used to generate @quantity coupons.', [
'@quantity' => $quantity,
]));
}
}
/**
* {@inheritdoc}
*/
public function submitForm(array &$form, FormStateInterface $form_state) {
$values = $form_state
->getValues();
$quantity = $values['quantity'];
$coupon_values = [
'promotion_id' => $this->promotion
->id(),
'usage_limit' => $values['limit'] ? $values['usage_limit'] : 0,
'usage_limit_customer' => $values['usage_limit_customer'],
];
$pattern = new CouponCodePattern($values['format'], $values['prefix'], $values['suffix'], $values['length']);
$batch_builder = (new BatchBuilder())
->setTitle($this
->t('Generating coupons'))
->setProgressMessage('')
->setFinishCallback([
$this,
'finishBatch',
])
->addOperation([
get_class($this),
'processBatch',
], [
$quantity,
$coupon_values,
$pattern,
]);
batch_set($batch_builder
->toArray());
$form_state
->setRedirect('entity.commerce_promotion_coupon.collection', [
'commerce_promotion' => $this->promotion
->id(),
]);
}
/**
* Processes the batch and generates the coupons.
*
* @param int $quantity
* The number of coupons to generate.
* @param string[] $coupon_values
* The initial coupon entity values.
* @param \Drupal\commerce_promotion\CouponCodePattern $pattern
* The pattern.
* @param array $context
* The batch context information.
*/
public static function processBatch($quantity, array $coupon_values, CouponCodePattern $pattern, array &$context) {
if (empty($context['sandbox'])) {
$context['sandbox']['total_quantity'] = (int) $quantity;
$context['sandbox']['created'] = 0;
$context['results']['codes'] = [];
$context['results']['total_quantity'] = $quantity;
}
$total_quantity = $context['sandbox']['total_quantity'];
$created =& $context['sandbox']['created'];
$remaining = $total_quantity - $created;
$coupon_storage = \Drupal::entityTypeManager()
->getStorage('commerce_promotion_coupon');
$limit = $remaining < self::BATCH_SIZE ? $remaining : self::BATCH_SIZE;
$coupon_code_generator = \Drupal::service('commerce_promotion.coupon_code_generator');
$codes = $coupon_code_generator
->generateCodes($pattern, $limit);
if (!empty($codes)) {
foreach ($codes as $code) {
$coupon = $coupon_storage
->create([
'code' => $code,
] + $coupon_values);
$coupon
->save();
$context['results']['codes'][] = $code;
$created++;
}
$context['message'] = t('Creating coupon @created of @total_quantity', [
'@created' => $created,
'@total_quantity' => $total_quantity,
]);
$context['finished'] = $created / $total_quantity;
}
else {
$context['finished'] = 1;
}
}
/**
* Batch finished callback: display batch statistics.
*
* @param bool $success
* Indicates whether the batch has completed successfully.
* @param mixed[] $results
* The array of results gathered by the batch processing.
* @param string[] $operations
* If $success is FALSE, contains the operations that remained unprocessed.
*/
public static function finishBatch($success, array $results, array $operations) {
if ($success) {
$created = count($results['codes']);
// An incomplete set of coupons was generated.
if ($created != $results['total_quantity']) {
\Drupal::messenger()
->addWarning(t('Generated %created out of %total requested coupons. Consider adding a unique prefix/suffix or increasing the pattern length to improve results.', [
'%created' => $created,
'%total' => $results['total_quantity'],
]));
}
else {
\Drupal::messenger()
->addMessage(\Drupal::translation()
->formatPlural($created, 'Generated 1 coupon.', 'Generated @count coupons.'));
}
}
else {
$error_operation = reset($operations);
\Drupal::messenger()
->addError(t('An error occurred while processing @operation with arguments: @args', [
'@operation' => $error_operation[0],
'@args' => print_r($error_operation[0], TRUE),
]));
}
}
}
Members
Name | Modifiers | Type | Description | Overrides |
---|---|---|---|---|
CouponGenerateForm:: |
protected | property | The coupon code generator. | |
CouponGenerateForm:: |
protected | property | The promotion. | |
CouponGenerateForm:: |
constant | The number of coupons to generate in each batch. | ||
CouponGenerateForm:: |
public | function |
Form constructor. Overrides FormInterface:: |
|
CouponGenerateForm:: |
public static | function |
Instantiates a new instance of this class. Overrides FormBase:: |
|
CouponGenerateForm:: |
public static | function | Batch finished callback: display batch statistics. | |
CouponGenerateForm:: |
public | function |
Returns a unique string identifying the form. Overrides FormInterface:: |
|
CouponGenerateForm:: |
constant | The maximum code length. | ||
CouponGenerateForm:: |
public static | function | Processes the batch and generates the coupons. | |
CouponGenerateForm:: |
public | function |
Form submission handler. Overrides FormInterface:: |
|
CouponGenerateForm:: |
public | function |
Form validation handler. Overrides FormBase:: |
|
CouponGenerateForm:: |
public | function | Constructs a new CouponGenerateForm object. | |
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 | |
FormBase:: |
protected | property | The config factory. | 1 |
FormBase:: |
protected | property | The request stack. | 1 |
FormBase:: |
protected | property | The route match. | |
FormBase:: |
protected | function | Retrieves a configuration object. | |
FormBase:: |
protected | function | Gets the config factory for this form. | 1 |
FormBase:: |
private | function | Returns the service container. | |
FormBase:: |
protected | function | Gets the current user. | |
FormBase:: |
protected | function | Gets the request object. | |
FormBase:: |
protected | function | Gets the route match. | |
FormBase:: |
protected | function | Gets the logger for a specific channel. | |
FormBase:: |
protected | function |
Returns a redirect response object for the specified route. Overrides UrlGeneratorTrait:: |
|
FormBase:: |
public | function | Resets the configuration factory. | |
FormBase:: |
public | function | Sets the config factory for this form. | |
FormBase:: |
public | function | Sets the request stack object to use. | |
LinkGeneratorTrait:: |
protected | property | The link generator. | 1 |
LinkGeneratorTrait:: |
protected | function | Returns the link generator. | |
LinkGeneratorTrait:: |
protected | function | Renders a link to a route given a route name and its parameters. | |
LinkGeneratorTrait:: |
public | function | Sets the link generator service. | |
LoggerChannelTrait:: |
protected | property | The logger channel factory service. | |
LoggerChannelTrait:: |
protected | function | Gets the logger for a specific channel. | |
LoggerChannelTrait:: |
public | function | Injects the logger channel factory. | |
MessengerTrait:: |
protected | property | The messenger. | 29 |
MessengerTrait:: |
public | function | Gets the messenger. | 29 |
MessengerTrait:: |
public | function | Sets the messenger. | |
RedirectDestinationTrait:: |
protected | property | The redirect destination service. | 1 |
RedirectDestinationTrait:: |
protected | function | Prepares a 'destination' URL query parameter for use with \Drupal\Core\Url. | |
RedirectDestinationTrait:: |
protected | function | Returns the redirect destination service. | |
RedirectDestinationTrait:: |
public | function | Sets the redirect destination service. | |
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. | |
UrlGeneratorTrait:: |
protected | property | The url generator. | |
UrlGeneratorTrait:: |
protected | function | Returns the URL generator service. | |
UrlGeneratorTrait:: |
public | function | Sets the URL generator service. | |
UrlGeneratorTrait:: |
protected | function | Generates a URL or path for a specific route based on the given parameters. |