Skip to content

Commit

Permalink
Make a more robust versioning of webhooks
Browse files Browse the repository at this point in the history
  • Loading branch information
loevgaard committed Apr 5, 2024
1 parent a162e5b commit 5ee1611
Show file tree
Hide file tree
Showing 6 changed files with 45 additions and 25 deletions.
2 changes: 1 addition & 1 deletion src/Controller/Admin/ShipmondoController.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ public function __construct(
public function index(): Response
{
return $this->render('@SetonoSyliusShipmondoPlugin/admin/shipmondo/index.html.twig', [
'registeredWebhooks' => $this->registeredWebhooksRepository->findOneByHash($this->webhookRegistrar->getHash()),
'registeredWebhooks' => $this->registeredWebhooksRepository->findOneByHash($this->webhookRegistrar->getVersion()),
]);
}

Expand Down
4 changes: 2 additions & 2 deletions src/Message/CommandHandler/RegisterWebhooksHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -24,15 +24,15 @@ public function __invoke(RegisterWebhooks $message): void
{
$this->webhookRegistrar->register();

$hash = $this->webhookRegistrar->getHash();
$hash = $this->webhookRegistrar->getVersion();

$registeredWebhooks = $this->registeredWebhooksRepository->findOneByHash($hash);
if (null === $registeredWebhooks) {
$registeredWebhooks = $this->registeredWebhooksFactory->createNew();
}

$registeredWebhooks->setRegisteredAt(new \DateTimeImmutable());
$registeredWebhooks->setHash($this->webhookRegistrar->getHash());
$registeredWebhooks->setVersion($this->webhookRegistrar->getVersion());

$this->registeredWebhooksRepository->add($registeredWebhooks);
}
Expand Down
10 changes: 5 additions & 5 deletions src/Model/RegisteredWebhooks.php
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,7 @@ class RegisteredWebhooks implements RegisteredWebhooksInterface
{
protected ?int $id = null;

protected ?string $hash = null;
protected ?string $version = null;

protected ?\DateTimeInterface $registeredAt = null;

Expand All @@ -17,14 +17,14 @@ public function getId(): ?int
return $this->id;
}

public function getHash(): ?string
public function getVersion(): ?string
{
return $this->hash;
return $this->version;
}

public function setHash(?string $hash): void
public function setVersion(?string $version): void
{
$this->hash = $hash;
$this->version = $version;
}

public function getRegisteredAt(): ?\DateTimeInterface
Expand Down
4 changes: 2 additions & 2 deletions src/Model/RegisteredWebhooksInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,9 @@ interface RegisteredWebhooksInterface extends ResourceInterface
{
public function getId(): ?int;

public function getHash(): ?string;
public function getVersion(): ?string;

public function setHash(?string $hash): void;
public function setVersion(?string $version): void;

public function getRegisteredAt(): ?\DateTimeInterface;

Expand Down
45 changes: 33 additions & 12 deletions src/Registrar/WebhookRegistrar.php
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,32 @@ public function register(): void
fn (WebhookResponse $webhook) => str_starts_with($webhook->name, $this->namePrefix),
);

foreach ($this->getWebhooks() as $webhook) {
$this->client->webhooks()->create(new WebhookRequest(
$webhook['name'],
$webhook['endpoint'],
$webhook['key'],
$webhook['action'],
$webhook['resource'],
));
}
}

public function getVersion(): string
{
$webhooks = iterator_to_array($this->getWebhooks());
usort($webhooks, static fn (array $a, array $b) => $a['name'] <=> $b['name']);

$webhooks = array_map(static fn (array $webhook) => $webhook['name'] . $webhook['endpoint'] . $webhook['key'] . $webhook['action'] . $webhook['resource'], $webhooks);

return md5(implode($webhooks));
}

/**
* @return \Generator<array-key, array{name: string, endpoint: string, key: string, action: string, resource: string}>
*/
private function getWebhooks(): \Generator
{
$resources = [
'Shipments' => ['create', 'cancel'],
'Orders' => ['create', 'status_update', 'create_fulfillment', 'create_shipment', 'payment_captured', 'payment_voided', 'delete'],
Expand All @@ -34,9 +60,9 @@ public function register(): void

foreach ($resources as $resource => $actions) {
foreach ($actions as $action) {
$this->client->webhooks()->create(new WebhookRequest(
sprintf('%s - [%s:%s]', $this->namePrefix, u($resource)->snake()->toString(), $action),
$this->urlGenerator->generate(
yield [
'name' => sprintf('%s - [%s:%s]', $this->namePrefix, u($resource)->snake()->toString(), $action),
'endpoint' => $this->urlGenerator->generate(
'_webhook_controller',
[
'type' => 'shipmondo',
Expand All @@ -45,16 +71,11 @@ public function register(): void
],
UrlGeneratorInterface::ABSOLUTE_URL,
),
$this->webhooksKey,
$action,
$resource,
));
'key' => $this->webhooksKey,
'action' => $action,
'resource' => $resource,
];
}
}
}

public function getHash(): string
{
return md5_file(__FILE__);
}
}
5 changes: 2 additions & 3 deletions src/Registrar/WebhookRegistrarInterface.php
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@ interface WebhookRegistrarInterface
public function register(): void;

/**
* Should return a hash (string) that uniquely identifies the webhooks being registered.
* The easiest approach is a hash of the concrete class
* Should return a version (string) that uniquely identifies the webhooks being registered.
*/
public function getHash(): string;
public function getVersion(): string;
}

0 comments on commit 5ee1611

Please sign in to comment.