Skip to content

Commit 544c3b4

Browse files
authored
Merge pull request #2 from picqer/fix-config-on-specific-sales-channel
Haal webhook instellingen bij bijbehorend verkoopkanaal op
2 parents 5247d96 + 7f1b73e commit 544c3b4

File tree

9 files changed

+168
-42
lines changed

9 files changed

+168
-42
lines changed

README.md

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,6 +16,8 @@ This project can easily be installed through Composer.
1616
3. Fill out the general configuration information:
1717
+ Subdomain: is the prefix of your domain name. If your log on to 'my-shop.picqer.com', then fill in 'my-shop'.
1818
+ Connection Key: can be found in Picqer > Settings > Webshops > Shopware shop. Copy and paste this field.
19+
+ Disable sending webhooks for this sales channel
20+
+ Enable debug logging: Only enable when the plugin is not working, this will log errors in the communication with Picqer.
1921

2022
Orders will now be pushed to Picqer immediately.
2123

composer.json

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@
2020
],
2121
"require": {
2222
"php": ">=7.4",
23-
"shopware/core": "6.4.*",
23+
"shopware/core": "^6.4",
2424
"ext-curl": "*",
2525
"ext-json": "*"
2626
},

src/Client/CurlPicqerClient.php

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -6,7 +6,7 @@
66

77
final class CurlPicqerClient implements PicqerClient
88
{
9-
const USER_AGENT = 'Picqer Shopware 6 Plugin (version 1.0.0)';
9+
const USER_AGENT = 'Picqer Shopware 6 Plugin (version 1.1.0)';
1010

1111
public function pushOrder(string $subdomain, string $connectionKey, string $id): void
1212
{
@@ -16,13 +16,13 @@ public function pushOrder(string $subdomain, string $connectionKey, string $id):
1616
);
1717
}
1818

