Skip to content

Commit

Permalink
Merge pull request #3 from Setono/middleware
Browse files Browse the repository at this point in the history
Fix the populating of properties even if the event would be sent async
  • Loading branch information
loevgaard authored Dec 19, 2023
2 parents a70825e + 2b8d89a commit cc1db27
Show file tree
Hide file tree
Showing 18 changed files with 148 additions and 128 deletions.
6 changes: 5 additions & 1 deletion src/DependencyInjection/SetonoSyliusPlausibleExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,11 @@ public function prepend(ContainerBuilder $container): void
$container->prependExtensionConfig('framework', [
'messenger' => [
'buses' => [
'setono_sylius_plausible.event_bus' => null,
'setono_sylius_plausible.event_bus' => [
'middleware' => [
'setono_sylius_plausible.message.middleware.populate',
],
],
],
],
]);
Expand Down
28 changes: 0 additions & 28 deletions src/Event/Plausible/Event.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,6 @@ class Event implements \JsonSerializable

private ?Revenue $revenue = null;

/** @var array<string, mixed> */
private array $context = [];

public function __construct(private readonly string $name)
{
$this->properties = new Properties();
Expand Down Expand Up @@ -66,31 +63,6 @@ public function setRevenue(string $currency, float $amount): static
return $this;
}

public function getContext(): array
{
return $this->context;
}

/**
* You can set an event specific context that event listeners can use to add more data to the event.
* The context is not sent to Plausible.
*
* @param array<string, mixed> $context
*/
public function setContext(array $context): static
{
$this->context = $context;

return $this;
}

public function addContext(string $key, mixed $value): static
{
$this->context[$key] = $value;

return $this;
}

public function clientSide(): static
{
$this->clientSide = true;
Expand Down
4 changes: 2 additions & 2 deletions src/Event/Plausible/Properties.php
Original file line number Diff line number Diff line change
Expand Up @@ -83,9 +83,9 @@ public function offsetUnset(mixed $offset): void
unset($this->properties[$offset]);
}

public function jsonSerialize(): ?array
public function jsonSerialize(): array
{
return $this->properties;
return array_filter($this->properties, static fn (mixed $value): bool => null !== $value && '' !== $value);
}

/**
Expand Down
17 changes: 17 additions & 0 deletions src/Event/PopulateEvent.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,17 @@
<?php

declare(strict_types=1);

namespace Setono\SyliusPlausiblePlugin\Event;

use Setono\SyliusPlausiblePlugin\Event\Plausible\Event;

/**
* This event is dispatched in the middleware on the event bus, and you can listen to it to populate the event with data
*/
final class PopulateEvent
{
public function __construct(public readonly Event $event)
{
}
}
23 changes: 0 additions & 23 deletions src/Event/PreSendEvent.php

This file was deleted.

11 changes: 2 additions & 9 deletions src/EventSubscriber/AddressSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@

use Setono\SyliusPlausiblePlugin\Event\Plausible\Event;
use Setono\SyliusPlausiblePlugin\Event\Plausible\Events;
use Sylius\Bundle\ResourceBundle\Event\ResourceControllerEvent;
use Sylius\Component\Core\Model\OrderInterface;
use Webmozart\Assert\Assert;

final class AddressSubscriber extends AbstractEventSubscriber
{
Expand All @@ -19,14 +16,10 @@ public static function getSubscribedEvents(): array
];
}

public function track(ResourceControllerEvent $resourceControllerEvent): void
public function track(): void
{
try {
/** @var OrderInterface|mixed $order */
$order = $resourceControllerEvent->getSubject();
Assert::isInstanceOf($order, OrderInterface::class);

$this->eventBus->dispatch((new Event(Events::ADDRESS))->addContext('order', $order));
$this->eventBus->dispatch(new Event(Events::ADDRESS));
} catch (\Throwable $e) {
$this->log(Events::ADDRESS, $e);
}
Expand Down
2 changes: 1 addition & 1 deletion src/EventSubscriber/BeginCheckoutSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ public function track(RequestEvent $requestEvent): void
$order = $this->cartContext->getCart();
Assert::isInstanceOf($order, OrderInterface::class);

$this->eventBus->dispatch((new Event(Events::BEGIN_CHECKOUT))->addContext('order', $order));
$this->eventBus->dispatch(new Event(Events::BEGIN_CHECKOUT));
} catch (\Throwable $e) {
$this->log(Events::BEGIN_CHECKOUT, $e);
}
Expand Down
8 changes: 4 additions & 4 deletions src/EventSubscriber/PageviewSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -20,11 +20,11 @@ public static function getSubscribedEvents(): array

