Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Allow a delay when assigning callouts #110

Merged
merged 1 commit into from
Jan 26, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
11 changes: 10 additions & 1 deletion src/DependencyInjection/Configuration.php
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,16 @@ public function getConfigTreeBuilder(): TreeBuilder
'bottom_center',
'bottom_right',
])
->scalarPrototype()
->scalarPrototype()->end()
->end()
->arrayNode('assignment')
->addDefaultsIfNotSet()
->children()
->integerNode('delay')
->info('The delay in seconds when assigning a callout. This is to avoid assigning the same callout multiple times within a short interval')
->defaultValue(60)
->min(0)

;

$this->addResourcesSection($rootNode);
Expand Down
2 changes: 2 additions & 0 deletions src/DependencyInjection/SetonoSyliusCalloutExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@ public function load(array $configs, ContainerBuilder $container): void
* @var array{
* elements: list<string>,
* positions: list<string>,
* assignment: array{delay: int},
* resources: array
* } $config
*/
Expand All @@ -31,6 +32,7 @@ public function load(array $configs, ContainerBuilder $container): void

$container->setParameter('setono_sylius_callout.elements', $config['elements']);
$container->setParameter('setono_sylius_callout.positions', $config['positions']);
$container->setParameter('setono_sylius_callout.assignment.delay', $config['assignment']['delay']);

$this->registerResources('setono_sylius_callout', SyliusResourceBundle::DRIVER_DOCTRINE_ORM, $config['resources'], $container);
}
Expand Down
24 changes: 16 additions & 8 deletions src/EventSubscriber/HandleCalloutUpdateSubscriber.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,6 +11,7 @@
use Setono\SyliusCalloutPlugin\Model\CalloutRuleInterface;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Messenger\MessageBusInterface;
use Symfony\Component\Messenger\Stamp\DelayStamp;

/**
* This subscriber listens for changes to callouts and callout rules
Expand All @@ -21,12 +22,14 @@
/**
* The keys are the callout codes and the values are true
*
* @var array<string, bool>
* @var array<string, CalloutInterface>
*/
private array $calloutsToAssign = [];

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

Check failure on line 29 in src/EventSubscriber/HandleCalloutUpdateSubscriber.php

View workflow job for this annotation

GitHub Actions / Backwards Compatibility Check

The number of required arguments for Setono\SyliusCalloutPlugin\EventSubscriber\HandleCalloutUpdateSubscriber#__construct() increased from 1 to 2
private readonly MessageBusInterface $commandBus,
private readonly int $processingDelay,
) {
}

public static function getSubscribedEvents(): array
Expand All @@ -47,7 +50,7 @@
return;
}

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

