Skip to content

Commit

Permalink
Handle callout updates
Browse files Browse the repository at this point in the history
  • Loading branch information
loevgaard committed Jan 24, 2024
1 parent 9e47da3 commit 8c77d30
Show file tree
Hide file tree
Showing 6 changed files with 133 additions and 84 deletions.

This file was deleted.

122 changes: 122 additions & 0 deletions src/EventSubscriber/HandleCalloutUpdateSubscriber.php
Original file line number Diff line number Diff line change
@@ -0,0 +1,122 @@
<?php

declare(strict_types=1);

namespace Setono\SyliusCalloutPlugin\EventSubscriber;

use Doctrine\ORM\Event\PrePersistEventArgs;
use Doctrine\ORM\Event\PreUpdateEventArgs;
use Setono\SyliusCalloutPlugin\Message\Command\AssignCallouts;
use Setono\SyliusCalloutPlugin\Model\CalloutInterface;
use Setono\SyliusCalloutPlugin\Model\CalloutRuleInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Messenger\MessageBusInterface;

/**
* This subscriber listens for changes to callouts and callout rules
* and dispatches a message to assign the callouts to products
*/
final class HandleCalloutUpdateSubscriber implements EventSubscriberInterface
{
/** @var array<string, bool> */
private array $calloutsToAssign = [];

public function __construct(private readonly MessageBusInterface $commandBus)
{
}

public static function getSubscribedEvents(): array
{
return [
'setono_sylius_callout.callout.post_create' => 'postUpdate',
'setono_sylius_callout.callout.post_update' => 'postUpdate',
];
}

/**
* This is called when a callout is persisted. When a callout is persisted it's obviously new, so we want to assign
*/
public function prePersist(PrePersistEventArgs $event): void
{
$callout = $event->getObject();
if (!$callout instanceof CalloutInterface) {
return;
}

$this->calloutsToAssign[(string) $callout->getCode()] = true;
}

/**
* This is called when a callout or callout rule is updated
*/
public function preUpdate(PreUpdateEventArgs $event): void
{
$obj = $event->getObject();

if ($obj instanceof CalloutInterface) {
$this->preUpdateCallout($obj, $event);
}

if ($obj instanceof CalloutRuleInterface) {
$this->preUpdateCalloutRule($obj, $event);
}
}

/**
* This is called when a callout is updated. Before assigning we check if the changed fields are all irrelevant to the assignment process
*/
private function preUpdateCallout(CalloutInterface $callout, PreUpdateEventArgs $event): void
{
// this is a list of fields that are irrelevant for the assignment of callouts
// and hence we don't want to trigger the assignment if _only_ these fields are changed
// todo define these fields using attributes on the properties in the entity
$irrelevantFields = ['version', 'name', 'startsAt', 'endsAt', 'priority', 'elements', 'position', 'color', 'backgroundColor', 'createdAt', 'updatedAt'];

// now we check if _all_ of the changed fields are irrelevant
$allIrrelevant = true;

foreach ($event->getEntityChangeSet() as $field => $change) {
if (!in_array($field, $irrelevantFields, true)) {
$allIrrelevant = false;

break;
}
}

if ($allIrrelevant) {
return;
}

$this->calloutsToAssign[(string) $callout->getCode()] = true;
}

/**
* This is called when a callout rule is updated. Before assigning we check if either the type or configuration has changed
*/
private function preUpdateCalloutRule(CalloutRuleInterface $calloutRule, PreUpdateEventArgs $event): void
{
if (!$event->hasChangedField('configuration') && !$event->hasChangedField('type')) {
return;
}

$callout = $calloutRule->getCallout();
if (null === $callout) {
return;
}

$this->calloutsToAssign[(string) $callout->getCode()] = true;
}

/**
* This is called when a callout is created or updated by Sylius.
* In the lifecycle this is the last method called and therefore we can safely dispatch the message here if needed
*/
public function postUpdate(): void
{
if ([] === $this->calloutsToAssign) {
return;
}

$this->commandBus->dispatch(new AssignCallouts(array_keys($this->calloutsToAssign)));
}
}
4 changes: 2 additions & 2 deletions src/Message/Command/AssignCallouts.php
Original file line number Diff line number Diff line change
Expand Up @@ -15,12 +15,12 @@ final class AssignCallouts implements CommandInterface
public array $callouts = [];

/**
* @param list<CalloutInterface> $callouts If the callouts array is empty, all callouts will be assigned
* @param list<CalloutInterface|string> $callouts If the callouts array is empty, all callouts will be assigned
*/
public function __construct(array $callouts = [])
{
foreach ($callouts as $callout) {
$this->callouts[] = (string) $callout->getCode();
$this->callouts[] = $callout instanceof CalloutInterface ? (string) $callout->getCode() : $callout;
}
}
}
1 change: 0 additions & 1 deletion src/Resources/config/services.xml
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@
<import resource="services/command.xml"/>
<import resource="services/controller.xml"/>
<import resource="services/css_class_builder.xml"/>
<import resource="services/event_listener.xml"/>
<import resource="services/event_subscriber.xml"/>
<import resource="services/factory.xml"/>
<import resource="services/fixture.xml"/>
Expand Down
15 changes: 0 additions & 15 deletions src/Resources/config/services/event_listener.xml

This file was deleted.

9 changes: 9 additions & 0 deletions src/Resources/config/services/event_subscriber.xml
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,15 @@
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">
<services>
<service id="setono_sylius_callout.event_subscriber.handle_callout_update"
class="Setono\SyliusCalloutPlugin\EventSubscriber\HandleCalloutUpdateSubscriber">
<argument type="service" id="setono_sylius_callout.command_bus"/>

<tag name="doctrine.event_listener" event="prePersist"/>
<tag name="doctrine.event_listener" event="preUpdate"/>
<tag name="kernel.event_subscriber"/>
</service>

<service id="setono_sylius_callout.event_subscriber.handle_product_update"
class="Setono\SyliusCalloutPlugin\EventSubscriber\HandleProductUpdateSubscriber">
<argument type="service" id="setono_sylius_callout.command_bus"/>
Expand Down

0 comments on commit 8c77d30

Please sign in to comment.