-
Notifications
You must be signed in to change notification settings - Fork 53
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
PISHPS-311: added custom event and cart collector for subscriptions (#…
…801) * PISHPS-311: added custom event and cart collector for subscriptions * PISHPS-311: SubscriptionCartCollector now uses LineItemAttributes to determine if a product is a subscription product * PISHPS-311: removed SubscriptionProductIdentifier
- Loading branch information
1 parent
ac3a463
commit bcbda5b
Showing
4 changed files
with
199 additions
and
0 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,57 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace Kiener\MolliePayments\Event; | ||
|
||
use Shopware\Core\Checkout\Cart\LineItem\LineItem as CheckoutCartLineItem; | ||
use Shopware\Core\System\SalesChannel\SalesChannelContext; | ||
|
||
/** | ||
* Class MollieSubscriptionCartItemAddedEvent | ||
* | ||
* This event is triggered when a product with a Mollie subscription is added to the cart. | ||
*/ | ||
class MollieSubscriptionCartItemAddedEvent | ||
{ | ||
/** | ||
* @var SalesChannelContext | ||
*/ | ||
private $context; | ||
|
||
/** | ||
* @var CheckoutCartLineItem | ||
*/ | ||
private $lineItem; | ||
|
||
/** | ||
* MollieSubscriptionCartItemAddedEvent constructor. | ||
* | ||
* @param SalesChannelContext $context The sales channel context | ||
* @param CheckoutCartLineItem $lineItem The line item added to the cart | ||
*/ | ||
public function __construct(SalesChannelContext $context, CheckoutCartLineItem $lineItem) | ||
{ | ||
$this->context = $context; | ||
$this->lineItem = $lineItem; | ||
} | ||
|
||
/** | ||
* Get the sales channel context. | ||
* | ||
* @return SalesChannelContext The sales channel context | ||
*/ | ||
public function getSalesChannelContext(): SalesChannelContext | ||
{ | ||
return $this->context; | ||
} | ||
|
||
/** | ||
* Get the line item that was added to the cart. | ||
* | ||
* @return CheckoutCartLineItem The line item added to the cart | ||
*/ | ||
public function getLineItem(): CheckoutCartLineItem | ||
{ | ||
return $this->lineItem; | ||
} | ||
} |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
56 changes: 56 additions & 0 deletions
56
src/Service/Cart/Subscription/SubscriptionCartCollector.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,56 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace Kiener\MolliePayments\Service\Cart\Subscription; | ||
|
||
use Kiener\MolliePayments\Event\MollieSubscriptionCartItemAddedEvent; | ||
use Kiener\MolliePayments\Struct\LineItem\LineItemAttributes; | ||
use Shopware\Core\Checkout\Cart\Cart; | ||
use Shopware\Core\Checkout\Cart\CartBehavior; | ||
use Shopware\Core\Checkout\Cart\CartDataCollectorInterface; | ||
use Shopware\Core\Checkout\Cart\LineItem\CartDataCollection; | ||
use Shopware\Core\System\SalesChannel\SalesChannelContext; | ||
use Symfony\Contracts\EventDispatcher\EventDispatcherInterface; | ||
|
||
/** | ||
* Class SubscriptionCartCollector | ||
* | ||
* This class is responsible for collecting subscription products added to the cart | ||
* and dispatching corresponding events. | ||
*/ | ||
class SubscriptionCartCollector implements CartDataCollectorInterface | ||
{ | ||
/** | ||
* @var EventDispatcherInterface | ||
*/ | ||
private $dispatcher; | ||
|
||
/** | ||
* SubscriptionCartCollector constructor. | ||
* | ||
* @param EventDispatcherInterface $dispatcher The event dispatcher | ||
*/ | ||
public function __construct(EventDispatcherInterface $dispatcher) | ||
{ | ||
$this->dispatcher = $dispatcher; | ||
} | ||
|
||
/** | ||
* Collects subscription line items from the cart and dispatches events for each subscription product added. | ||
* | ||
* @param CartDataCollection $data The cart data collection | ||
* @param Cart $original The original cart | ||
* @param SalesChannelContext $context The sales channel context | ||
* @param CartBehavior $behavior The cart behavior | ||
*/ | ||
public function collect(CartDataCollection $data, Cart $original, SalesChannelContext $context, CartBehavior $behavior): void | ||
{ | ||
$events = []; | ||
foreach ($original->getLineItems() as $lineItem) { | ||
if ((new LineItemAttributes($lineItem))->isSubscriptionProduct()) { | ||
$events[] = new MollieSubscriptionCartItemAddedEvent($context, $lineItem); | ||
} | ||
} | ||
array_map([$this->dispatcher, 'dispatch'], $events); | ||
} | ||
} |
80 changes: 80 additions & 0 deletions
80
tests/PHPUnit/Service/Cart/Subscription/SubscriptionCartCollectorTest.php
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,80 @@ | ||
<?php | ||
declare(strict_types=1); | ||
|
||
namespace MolliePayments\Tests\Service\Cart\Subscription; | ||
|
||
|
||
use Kiener\MolliePayments\Event\MollieSubscriptionCartItemAddedEvent; | ||
use Kiener\MolliePayments\Service\Cart\Subscription\SubscriptionCartCollector; | ||
use Kiener\MolliePayments\Service\Cart\Subscription\SubscriptionProductIdentifier; | ||
use PHPUnit\Framework\TestCase; | ||
use Shopware\Core\Checkout\Cart\Cart; | ||
use Shopware\Core\Checkout\Cart\CartBehavior; | ||
use Shopware\Core\Checkout\Cart\LineItem\CartDataCollection; | ||
use Shopware\Core\Checkout\Cart\LineItem\LineItemCollection; | ||
use Shopware\Core\Framework\Uuid\Uuid; | ||
use Shopware\Core\System\SalesChannel\SalesChannelContext; | ||
use Symfony\Component\EventDispatcher\EventDispatcherInterface; | ||
use Shopware\Core\Checkout\Cart\LineItem\LineItem as CheckoutCartLineItem; | ||
|
||
class SubscriptionCartCollectorTest extends TestCase | ||
{ | ||
const SUBSCRIPTION_ENABLED = 'mollie_payments_product_subscription_enabled'; | ||
private $dispatcher; | ||
private $collector; | ||
private $data; | ||
|
||
protected function setUp(): void | ||
{ | ||
$this->dispatcher = $this->createMock(EventDispatcherInterface::class); | ||
$this->collector = new SubscriptionCartCollector($this->dispatcher); | ||
$this->data = $this->createMock(CartDataCollection::class); | ||
$this->original = $this->createMock(Cart::class); | ||
$this->context = $this->createMock(SalesChannelContext::class); | ||
$this->behavior = $this->createMock(CartBehavior::class); | ||
} | ||
|
||
public function testDispatchesEventWhenAProductIsAMollieSubscriptionProduct(): void | ||
{ | ||
// this will cause the line item to be considered a subscription product and trigger the event | ||
$subscriptionProduct = $this->createLineItemMockWithPayloadValue([self::SUBSCRIPTION_ENABLED => true,]); | ||
|
||
// this will cause the line item to be considered a regular product and not trigger the event | ||
$regularProduct = $this->createLineItemMockWithPayloadValue([self::SUBSCRIPTION_ENABLED => false,]); | ||
|
||
$this->configureGetLineItemsMethodOfCart($subscriptionProduct, $regularProduct); | ||
|
||
// we expect the event to be dispatched only once | ||
$this->dispatcher->expects($this->once()) | ||
->method('dispatch') | ||
->with($this->isInstanceOf(MollieSubscriptionCartItemAddedEvent::class)); | ||
|
||
$this->collector->collect($this->data, $this->original, $this->context, $this->behavior); | ||
} | ||
|
||
public function testDoesNotDispatchEventWhenNoMollieSubscriptionProductIsAdded(): void | ||
{ | ||
// this will cause the line item to be considered a regular product and not trigger the event | ||
$regularProduct = $this->createLineItemMockWithPayloadValue([self::SUBSCRIPTION_ENABLED => false,]); | ||
|
||
$this->configureGetLineItemsMethodOfCart($regularProduct); | ||
|
||
// we expect the event to not be dispatched | ||
$this->dispatcher->expects($this->never())->method('dispatch'); | ||
|
||
$this->collector->collect($this->data, $this->original, $this->context, $this->behavior); | ||
} | ||
|
||
private function createLineItemMockWithPayloadValue($value): CheckoutCartLineItem | ||
{ | ||
return (new CheckoutCartLineItem( | ||
Uuid::randomBytes(), | ||
'product' | ||
))->setPayload(['customFields' => $value]); | ||
} | ||
|
||
private function configureGetLineItemsMethodOfCart(CheckoutCartLineItem ...$items): void | ||
{ | ||
$this->original->method('getLineItems')->willReturn(new LineItemCollection($items)); | ||
} | ||
} |