diff --git a/commerce_stock_notifications.module b/commerce_stock_notifications.module index 926c6c1..99b44cf 100644 --- a/commerce_stock_notifications.module +++ b/commerce_stock_notifications.module @@ -7,7 +7,6 @@ use Drupal\commerce_product\Entity\ProductVariationInterface; use Drupal\commerce_stock_notifications\Form\AdminConfigForm; -use Drupal\commerce_stock_notifications\Form\NotificationForm; /** * Implements hook_form_alter(). @@ -28,8 +27,15 @@ function commerce_stock_notifications_form_alter(&$form, &$form_state, $form_id) $selected_variation = $product->getDefaultVariation(); } // Check if in stock. - if (commerce_stock_notifications_check_stock($selected_variation)) { - $form['commerce_stock_notifications'] = \Drupal::service('form_builder')->getForm(NotificationForm::class, $selected_variation); + if (!commerce_stock_notifications_check_stock($selected_variation)) { + $inline_form_manager = \Drupal::getContainer()->get('plugin.manager.commerce_inline_form'); + $inline_form = $inline_form_manager->createInstance('commerce_stock_notifications', [ + 'variation_id' => $selected_variation->id(), + ]); + $form['commerce_stock_notifications'] = [ + '#parents' => ['commerce_stock_notifications'], + ]; + $form['commerce_stock_notifications'] = $inline_form->buildInlineForm($form['commerce_stock_notifications'], $form_state); $form['actions']['submit']['#value'] = t('Out of stock'); $form['actions']['submit']['#disabled'] = TRUE; } diff --git a/src/Form/NotificationForm.php b/src/Form/NotificationForm.php deleted file mode 100644 index d09bb13..0000000 --- a/src/Form/NotificationForm.php +++ /dev/null @@ -1,129 +0,0 @@ -messenger = $container->get('messenger'); - $form->configFactory = $container->get('config.factory'); - $form->emailValidator = $container->get('email.validator'); - $form->entityTypeManager = $container->get('entity_type.manager'); - - return $form; - } - - /** - * {@inheritdoc} - */ - public function getFormId() { - return 'commerce_stock_notifications_notification_form'; - } - - /** - * {@inheritdoc} - */ - public function buildForm(array $form, FormStateInterface $form_state, $selectedVariation = NULL) { - $this->selectedVariation = $selectedVariation; - $config = $this->configFactory->get('commerce_stock_notifications.config')->getRawData(); - - return [ - 'commerce_stock_notifications' => [ - '#type' => 'fieldset', - '#title' => $config['oos_message'] ?? $this->t('Please notify me when this product is back in stock.'), - 'notify_email' => [ - '#type' => 'textfield', - '#title' => $this->t('E-Mail'), - '#required' => TRUE, - '#default_value' => $this->currentUser()->getEmail(), - ], - 'notify_submit' => [ - '#type' => 'submit', - '#value' => $this->t('Notify me'), - ], - ], - ]; - } - - /** - * {@inheritdoc} - */ - public function validateForm(array &$form, FormStateInterface $form_state) { - parent::validateForm($form, $form_state); - // Check if user is logged in. - if ($this->currentUser()->isAnonymous()) { - $form_state->setError($form, $this->t('You must be authenticated to do that.')); - } - // Check if e-mail is valid. - $email = $form_state->getValue('notify_email'); - if (!$this->emailValidator->isValid($email)) { - $form_state->setErrorByName('notify_email', $this->t('Invalid e-mail')); - } - // Check if already subscribed. - $notificationCount = $this->entityTypeManager - ->getStorage('commerce_stock_notification') - ->getQuery() - ->condition('email', $email) - ->condition('product_id', $this->selectedVariation->id()) - ->condition('sent_time', NULL, 'IS') - ->count(); - - if ($notificationCount->execute() > 0) { - $duplicateMessage = AdminConfigForm::getValuesFromConfig()['duplicate_message']; - $form_state->setErrorByName('notify_email', $duplicateMessage); - } - } - - /** - * {@inheritdoc} - */ - public function submitForm(array &$form, FormStateInterface $form_state) { - $this->entityTypeManager - ->getStorage('commerce_stock_notification') - ->create([ - 'user_id' => $this->currentUser()->id(), - 'product_id' => $this->selectedVariation->id(), - 'submit_time' => (new DrupalDateTime())->getTimestamp(), - 'email' => $form_state->getValue('notify_email'), - ]) - ->save(); - - $this->messenger->addStatus(AdminConfigForm::getValuesFromConfig()['success_message']); - } - -} diff --git a/src/Plugin/Commerce/InlineForm/Notification.php b/src/Plugin/Commerce/InlineForm/Notification.php new file mode 100644 index 0000000..45471f4 --- /dev/null +++ b/src/Plugin/Commerce/InlineForm/Notification.php @@ -0,0 +1,224 @@ +config = $config_factory->get('commerce_stock_notifications.config'); + $this->currentUser = $current_user; + $this->emailValidator = $email_validator; + $this->entityTypeManager = $entity_type_manager; + $this->time = $time; + } + + /** + * {@inheritdoc} + */ + public static function create(ContainerInterface $container, array $configuration, $plugin_id, $plugin_definition) { + return new static( + $configuration, + $plugin_id, + $plugin_definition, + $container->get('config.factory'), + $container->get('current_user'), + $container->get('email.validator'), + $container->get('entity_type.manager'), + $container->get('datetime.time') + ); + } + + /** + * {@inheritdoc} + */ + public function defaultConfiguration() { + return [ + // The variation_id is passed via configuration to avoid serializing the + // variation. + 'variation_id' => '', + ]; + } + + /** + * {@inheritdoc} + */ + protected function requiredConfiguration() { + return ['variation_id']; + } + + /** + * {@inheritdoc} + */ + public function buildInlineForm(array $inline_form, FormStateInterface $form_state) { + $inline_form = parent::buildInlineForm($inline_form, $form_state); + + /** @var \Drupal\commerce_product\Entity\ProductVariationInterface|null $variation */ + $variation = $this->entityTypeManager->getStorage('commerce_product_variation')->load($this->configuration['variation_id']); + if (!$variation) { + throw new \RuntimeException('Invalid variation_id given to the commerce_stock_notifications inline form.'); + } + + $inline_form['notification'] = [ + '#type' => 'fieldset', + '#title' => $this->config->get('oos_message') ?? $this->t('Please notify me when this product is back in stock.'), + 'notify_email' => [ + '#type' => 'textfield', + '#title' => $this->t('E-Mail'), + '#required' => TRUE, + '#default_value' => $this->currentUser->getEmail(), + ], + 'notify_submit' => [ + '#type' => 'submit', + '#value' => $this->t('Notify me'), + '#limit_validation_errors' => [ + $inline_form['#parents'], + ], + '#submit' => [ + [get_called_class(), 'preventParentSubmit'], + ], + ], + ]; + + return $inline_form; + } + + /** + * {@inheritdoc} + */ + public function validateInlineForm(array &$inline_form, FormStateInterface $form_state) { + parent::validateInlineForm($inline_form, $form_state); + + $notify_email_parents = array_merge($inline_form['#parents'], ['notification', 'notify_email']); + $notify_email = $form_state->getValue($notify_email_parents); + $notify_email_path = implode('][', $notify_email_parents); + $variation_id = $this->configuration['variation_id']; + + // Check if user is logged in. + if ($this->currentUser->isAnonymous()) { + $form_state->setErrorByName($notify_email_path, $this->t('You must be authenticated to do that. Please register or log in!', ['@register_url' => '/user/register','@login_url' => '/user/login'])); + } + + // Check if e-mail is valid. + if (!$this->emailValidator->isValid($notify_email)) { + $form_state->setErrorByName($notify_email_path, $this->t('Invalid e-mail')); + } + + // Check if already subscribed. + $notification_count_query = $this->entityTypeManager + ->getStorage('commerce_stock_notification') + ->getQuery() + ->condition('email', $notify_email) + ->condition('product_id', $variation_id) + ->condition('sent_time', NULL, 'IS') + ->count(); + + if ($notification_count_query->execute() > 0) { + $duplicate_message = AdminConfigForm::getValuesFromConfig()['duplicate_message']; + $form_state->setErrorByName($notify_email_path, $duplicate_message); + } + } + + /** + * {@inheritdoc} + */ + public function submitInlineForm(array &$inline_form, FormStateInterface $form_state) { + parent::submitInlineForm($inline_form, $form_state); + + $notify_email_parents = array_merge($inline_form['#parents'], ['notification', 'notify_email']); + $variation_id = $this->configuration['variation_id']; + + $this->entityTypeManager + ->getStorage('commerce_stock_notification') + ->create([ + 'user_id' => $this->currentUser->id(), + 'product_id' => $variation_id, + 'submit_time' => $this->time->getRequestTime(), + 'email' => $form_state->getValue($notify_email_parents), + ]) + ->save(); + + $this->messenger()->addStatus(AdminConfigForm::getValuesFromConfig()['success_message']); + } + + /** + * Empty submit callback to prevent add to cart submit handler to be called. + */ + public static function preventParentSubmit(array $form, FormStateInterface $form_state) { + } + +}