Allow visitors to be notified of a new product variation with Drupal commerce 2

Block note

For e-commerce sites offering training or events, an extremely interesting function is to offer visitors to subscribe to the training or event in question in order to be notified as soon as a new session, a new date, is available. The interest is twofold: this allows the user to receive real-time notification as soon as a new session is available, and for the e-commerce site it allows him to know the interest generated by his various events or training courses, and can encourage him to strengthen certain products rather than others, in other words to respond to a request that is expressed.

This is the main objective of the Commerce Product Reminder module, which we will discover here.

The configuration of the module is quite simple. Its main concept is to provide a subscription form, allowing the user to subscribe with an email, on Drupal Commerce's Product entities, and then to notify all subscribers as soon as a new variation of the product in question is published (or if an existing unpublished variation is published again).

Module configuration

The module offers us several general configuration options

Commerce Product Reminder general settings

So we can:

  • Disable the sending of notification emails if necessary
  • Use background tasks to send notification mails (recommended option)
  • Log the sending of each notification
  • And finally, select the different product types of Drupal Commerce on which to activate the subscription form.

The module configuration options also allow you to customize the various text elements of the subscription form as well as those of the notification emails sent.

Commerce Product Reminder form settings

The various configurable text elements of the subscription form are

  • An introductory text for the subscription form
  • The label of the form submission button
  • The subscription confirmation message
  • And finally an introductory text on the page allowing anonymous visitors to manage their different subscriptions (The link to this page is automatically available on all notification emails sent to subscribers)

Commerce Product Reminder mail settings

The configurable text elements for notification mails are :

  • The sender email (leave blank to use by default the main email of the site)
  • The body of the mail (tokens associated with the Product and Product Variation entities are available)
  • The subject of the email

Once these different elements have been configured, all that remains is to activate the subscription form on the different product types, on the relevant view mode (generally the Full view mode).

Commerce Product Reminder Extra field

And now all anonymous visitors can subscribe to receive a notification as soon as a new variation is published related to the product in question.

Commerce Product Reminder subscription form

Extension du périmètre fonctionnel du module

The functional scope of the module consists above all in notifying users of a new variation published on a Drupal Commerce product. And its main contribution consists in providing the storage of subscribers, giving them access to a page allowing them to manage their subscriptions while being an anonymous visitor, and then to manage the sending of notification emails.

The logic that determines the sending of notification mails ultimately represents a very small part of the module and can be easily modified by a Drupal 8 developer, as for example if you want to generate the sending of notifications on any other property or fields of a product variation.

It is enough to implement an EventSubscriber that will react on events related to a product variation, events propagated by Drupal Commerce itself, or to overload the EventSubscriber used by the module itself.

/**
 * Class ProductVariationSubscriber.
 */
class ProductVariationSubscriber implements EventSubscriberInterface {

  /**
   * Drupal\commerce_product_reminder\HelperServiceInterface definition.
   *
   * @var \Drupal\commerce_product_reminder\HelperServiceInterface
   */
  protected $helper;

  /**
   * Queue factory.
   *
   * @var \Drupal\Core\Queue\QueueFactory
   */
  protected $queueFactory;

  /**
   * ProductVariationSubscriber constructor.
   *
   * @param \Drupal\commerce_product_reminder\HelperServiceInterface $helper
   * @param \Drupal\Core\Queue\QueueFactory $queue_factory
   */
  public function __construct(HelperServiceInterface $helper, QueueFactory $queue_factory) {
    $this->helper = $helper;
    $this->queueFactory = $queue_factory;
  }

  /**
   * {@inheritdoc}
   */
  public static function getSubscribedEvents() {
    $events[ProductEvents::PRODUCT_VARIATION_INSERT] = ['onProductVariationInsert'];
    $events[ProductEvents::PRODUCT_VARIATION_UPDATE] = ['onProductVariationUpdate'];
    return $events;
  }

  /**
   * This method is called when the product_variation_insert event is dispatched.
   *
   * @param \Drupal\commerce_product\Event\ProductVariationEvent $event
   *   The dispatched event.
   */
  public function onProductVariationInsert(ProductVariationEvent $event) {
    $product_variation = $event->getProductVariation();
    if ($product_variation->isPublished()) {
      $this->sendMailForReminderRelated($product_variation);
    }
  }

  /**
   * This method is called when the product_variation_update event is dispatched.
   *
   * @param \Drupal\commerce_product\Event\ProductVariationEvent $event
   *   The dispatched event.
   */
  public function onProductVariationUpdate(ProductVariationEvent $event) {
    $product_variation = $event->getProductVariation();
    $product_variation_original = $product_variation->original;
    if (!$product_variation_original instanceof ProductVariationInterface) {
      return;
    }
    if ($product_variation->isPublished() && !$product_variation_original->isPublished()) {
      $this->sendMailForReminderRelated($product_variation);
    }
  }

  /**
   * Send reminder mails or queue them.
   *
   * @param \Drupal\commerce_product\Entity\ProductVariationInterface $product_variation
   */
  protected function sendMailForReminderRelated(ProductVariationInterface $product_variation) {
    if (!$this->helper->isEnabled()) {
      return;
    }
    $data = [];
    $data['product_variation_id'] = $product_variation->id();
    $reminders = $this->helper->getRemindersFromVariation($product_variation);
    foreach ($reminders as $reminder) {
      $data['reminder_id'] = $reminder->id();
      if ($this->helper->useCron()) {
        $this->queueFactory->get('commerce_product_reminder_worker')->createItem($data);
      }
      else {
        $this->helper->sendMail($product_variation, $reminder);
      }
    }
  }
}

And then you can modify the methods that are in charge of acting on product variation update or create events, and thus introduce your own business logic. The module will take care of all subscription management and sending notification emails according to your own needs.

A very likely evolution of the module will certainly be to allow an easier modification of the logic triggering notifications, whether via a plugin system or additional configuration options, or even to support other contributed modules such as those related to inventory management for example.

 

Ajouter un commentaire