Skip to content
Snippets Groups Projects
Commit 471e63f0 authored by Tom Ashe's avatar Tom Ashe Committed by Tom Ashe
Browse files

Issue #3362663 by Morbus Iff, laurentwh, joachim, TomTech: RC1: Can't add more...

Issue #3362663 by Morbus Iff, laurentwh, joachim, TomTech: RC1: Can't add more than one digital product to cart
parent 92743647
No related branches found
No related tags found
No related merge requests found
......@@ -35,7 +35,7 @@ services:
commerce_license.multiple_license_order_processor:
class: Drupal\commerce_license\LicenseOrderProcessorMultiples
arguments: ['@messenger']
arguments: ['@messenger', '@entity_type.manager', '@uuid']
tags:
- { name: commerce_order.order_processor }
......
......@@ -88,6 +88,9 @@ class LicenseMultiplesCartEventSubscriber implements EventSubscriberInterface {
'@product-label' => $order_item->getPurchasedEntity()->label(),
'@cart-url' => Url::fromRoute('commerce_cart.page')->toString(),
]));
// Since we have reverted the quantity, we will stop propagation, so that
// add to cart messages are not logged nor displayed.
$event->stopPropagation();
}
/**
......
......@@ -4,6 +4,8 @@ namespace Drupal\commerce_license;
use Drupal\commerce_order\Entity\OrderInterface;
use Drupal\commerce_order\OrderProcessorInterface;
use Drupal\Component\Uuid\UuidInterface;
use Drupal\Core\Entity\EntityTypeManagerInterface;
use Drupal\Core\Messenger\MessengerInterface;
use Drupal\Core\Messenger\MessengerTrait;
use Drupal\Core\StringTranslation\StringTranslationTrait;
......@@ -25,24 +27,54 @@ class LicenseOrderProcessorMultiples implements OrderProcessorInterface {
use MessengerTrait;
use StringTranslationTrait;
/**
* The entity type manager.
*
* @var \Drupal\Core\Entity\EntityTypeManagerInterface
*/
protected $entityTypeManager;
/**
* The UUID service.
*
* @var \Drupal\Component\Uuid\UuidInterface
*/
protected $uuid;
/**
* The license storage service.
*
* @var \Drupal\commerce_license\LicenseStorageInterface
*/
protected $licenseStorage;
/**
* Constructs a new LicenseOrderProcessorMultiples object.
*
* @param \Drupal\Core\Messenger\MessengerInterface $messenger
* The messenger.
* @param \Drupal\Core\Entity\EntityTypeManagerInterface $entity_type_manager
* The entity type manager.
* @param \Drupal\Component\Uuid\UuidInterface $uuid
* The uuid service.
*
* @throws \Drupal\Component\Plugin\Exception\InvalidPluginDefinitionException
* @throws \Drupal\Component\Plugin\Exception\PluginNotFoundException
*/
public function __construct(MessengerInterface $messenger) {
public function __construct(MessengerInterface $messenger, EntityTypeManagerInterface $entity_type_manager, UuidInterface $uuid) {
$this->setMessenger($messenger);
$this->entityTypeManager = $entity_type_manager;
$this->licenseStorage = $entity_type_manager->getStorage('commerce_license');
$this->uuid = $uuid;
}
/**
* {@inheritdoc}
*/
public function process(OrderInterface $order) {
// Collect licenses by types and configurations. Granting the same license
// type with the same configuration should be avoided.
/** @var \Drupal\commerce_product\Entity\ProductVariationInterface[] $purchased_entities_by_license_hash */
$purchased_entities_by_license_hash = [];
// Collect licenses by purchased entity.
/** @var \Drupal\commerce_product\Entity\ProductVariationInterface[] $purchased_entities */
$purchased_entities = [];
foreach ($order->getItems() as $order_item) {
// Skip order items that do not have a license reference field.
......@@ -61,12 +93,24 @@ class LicenseOrderProcessorMultiples implements OrderProcessorInterface {
]));
}
/** @var \Drupal\commerce\Plugin\Field\FieldType\PluginItem $license_type */
$license_type = $purchased_entity->get('license_type')->first();
$license_hash = \hash('sha256', \serialize($license_type->getValue()));
$product_variation_type_id = $purchased_entity->bundle();
$product_variation_type = $this->entityTypeManager->getStorage('commerce_product_variation_type')->load($product_variation_type_id);
$allow_renewal = $product_variation_type->getThirdPartySetting(
'commerce_license',
'allow_renewal',
FALSE
);
$existing_license = $this->licenseStorage->getExistingLicense($purchased_entity, $order->getCustomerId());
if ($existing_license) {
$license_uuid = $existing_license->uuid();
}
else {
$license_uuid = $this->uuid->generate();
}
// Check if this $purchased_entity is already in the cart.
if (in_array($purchased_entity, $purchased_entities_by_license_hash)) {
if (in_array($purchased_entity, $purchased_entities)) {
$order->removeItem($order_item);
// Remove success message from user facing messages.
$this->messenger()->deleteByType($this->messenger()::TYPE_STATUS);
......@@ -74,19 +118,20 @@ class LicenseOrderProcessorMultiples implements OrderProcessorInterface {
'%product-label' => $purchased_entity->label(),
]));
}
// If another $order_item resolves to the same license.
elseif (array_key_exists($license_hash, $purchased_entities_by_license_hash)) {
// If another $order_item resolves to the same product variation
// and the variation allows renewal.
elseif ($allow_renewal && array_key_exists($license_uuid, $purchased_entities)) {
$order->removeItem($order_item);
// Remove success message from user facing messages.
$this->messenger()->deleteByType($this->messenger()::TYPE_STATUS);
$this->messenger()->addError($this->t('Removed %removed-product-label as %product-label in your cart already grants the same license.', [
'%product-label' => $purchased_entities_by_license_hash[$license_hash]->label(),
'%product-label' => $purchased_entities[$license_uuid]->label(),
'%removed-product-label' => $purchased_entity->label(),
]));
}
// Add this to the array to check against.
else {
$purchased_entities_by_license_hash[$license_hash] = $purchased_entity;
$purchased_entities[$license_uuid] = $purchased_entity;
}
}
}
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment