diff --git a/commerce_webform_order.module b/commerce_webform_order.module
index 7632495..4e0c87d 100644
--- a/commerce_webform_order.module
+++ b/commerce_webform_order.module
@@ -5,6 +5,10 @@
* Code for the Commerce Webform Order module.
*/
+use Drupal\Core\Entity\EntityTypeInterface;
+use Drupal\Core\Field\BaseFieldDefinition;
+use Drupal\Core\Field\FieldStorageDefinitionInterface;
+
/**
* Implements hook_theme().
*/
@@ -15,3 +19,58 @@ function commerce_webform_order_theme() {
],
];
}
+
+/**
+ * Implements hook_entity_base_field_info().
+ */
+function commerce_webform_order_entity_base_field_info(EntityTypeInterface $entity_type) {
+ $fields = [];
+
+ // Add our base fields, to add relation between webform submissions, orders
+ // and order items.
+ if ($entity_type->id() == 'commerce_order_item') {
+ $fields['commerce_webform_order_submissions'] = BaseFieldDefinition::create('entity_reference')
+ ->setLabel(t('Webform submission'))
+ ->setDescription(t('The webform submission which has created by this order item.'))
+ ->setCardinality(1)
+ ->setRequired(FALSE)
+ ->setSetting('target_type', 'webform_submission')
+ ->setSetting('handler', 'default')
+ ->setTranslatable(FALSE)
+ ->setDisplayConfigurable('form', FALSE)
+ ->setDisplayOptions('form', [
+ 'region' => 'hidden',
+ 'weight' => 0,
+ ])
+ ->setDisplayConfigurable('view', TRUE)
+ ->setDisplayOptions('view', [
+ 'region' => 'hidden',
+ 'weight' => 0,
+ ]);
+
+ return $fields;
+ }
+ elseif ($entity_type->id() == 'webform_submission') {
+ $fields['commerce_webform_order_orders'] = BaseFieldDefinition::create('entity_reference')
+ ->setLabel(t('Commerce orders'))
+ ->setDescription(t('The commerce orders which have been created by this webform submission.'))
+ // One order could be created by multiple submissions.
+ ->setCardinality(FieldStorageDefinitionInterface::CARDINALITY_UNLIMITED)
+ ->setRequired(FALSE)
+ ->setSetting('target_type', 'commerce_order')
+ ->setSetting('handler', 'default')
+ ->setTranslatable(FALSE)
+ ->setDisplayConfigurable('form', FALSE)
+ ->setDisplayOptions('form', [
+ 'region' => 'hidden',
+ 'weight' => 0,
+ ])
+ ->setDisplayConfigurable('view', TRUE)
+ ->setDisplayOptions('view', [
+ 'region' => 'hidden',
+ 'weight' => 0,
+ ]);
+
+ return $fields;
+ }
+}
diff --git a/src/Plugin/Field/FieldFormatter/OrderIdLinkFormatter.php b/src/Plugin/Field/FieldFormatter/OrderIdLinkFormatter.php
new file mode 100644
index 0000000..4dbc9e8
--- /dev/null
+++ b/src/Plugin/Field/FieldFormatter/OrderIdLinkFormatter.php
@@ -0,0 +1,78 @@
+getEntitiesToView($items, $langcode) as $delta => $entity) {
+ $id = $entity->id();
+ // If the order has a uri, display a link.
+ if ($output_as_link && !$entity->isNew()) {
+ try {
+ $uri = $entity->toUrl();
+ }
+ catch (UndefinedLinkTemplateException $e) {
+ // This exception is thrown by \Drupal\Core\Entity\Entity::toUrl()
+ // and it means that the entity type doesn't have a link template nor
+ // a valid "uri_callback", so don't bother trying to output a link for
+ // the rest of the referenced entities.
+ $output_as_link = FALSE;
+ }
+ }
+
+ if ($output_as_link && isset($uri) && !$entity->isNew()) {
+ $elements[$delta] = [
+ '#type' => 'link',
+ '#title' => $id,
+ '#url' => $uri,
+ '#options' => $uri->getOptions(),
+ ];
+
+ if (!empty($items[$delta]->_attributes)) {
+ $elements[$delta]['#options'] += ['attributes' => []];
+ $elements[$delta]['#options']['attributes'] += $items[$delta]->_attributes;
+ // Unset field item attributes since they have been included in the
+ // formatter output and shouldn't be rendered in the field template.
+ unset($items[$delta]->_attributes);
+ }
+ }
+ else {
+ $elements[$delta] = ['#plain_text' => $id];
+ }
+ $elements[$delta]['#cache']['tags'] = $entity->getCacheTags();
+ }
+
+ return $elements;
+ }
+
+ /**
+ * {@inheritdoc}
+ */
+ protected function checkAccess(EntityInterface $entity) {
+ return $entity->access('view label', NULL, TRUE);
+ }
+
+}
diff --git a/src/Plugin/WebformHandler/CommerceWebformOrderHandler.php b/src/Plugin/WebformHandler/CommerceWebformOrderHandler.php
index 8b57643..b648735 100644
--- a/src/Plugin/WebformHandler/CommerceWebformOrderHandler.php
+++ b/src/Plugin/WebformHandler/CommerceWebformOrderHandler.php
@@ -259,6 +259,7 @@ class CommerceWebformOrderHandler extends WebformHandlerBase {
'hide_add_to_cart_message' => FALSE,
'redirect' => TRUE,
],
+ 'states' => [WebformSubmissionInterface::STATE_COMPLETED],
'debug' => FALSE,
];
}
@@ -529,6 +530,31 @@ class CommerceWebformOrderHandler extends WebformHandlerBase {
'#default_value' => $this->configuration['checkout']['redirect'],
];
+ // Additional.
+ $results_disabled = $this->getWebform()->getSetting('results_disabled');
+ $form['additional'] = [
+ '#type' => 'fieldset',
+ '#title' => $this->t('Additional settings'),
+ ];
+ // Settings: States.
+ $form['additional']['states'] = [
+ '#type' => 'checkboxes',
+ '#title' => $this->t('Create order'),
+ '#options' => [
+ WebformSubmissionInterface::STATE_DRAFT => $this->t('…when draft is saved.'),
+ WebformSubmissionInterface::STATE_CONVERTED => $this->t('…when anonymous submission is converted to authenticated.'),
+ WebformSubmissionInterface::STATE_COMPLETED => $this->t('…when submission is completed.'),
+ WebformSubmissionInterface::STATE_UPDATED => $this->t('…when submission is updated.'),
+ WebformSubmissionInterface::STATE_DELETED => $this->t('…when submission is deleted.'),
+ ],
+ '#parents' => [
+ 'settings',
+ 'states',
+ ],
+ '#access' => $results_disabled ? FALSE : TRUE,
+ '#default_value' => $results_disabled ? [WebformSubmissionInterface::STATE_COMPLETED] : $this->configuration['states'],
+ ];
+
// Settings: Debug.
$form['development'] = [
'#type' => 'details',
@@ -567,6 +593,9 @@ class CommerceWebformOrderHandler extends WebformHandlerBase {
$values = $form_state->getValues();
+ // Cleanup states.
+ $values['states'] = array_values(array_filter($values['states']));
+
foreach ($this->configuration as $name => $value) {
if (isset($values[$name])) {
$this->configuration[$name] = $values[$name];
@@ -577,117 +606,125 @@ class CommerceWebformOrderHandler extends WebformHandlerBase {
/**
* {@inheritdoc}
*/
- public function submitForm(array &$form, FormStateInterface $form_state, WebformSubmissionInterface $webform_submission) {
- try {
- // Collect data from the handler and the webform submission.
- $data = $this->prepareData($webform_submission);
-
- /** @var \Drupal\commerce_order\OrderStorage $order_item_storage */
- $order_item_storage = $this->entityTypeManager->getStorage('commerce_order_item');
-
- // Create the order item.
- /** @var \Drupal\commerce_order\Entity\OrderItemInterface $order_item */
- $order_item = $order_item_storage->create([
- 'type' => $data['order_item_bundle'],
- 'title' => $data['title'],
- 'unit_price' => $data['price'],
- 'overridden_unit_price' => TRUE,
- 'quantity' => (string) $data['quantity'],
- 'purchased_entity' => $data['product_variation'],
- ]);
-
- // Add non BaseFieldDefinition field values.
- foreach ($data['order_item_fields'] as $field => $value) {
- $order_item->set($field, $value);
- }
-
- // Create or update the cart.
- $order_type_id = $this->orderTypeResolver->resolve($order_item);
- $this->cart = $this->cartProvider->getCart($order_type_id, $data['store']);
- if (!$this->cart) {
- $this->cart = $this->cartProvider->createCart($order_type_id, $data['store']);
- }
- elseif ($this->configuration['checkout']['empty_cart']) {
- $this->cartManager->emptyCart($this->cart);
- }
-
- // Set the owner and the email if the user is not an anonymous user.
- if ($this->currentUser->isAuthenticated()) {
- $this->cart->setCustomerId($this->currentUser->id());
- $this->cart->setEmail($this->currentUser->getEmail());
- }
- // Set the email.
- elseif (!empty($data['owner_email'])) {
- $this->cart->setEmail($data['owner_email']);
- }
-
- // Add the order item.
- $this->cartManager->addOrderItem($this->cart, $order_item);
+ public function postSave(WebformSubmissionInterface $webform_submission, $update = TRUE) {
+ $state = $webform_submission->getWebform()->getSetting('results_disabled') ? WebformSubmissionInterface::STATE_COMPLETED : $webform_submission->getState();
+ if ($this->configuration['states'] && in_array($state, $this->configuration['states'])) {
+ try {
+ // Collect data from the handler and the webform submission.
+ $data = $this->prepareData($webform_submission);
+
+ /** @var \Drupal\commerce_order\OrderStorage $order_item_storage */
+ $order_item_storage = $this->entityTypeManager->getStorage('commerce_order_item');
+
+ // Create the order item.
+ /** @var \Drupal\commerce_order\Entity\OrderItemInterface $order_item */
+ $order_item = $order_item_storage->create([
+ 'type' => $data['order_item_bundle'],
+ 'title' => $data['title'],
+ 'unit_price' => $data['price'],
+ 'overridden_unit_price' => TRUE,
+ 'quantity' => (string) $data['quantity'],
+ 'purchased_entity' => $data['product_variation'],
+ 'commerce_webform_order_submissions' => $webform_submission->id(),
+ ]);
+
+ // Add non BaseFieldDefinition field values.
+ foreach ($data['order_item_fields'] as $field => $value) {
+ $order_item->set($field, $value);
+ }
- $this->cart->save();
+ // Create or update the cart.
+ $order_type_id = $this->orderTypeResolver->resolve($order_item);
+ $this->cart = $this->cartProvider->getCart($order_type_id, $data['store']);
+ if (!$this->cart) {
+ $this->cart = $this->cartProvider->createCart($order_type_id, $data['store']);
+ }
+ elseif ($this->configuration['checkout']['empty_cart']) {
+ $this->cartManager->emptyCart($this->cart);
+ }
- // Remove the add to cart status message.
- if ($this->configuration['checkout']['hide_add_to_cart_message']) {
- $messages = $this->messenger()->messagesByType('status');
- $this->messenger()->deleteByType('status');
- /** @var \Drupal\Core\Render\Markup $original_message */
- foreach ($messages as $original_message) {
- if ($original_message instanceof Markup) {
- $message = $original_message->__toString();
- }
- else {
- $message = $original_message;
- }
+ // Set the owner and the email if the user is not an anonymous user.
+ if ($this->currentUser->isAuthenticated()) {
+ $this->cart->setCustomerId($this->currentUser->id());
+ $this->cart->setEmail($this->currentUser->getEmail());
+ }
+ // Set the email.
+ elseif (!empty($data['owner_email'])) {
+ $this->cart->setEmail($data['owner_email']);
+ }
- /* @see \Drupal\commerce_cart\EventSubscriber\CartEventSubscriber::displayAddToCartMessage */
- if (!is_string($message) || preg_match('/.* added to your cart<\/a>\./', $message) === FALSE) {
- $this->messenger()->addMessage($message, 'status');
+ // Add the order item to the order, and save the order.
+ $this->cartManager->addOrderItem($this->cart, $order_item);
+ $this->cart->save();
+
+ // Add the reference to the order and save the submission without
+ // triggering any hooks or handlers.
+ $webform_submission->set('commerce_webform_order_orders', [$this->cart]);
+ $webform_submission->resave();
+
+ // Remove the add to cart status message.
+ if ($this->configuration['checkout']['hide_add_to_cart_message']) {
+ $messages = $this->messenger()->messagesByType('status');
+ $this->messenger()->deleteByType('status');
+ /** @var \Drupal\Core\Render\Markup $original_message */
+ foreach ($messages as $original_message) {
+ if ($original_message instanceof Markup) {
+ $message = $original_message->__toString();
+ }
+ else {
+ $message = $original_message;
+ }
+
+ /* @see \Drupal\commerce_cart\EventSubscriber\CartEventSubscriber::displayAddToCartMessage */
+ if (!is_string($message) || preg_match('/.* added to your cart<\/a>\./', $message) === FALSE) {
+ $this->messenger()->addMessage($message, 'status');
+ }
}
}
- }
-
- // Log message in Drupal's log.
- $context = [
- '@form' => $this->getWebform()->label(),
- '@title' => $this->label(),
- 'link' => $this->getWebform()->toLink($this->t('Edit'), 'handlers')->toString(),
- ];
- $this->getLogger()->notice('@form webform created @title order.', $context);
-
- // Log message in Webform's submission log.
- $context = [
- '@order_id' => $this->cart->get('order_id')->getString(),
- '@owner_email' => $this->cart->getEmail(),
- 'webform_submission' => $webform_submission,
- 'handler_id' => $this->getHandlerId(),
- 'data' => [],
- ];
- if ($this->cart->getEmail() !== NULL) {
- $this->getLogger('webform_submission')->notice("Order #@order_id created to '@owner_email'.", $context);
- }
- else {
- $this->getLogger('webform_submission')->notice("Order #@order_id created.", $context);
- }
- // Debug by displaying create order onscreen.
- if ($this->configuration['debug']) {
- $t_args = [
- '%order_id' => $this->cart->get('order_id')->getString(),
- '%owner_email' => $this->cart->getEmail(),
+ // Log message in Drupal's log.
+ $context = [
+ '@form' => $this->getWebform()->label(),
+ '@title' => $this->label(),
+ 'link' => $this->getWebform()->toLink($this->t('Edit'), 'handlers')->toString(),
+ ];
+ $this->getLogger()->notice('@form webform created @title order.', $context);
+
+ // Log message in Webform's submission log.
+ $context = [
+ '@order_id' => $this->cart->get('order_id')->getString(),
+ '@owner_email' => $this->cart->getEmail(),
+ 'webform_submission' => $webform_submission,
+ 'handler_id' => $this->getHandlerId(),
+ 'data' => [],
];
if ($this->cart->getEmail() !== NULL) {
- $this->messenger()->addWarning($this->t("Order #%order_id created to '%owner_email'.", $t_args), TRUE);
+ $this->getLogger('webform_submission')->notice("Order #@order_id created to '@owner_email'.", $context);
}
else {
- $this->messenger()->addWarning($this->t("Order #%order_id created.", $t_args), TRUE);
+ $this->getLogger('webform_submission')->notice("Order #@order_id created.", $context);
+ }
+
+ // Debug by displaying create order onscreen.
+ if ($this->configuration['debug']) {
+ $t_args = [
+ '%order_id' => $this->cart->get('order_id')->getString(),
+ '%owner_email' => $this->cart->getEmail(),
+ ];
+ if ($this->cart->getEmail() !== NULL) {
+ $this->messenger()->addWarning($this->t("Order #%order_id created to '%owner_email'.", $t_args), TRUE);
+ }
+ else {
+ $this->messenger()->addWarning($this->t("Order #%order_id created.", $t_args), TRUE);
+ }
+ $debug_message = $this->buildDebugMessage($this->cart);
+ $this->messenger()->addWarning($this->renderer->renderPlain($debug_message), TRUE);
}
- $debug_message = $this->buildDebugMessage($this->cart);
- $this->messenger()->addWarning($this->renderer->renderPlain($debug_message), TRUE);
}
- }
- catch (\Exception $exception) {
- watchdog_exception('commerce_webform_order', $exception);
- $this->messenger()->addWarning($this->t('There was a problem processing your request. Please, try again.'), TRUE);
+ catch (\Exception $exception) {
+ watchdog_exception('commerce_webform_order', $exception);
+ $this->messenger()->addWarning($this->t('There was a problem processing your request. Please, try again.'), TRUE);
+ }
}
}
diff --git a/templates/webform-handler-commerce-webform-order-summary.html.twig b/templates/webform-handler-commerce-webform-order-summary.html.twig
index 2c3221e..f3bea44 100644
--- a/templates/webform-handler-commerce-webform-order-summary.html.twig
+++ b/templates/webform-handler-commerce-webform-order-summary.html.twig
@@ -11,6 +11,7 @@
*/
#}
{% if settings.debug %}{{ 'Debugging is enabled'|t }}
{% endif %}
+{% if settings.states %}{{ 'The order will be created when the submission is: '|t }} {{ settings.states|join('; ') }}.
{% endif %}
{% if settings.checkout.empty_cart %}{{ 'The cart will be emptied.'|t }}
{% endif %}
{% if settings.checkout.hide_add_to_cart_message %}{{ 'The add to cart message will be removed.'|t }}
{% endif %}
{% if settings.checkout.rediect %}{{ 'User will be redirected to the checkout.'|t }}{% endif %}