19-
private function post(string $url, array $body): void
19+
private function post(string $endpoint, array $body): void
2020
{
2121
$session = curl_init();
2222

2323
curl_setopt($session, CURLOPT_USERAGENT, self::USER_AGENT);
2424

25-
curl_setopt($session, CURLOPT_URL, $url);
25+
curl_setopt($session, CURLOPT_URL, $endpoint);
2626
curl_setopt($session, CURLOPT_HTTPHEADER, [
2727
'Content-Type: application/json',
2828
'Accept: application/json'
@@ -42,7 +42,7 @@ private function post(string $url, array $body): void
4242
curl_close($session);
4343

4444
if ($errorNo) {
45-
throw new RequestFailedException($errorMessage);
45+
throw new RequestFailedException($endpoint, $errorMessage);
4646
}
4747
}
4848
}
Lines changed: 36 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,36 @@
1+
<?php
2+
3+
namespace Picqer\Shopware6Plugin\Exception;
4+
5+
use Exception;
6+
7+
class IncompleteConfigurationException extends Exception
8+
{
9+
/**
10+
* @var string|null
11+
*/
12+
private $subdomain;
13+
14+
/**
15+
* @var string|null
16+
*/
17+
private $connectionKey;
18+
19+
public function __construct(
20+
string $subdomain = null,
21+
string $connectionKey = null
22+
) {
23+
$this->subdomain = $subdomain;
24+
$this->connectionKey = $connectionKey;
25+
}
26+
27+
public function getSubdomain()
28+
{
29+
return $this->subdomain;
30+
}
31+
32+
public function getConnectionKey()
33+
{
34+
return $this->connectionKey;
35+
}
36+
}

src/Exception/InvalidConfigException.php renamed to src/Exception/OrderNotFoundException.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,7 @@
44

55
use Exception;
66

7-
class InvalidConfigException extends Exception
7+
final class OrderNotFoundException extends Exception
88
{
99

1010
}

src/Exception/RequestFailedException.php

Lines changed: 17 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -6,5 +6,22 @@
66

77
class RequestFailedException extends Exception
88
{
9+
/**
10+
* @var string
11+
*/
12+
private $endpoint;
913

14+
public function __construct(
15+
string $endpoint,
16+
string $message
17+
) {
18+
$this->endpoint = $endpoint;
19+
20+
parent::__construct($message);
21+
}
22+
23+
public function getEndpoint(): string
24+
{
25+
return $this->endpoint;
26+
}
1027
}

src/Resources/config/config.xml

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,8 +9,16 @@
99
<label>Subdomain</label>
1010
</input-field>
1111
<input-field>
12-
<name >connectionkey</name>
12+
<name>connectionkey</name>
1313
<label>Connection Key</label>
1414
</input-field>
15+
<input-field type="bool">
16+
<name>disabled</name>
17+
<label>Disable sending webhooks for this sales channel</label>
18+
</input-field>
19+
<input-field type="bool">
20+
<name>debug</name>
21+
<label>Enable debug logging</label>
22+
</input-field>
1523
</card>
1624
</config>

src/Resources/config/services.xml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
<service id="Picqer\Shopware6Plugin\Subscriber\EventSubscriber">
1111
<argument type="service" id="Shopware\Core\System\SystemConfig\SystemConfigService" />
1212
<argument type="service" id="Picqer\Shopware6Plugin\Client\CurlPicqerClient" />
13+
<argument type="service" id="order.repository" />
1314
<argument type="service" id="logger" />
1415
<tag name="kernel.event_subscriber"/>
1516
</service>

src/Subscriber/EventSubscriber.php

Lines changed: 97 additions & 35 deletions
Original file line numberDiff line numberDiff line change
@@ -2,77 +2,139 @@
22

33
namespace Picqer\Shopware6Plugin\Subscriber;
44

5+
use Exception;
56
use Picqer\Shopware6Plugin\Client\PicqerClient;
6-
use Picqer\Shopware6Plugin\Exception\InvalidConfigException;
7+
use Picqer\Shopware6Plugin\Exception\IncompleteConfigurationException;
8+
use Picqer\Shopware6Plugin\Exception\OrderNotFoundException;
79
use Picqer\Shopware6Plugin\Exception\RequestFailedException;
810
use Psr\Log\LoggerInterface;
11+
use Shopware\Core\Checkout\Order\OrderEntity;
912
use Shopware\Core\Checkout\Order\OrderEvents;
13+
use Shopware\Core\Framework\DataAbstractionLayer\EntityRepository;
1014
use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityWrittenEvent;
15+
use Shopware\Core\Framework\DataAbstractionLayer\Search\Criteria;
1116
use Shopware\Core\System\SystemConfig\SystemConfigService;
1217
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
1318

1419
final class EventSubscriber implements EventSubscriberInterface
1520
{
21+
/**
22+
* @var SystemConfigService
23+
*/
1624
private $configService;
25+
26+
/**
27+
* @var PicqerClient
28+
*/
1729
private $client;
30+
31+
/**
32+
* @var EntityRepository
33+
*/
34+
private $orderRepository;
35+
36+
/**
37+
* @var LoggerInterface
38+
*/
1839
private $logger;
1940

20-
public function __construct(SystemConfigService $configService, PicqerClient $client, LoggerInterface $logger)
21-
{
22-
$this->client = $client;
41+
public function __construct(
42+
SystemConfigService $configService,
43+
PicqerClient $client,
44+
EntityRepository $orderRepository,
45+
LoggerInterface $logger
46+
) {
2347
$this->configService = $configService;
48+
$this->client = $client;
49+
$this->orderRepository = $orderRepository;
2450
$this->logger = $logger;
2551
}
2652

2753
public static function getSubscribedEvents(): array
2854
{
2955
return [
30-
OrderEvents::ORDER_WRITTEN_EVENT => 'pushOrder',
56+
OrderEvents::ORDER_WRITTEN_EVENT => 'handle',
3157
];
3258
}
3359

34-
public function pushOrder(EntityWrittenEvent $event): void
60+
public function handle(EntityWrittenEvent $event): void
3561
{
36-
if (!isset($event->getIds()[0])) {
62+
if (! isset($event->getIds()[0])) {
3763
return;
3864
}
3965

40-
$id = $event->getIds()[0];
66+
$orderId = $event->getIds()[0];
4167

4268
try {
43-
$this->client->pushOrder(
44-
$this->getConfigurationValue('subdomain'),
45-
$this->getConfigurationValue('connectionkey'),
46-
$id
47-
);
48-
} catch (InvalidConfigException $e) {
49-
/*
50-
* It is possible that the configuration values are not yet set
51-
* due to the fact that a plugin needs to be installed and activated before you can configure these.
52-
*
53-
* Picqer will check the webshop on interval as well.
54-
* When a call fails there might be a delay in orders showing up in Picqer, but they will not get lost.
55-
*
56-
* We choose to silently fail to prevent any disturbances of the webshop.
57-
*/
58-
59-
$this->logger->info('[Picqer] Plugin configuration is invalid', [
60-
'message' => $e->getMessage(),
61-
]);
62-
} catch(RequestFailedException $e) {
63-
$this->logger->info('[Picqer] Could not call webhook', [
69+
$order = $this->orderRepository->search(new Criteria([$orderId]), $event->getContext())->first();
70+
if (! $order instanceof OrderEntity) {
71+
throw new OrderNotFoundException(sprintf('Order [%s] not found', $orderId));
72+
}
73+
74+
$salesChannelId = $order->getSalesChannelId();
75+
$disabled = $this->configService->getBool($this->buildConfigKey('disabled'), $salesChannelId);
76+
if ($disabled) {
77+
return;
78+
}
79+
80+
$subdomain = $this->configService->getString($this->buildConfigKey('subdomain'), $salesChannelId);
81+
$connectionKey = $this->configService->getString($this->buildConfigKey('connectionkey'), $salesChannelId);
82+
$debug = $this->configService->getBool($this->buildConfigKey('debug'), $salesChannelId);
83+
84+
$this->pushOrderToPicqer($subdomain, $connectionKey, $order, $debug, $salesChannelId);
85+
} catch (Exception $e) {
86+
$this->logger->error('[Picqer] Caught unexpected exception', [
87+
'exception' => get_class($e),
6488
'message' => $e->getMessage(),
89+
'orderId' => $orderId,
6590
]);
6691
}
6792
}
6893

69-
private function getConfigurationValue(string $type): string
94+
private function buildConfigKey(string $key): string
7095
{
71-
$value = $this->configService->get(sprintf('PicqerExtendedIntegration.config.%s', $type));
72-
if (!is_string($value)) {
73-
throw new InvalidConfigException(sprintf('%s not set', ucfirst($type)));
74-
}
96+
return sprintf('PicqerExtendedIntegration.config.%s', $key);
97+
}
98+
99+
private function pushOrderToPicqer(
100+
string $subdomain,
101+
string $connectionKey,
102+
OrderEntity $order,
103+
bool $debug,
104+
string $salesChannelId
105+
): void {
106+
try {
107+
if (empty($subdomain) || empty($connectionKey)) {
108+
throw new IncompleteConfigurationException($subdomain, $connectionKey);
109+
}
110+
111+
$this->client->pushOrder(
112+
$subdomain,
113+
$connectionKey,
114+
$order->getId()
115+
);
116+
} catch (IncompleteConfigurationException $e) {
117+
if (! $debug) {
118+
return;
119+
}
120+
121+
$this->logger->error('[Picqer] Subdomain and/or connection-key not configured', [
122+
'subdomain' => $e->getSubdomain(),
123+
'connectionKey' => $e->getConnectionKey(),
124+
'orderId' => $order->getId(),
125+
'salesChannelId' => $salesChannelId,
126+
]);
127+
} catch (RequestFailedException $e) {
128+
if (! $debug) {
129+
return;
130+
}
75131

76-
return $value;
132+
$this->logger->error('[Picqer] Could not call webhook', [
133+
'endpoint' => $e->getEndpoint(),
134+
'message' => $e->getMessage(),
135+
'orderId' => $order->getId(),
136+
'salesChannelId' => $salesChannelId,
137+
]);
138+
}
77139
}
78140
}

0 commit comments

Comments
 (0)