public function track(RequestEvent $requestEvent): void
{
try {
if (!$requestEvent->isMainRequest()) {
return;
}
if (!$requestEvent->isMainRequest()) {
return;
}

try {
$this->eventBus->dispatch(new Event(Events::PAGEVIEW));
} catch (\Throwable $e) {
$this->log(Events::PAGEVIEW, $e);
Expand Down
56 changes: 28 additions & 28 deletions src/EventSubscriber/PopulateOrderRelatedPropertiesSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -5,45 +5,55 @@
namespace Setono\SyliusPlausiblePlugin\EventSubscriber;

use Setono\SyliusPlausiblePlugin\Event\Plausible\Event;
use Setono\SyliusPlausiblePlugin\Event\PreSendEvent;
use Setono\SyliusPlausiblePlugin\Event\PopulateEvent;
use Sylius\Component\Core\Model\OrderInterface;
use Sylius\Component\Order\Context\CartContextInterface;
use Sylius\Component\Order\Context\CartNotFoundException;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Webmozart\Assert\Assert;

final class PopulateOrderRelatedPropertiesSubscriber implements EventSubscriberInterface
{
public function __construct(private readonly CartContextInterface $cartContext)
{
}

public static function getSubscribedEvents(): array
{
return [
PreSendEvent::class => 'populate',
PopulateEvent::class => 'populate',
];
}

public function populate(PreSendEvent $event): void
public function populate(PopulateEvent $event): void
{
$context = $event->event->getContext();
if (!isset($context['order'])) {
try {
$order = $this->cartContext->getCart();
} catch (CartNotFoundException) {
return;
}

if (!$order instanceof OrderInterface) {
return;
}

/** @var OrderInterface|mixed $order */
$order = $context['order'];
Assert::isInstanceOf($order, OrderInterface::class);
/** @var mixed $orderId */
$orderId = $order->getId();

// if the order id is null it means that the order has not been persisted yet
if (null === $orderId) {
return;
}

$event->event
->setProperty('order_id', (string) $order->getId())
->setProperty('order_number', (string) $order->getNumber())
->setProperty('order_id', $orderId)
->setProperty('order_number', $order->getNumber())
->setProperty('shipping_total', $order->getShippingTotal())
->setProperty('order_promotion_total', $order->getOrderPromotionTotal())
->setProperty('payment_method', $order->getLastPayment()?->getMethod()?->getCode())
->setProperty('coupon_code', $order->getPromotionCoupon()?->getCode())
;

$couponCode = $order->getPromotionCoupon()?->getCode();
if (null !== $couponCode) {
$event->event->setProperty('coupon_code', $couponCode);
}

self::populateShippingMethod($order, $event->event);
self::populatePaymentMethod($order, $event->event);
}

private static function populateShippingMethod(OrderInterface $order, Event $event): void
Expand All @@ -58,16 +68,6 @@ private static function populateShippingMethod(OrderInterface $order, Event $eve
$shippingMethodCode = $shippingMethod->getCode();
}

if (null !== $shippingMethodCode) {
$event->setProperty('shipping_method', $shippingMethodCode);
}
}

private static function populatePaymentMethod(OrderInterface $order, Event $event): void
{
$paymentMethodCode = $order->getLastPayment()?->getMethod()?->getCode();
if (null !== $paymentMethodCode) {
$event->setProperty('payment_method', $paymentMethodCode);
}
$event->setProperty('shipping_method', $shippingMethodCode);
}
}
1 change: 0 additions & 1 deletion src/EventSubscriber/PurchaseSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,6 @@ public function track(RequestEvent $requestEvent): void

$this->eventBus->dispatch(
(new Event(Events::PURCHASE))
->addContext('order', $order)
->setRevenue((string) $order->getCurrencyCode(), self::formatAmount($order->getTotal())),
);
} catch (\Throwable $e) {
Expand Down
11 changes: 2 additions & 9 deletions src/EventSubscriber/SelectPaymentMethodSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@

use Setono\SyliusPlausiblePlugin\Event\Plausible\Event;
use Setono\SyliusPlausiblePlugin\Event\Plausible\Events;
use Sylius\Bundle\ResourceBundle\Event\ResourceControllerEvent;
use Sylius\Component\Core\Model\OrderInterface;
use Webmozart\Assert\Assert;

final class SelectPaymentMethodSubscriber extends AbstractEventSubscriber
{
Expand All @@ -19,14 +16,10 @@ public static function getSubscribedEvents(): array
];
}

public function track(ResourceControllerEvent $resourceControllerEvent): void
public function track(): void
{
try {
/** @var OrderInterface|mixed $order */
$order = $resourceControllerEvent->getSubject();
Assert::isInstanceOf($order, OrderInterface::class);

$this->eventBus->dispatch((new Event(Events::SELECT_PAYMENT_METHOD))->addContext('order', $order));
$this->eventBus->dispatch(new Event(Events::SELECT_PAYMENT_METHOD));
} catch (\Throwable $e) {
$this->log(Events::SELECT_PAYMENT_METHOD, $e);
}
Expand Down
11 changes: 2 additions & 9 deletions src/EventSubscriber/SelectShippingMethodSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -6,9 +6,6 @@

use Setono\SyliusPlausiblePlugin\Event\Plausible\Event;
use Setono\SyliusPlausiblePlugin\Event\Plausible\Events;
use Sylius\Bundle\ResourceBundle\Event\ResourceControllerEvent;
use Sylius\Component\Core\Model\OrderInterface;
use Webmozart\Assert\Assert;

final class SelectShippingMethodSubscriber extends AbstractEventSubscriber
{
Expand All @@ -19,14 +16,10 @@ public static function getSubscribedEvents(): array
];
}

public function track(ResourceControllerEvent $resourceControllerEvent): void
public function track(): void
{
try {
/** @var OrderInterface|mixed $order */
$order = $resourceControllerEvent->getSubject();
Assert::isInstanceOf($order, OrderInterface::class);

$this->eventBus->dispatch((new Event(Events::SELECT_SHIPPING_METHOD))->addContext('order', $order));
$this->eventBus->dispatch(new Event(Events::SELECT_SHIPPING_METHOD));
} catch (\Throwable $e) {
$this->log(Events::SELECT_SHIPPING_METHOD, $e);
}
Expand Down
15 changes: 2 additions & 13 deletions src/Message/EventHandler/ClientSideEventHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -4,35 +4,24 @@

namespace Setono\SyliusPlausiblePlugin\Message\EventHandler;

use Psr\EventDispatcher\EventDispatcherInterface;
use Psr\Log\LoggerAwareInterface;
use Psr\Log\LoggerInterface;
use Psr\Log\NullLogger;
use Setono\SyliusPlausiblePlugin\Event\Plausible\Event;
use Setono\SyliusPlausiblePlugin\Event\PreSendEvent;
use Setono\TagBag\Tag\InlineScriptTag;
use Setono\TagBag\TagBagInterface;

final class ClientSideEventHandler implements LoggerAwareInterface
{
private LoggerInterface $logger;

public function __construct(
private readonly TagBagInterface $tagBag,
private readonly EventDispatcherInterface $eventDispatcher,
) {
public function __construct(private readonly TagBagInterface $tagBag)
{
$this->logger = new NullLogger();
}

public function __invoke(Event $event): void
{
$preSendEvent = new PreSendEvent($event);
$this->eventDispatcher->dispatch($preSendEvent);

if (!$preSendEvent->send) {
return;
}

$event->clientSide();

try {
Expand Down
32 changes: 32 additions & 0 deletions src/Message/Middleware/PopulateMiddleware.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,32 @@
<?php

declare(strict_types=1);

namespace Setono\SyliusPlausiblePlugin\Message\Middleware;

use Psr\EventDispatcher\EventDispatcherInterface;
use Setono\SyliusPlausiblePlugin\Event\Plausible\Event;
use Setono\SyliusPlausiblePlugin\Event\PopulateEvent;
use Setono\SyliusPlausiblePlugin\Message\Stamp\PopulatedStamp;
use Symfony\Component\Messenger\Envelope;
use Symfony\Component\Messenger\Middleware\MiddlewareInterface;
use Symfony\Component\Messenger\Middleware\StackInterface;

final class PopulateMiddleware implements MiddlewareInterface
{
public function __construct(private readonly EventDispatcherInterface $eventDispatcher)
{
}

public function handle(Envelope $envelope, StackInterface $stack): Envelope
{
$message = $envelope->getMessage();

if ($message instanceof Event && $envelope->last(PopulatedStamp::class) === null) {
$this->eventDispatcher->dispatch(new PopulateEvent($message));
$envelope = $envelope->with(new PopulatedStamp());
}

return $stack->next()->handle($envelope, $stack);
}
}
11 changes: 11 additions & 0 deletions src/Message/Stamp/PopulatedStamp.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
<?php

declare(strict_types=1);

namespace Setono\SyliusPlausiblePlugin\Message\Stamp;

use Symfony\Component\Messenger\Stamp\StampInterface;

final class PopulatedStamp implements StampInterface
{
}
Loading

0 comments on commit cc1db27

Please sign in to comment.