/**
Expand Down Expand Up @@ -91,7 +94,7 @@
return;
}

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

/**
Expand All @@ -108,19 +111,24 @@
return;
}

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

/**
* 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
* 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)));
$stamps = [];
if ($this->processingDelay > 0) {
$stamps[] = new DelayStamp($this->processingDelay * 1000);
}

$this->commandBus->dispatch(new AssignCallouts(array_values($this->calloutsToAssign)), $stamps);
}
}
31 changes: 0 additions & 31 deletions src/Message/Command/AssignCallout.php

This file was deleted.

8 changes: 6 additions & 2 deletions src/Message/Command/AssignCallouts.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,11 @@
*/
final class AssignCallouts implements CommandInterface
{
/** @var list<string> */
/**
* This is a list of arrays where the first element is the callout code and the second element is the version
*
* @var list<array{string, int|null}>
*/
public array $callouts = [];

/**
Expand All @@ -20,7 +24,7 @@ final class AssignCallouts implements CommandInterface
public function __construct(array $callouts = [])
{
foreach ($callouts as $callout) {
$this->callouts[] = $callout instanceof CalloutInterface ? (string) $callout->getCode() : $callout;
$this->callouts[] = $callout instanceof CalloutInterface ? [(string) $callout->getCode(), $callout->getVersion()] : [$callout, null];
}
}
}
32 changes: 0 additions & 32 deletions src/Message/Handler/AssignCalloutHandler.php

This file was deleted.

22 changes: 21 additions & 1 deletion src/Message/Handler/AssignCalloutsHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -11,8 +11,28 @@ final class AssignCalloutsHandler extends AbstractAssignCalloutsHandler
public function __invoke(AssignCallouts $message): void
{
$callouts = [];

if ([] !== $message->callouts) {
$callouts = $this->calloutRepository->findEnabled($message->callouts);
foreach ($message->callouts as $calloutShape) {
$callout = $this->calloutRepository->findOneByCode($calloutShape[0]);
if (null === $callout) {
continue;
}

if (null !== $calloutShape[1] && $calloutShape[1] !== $callout->getVersion()) {
continue;
}

if (!$callout->isEnabled()) {
continue;
}

$callouts[] = $callout;
}

if ([] === $callouts) {
return;
}
}

$this->assign(callouts: $callouts);
Expand Down
2 changes: 2 additions & 0 deletions src/Model/ProductTrait.php
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ public function removePreQualifiedCallout(CalloutInterface|string $preQualifiedC
if (false !== $key) {
unset($this->preQualifiedCallouts[$key]);
}

$this->preQualifiedCallouts = array_values($this->preQualifiedCallouts);
}

public function resetPreQualifiedCallouts(): void
Expand Down
1 change: 1 addition & 0 deletions src/Resources/config/services/event_subscriber.xml
Original file line number Diff line number Diff line change
Expand Up @@ -12,6 +12,7 @@
<service id="setono_sylius_callout.event_subscriber.handle_callout_update"
class="Setono\SyliusCalloutPlugin\EventSubscriber\HandleCalloutUpdateSubscriber">
<argument type="service" id="setono_sylius_callout.command_bus"/>
<argument>%setono_sylius_callout.assignment.delay%</argument>

<tag name="doctrine.event_listener" event="prePersist"/>
<tag name="doctrine.event_listener" event="preUpdate"/>
Expand Down
6 changes: 0 additions & 6 deletions src/Resources/config/services/message.xml
Original file line number Diff line number Diff line change
Expand Up @@ -13,12 +13,6 @@
<argument>%sylius.model.product.class%</argument>
</service>

<service id="setono_sylius_callout.message.handler.assign_callout"
class="Setono\SyliusCalloutPlugin\Message\Handler\AssignCalloutHandler"
parent="setono_sylius_callout.message.handler.abstract_assign_callouts">
<tag name="messenger.message_handler"/>
</service>

<service id="setono_sylius_callout.message.handler.assign_callouts"
class="Setono\SyliusCalloutPlugin\Message\Handler\AssignCalloutsHandler"
parent="setono_sylius_callout.message.handler.abstract_assign_callouts">
Expand Down
1 change: 1 addition & 0 deletions src/Resources/config/services/twig.xml
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
<services>
<service id="setono_sylius_callout.twig.callout_extension"
class="Setono\SyliusCalloutPlugin\Twig\CalloutExtension">
<argument>%setono_sylius_callout.assignment.delay%</argument>
<tag name="twig.extension"/>
</service>

Expand Down
7 changes: 4 additions & 3 deletions src/Resources/translations/messages.en.yml
Original file line number Diff line number Diff line change
Expand Up @@ -46,8 +46,11 @@ setono_sylius_callout:
assign: Assign
bottom_left: Bottom left
bottom_right: Bottom right
callout: Callout
callouts: Callouts
callouts_product_list: Product list
code: Code
delay_info: "NOTICE: Callouts are configured to wait %seconds% seconds before the assignment process is started"
edit_callout: Edit callout
enabled: Enabled
ends_at: Ends at
Expand All @@ -59,13 +62,11 @@ setono_sylius_callout:
on_sale: On sale
position: Position
priority: Priority
rule: Rule
rules: Rules
select_position: Select position...
starts_at: Starts at
text: Text
top_left: Top left
top_right: Top right
type: Type
callout: Callout
rule: Rule
callouts_product_list: Product list
7 changes: 7 additions & 0 deletions src/Resources/views/Admin/Callout/_form.html.twig
Original file line number Diff line number Diff line change
Expand Up @@ -63,3 +63,10 @@
</div>
</div>
</div>

{% if get_callout_assignment_delay() > 0 %}
<div class="ui icon info message" style="max-width: fit-content;">
<i class="info circle icon"></i>
{{ 'setono_sylius_callout.ui.delay_info'|trans( { '%seconds%': get_callout_assignment_delay() }) }}
</div>
{% endif %}
10 changes: 10 additions & 0 deletions src/Twig/CalloutExtension.php
Original file line number Diff line number Diff line change
Expand Up @@ -9,12 +9,22 @@

final class CalloutExtension extends AbstractExtension
{
public function __construct(private readonly int $delay)
{
}

public function getFunctions(): array
{
return [
new TwigFunction('get_callouts', [CalloutRuntime::class, 'getCallouts']),
new TwigFunction('get_callout_assignment_delay', $this->getDelay(...)),
new TwigFunction('render_class_attribute', [CalloutRuntime::class, 'renderClassAttribute']),
new TwigFunction('render_callout', [CalloutRuntime::class, 'renderCallout'], ['is_safe' => ['html']]),
];
}

public function getDelay(): int
{
return $this->delay;
}
}
Loading