Skip to content

Commit edf63ff

Browse files
authored
[UC-4] Call User.com after form submission (#3)
* [UC-4] Extend customer model * [UC-4] Remove unnecessarily extended customer * [UC-4] Add User.com API front config * [UC-4] Add updaters logic * Add event subscriber and manager to init update & add missing events entry * Add user type extension * [UC-4] Fix code style * [UC-4] Add changes requested on CR
1 parent d85fa0b commit edf63ff

24 files changed

Lines changed: 802 additions & 3 deletions

config/services/builder.xml

Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
3+
<container xmlns="http://symfony.com/schema/dic/services" 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">
4+
<services>
5+
<defaults autowire="false" autoconfigure="false"/>
6+
<service
7+
id="bit_bag.sylius_user_com_plugin.builder.payload.customer_payload_builder"
8+
class="BitBag\SyliusUserComPlugin\Builder\Payload\CustomerPayloadBuilder"
9+
>
10+
</service>
11+
</services>
12+
</container>
Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
3+
<container xmlns="http://symfony.com/schema/dic/services" 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">
4+
<services>
5+
<defaults autowire="false" autoconfigure="false"/>
6+
<service
7+
id="bit_bag.sylius_user_com_plugin.event_subscriber.customer_profile_updated_subscriber"
8+
class="BitBag\SyliusUserComPlugin\EventSubscriber\CustomerProfileUpdatedSubscriber"
9+
>
10+
<argument type="service" id="bit_bag.sylius_user_com_plugin.manager.customer_update_manager"/>
11+
</service>
12+
</services>
13+
</container>

config/services/form.xml

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
<?xml version="1.0" encoding="UTF-8"?>
2+
<container xmlns="http://symfony.com/schema/dic/services" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
3+
xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd"
4+
>
5+
<services>
6+
<defaults public="true"/>
7+
<service id="bit_bag.sylius_user_com_plugin.form.extension.user_com_customer_information_type_extension" class="BitBag\SyliusUserComPlugin\Form\Extension\UserComCustomerInformationTypeExtension">
8+
<argument type="service" id="bit_bag.sylius_user_com_plugin.event_subscriber.customer_profile_updated_subscriber"/>
9+
<argument type="service" id="sylius.context.customer"/>
10+
<tag name="form.type_extension" />
11+
</service>
12+
</services>
13+
</container>

config/services/manager.xml

Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
3+
<container xmlns="http://symfony.com/schema/dic/services" 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">
4+
<services>
5+
<defaults autowire="false" autoconfigure="false"/>
6+
<service
7+
id="bit_bag.sylius_user_com_plugin.manager.cookie_manager"
8+
class="BitBag\SyliusUserComPlugin\Manager\CookieManager"
9+
>
10+
<argument type="service" id="request_stack"/>
11+
</service>
12+
13+
<service
14+
id="bit_bag.sylius_user_com_plugin.manager.customer_update_manager"
15+
class="BitBag\SyliusUserComPlugin\Manager\CustomerUpdateManager"
16+
>
17+
<argument type="service" id="bit_bag.sylius_user_com_plugin.manager.cookie_manager"/>
18+
<argument type="service" id="bit_bag.sylius_user_com_plugin.updater.customer_with_key_updater"/>
19+
<argument type="service" id="bit_bag.sylius_user_com_plugin.updater.customer_without_key_updater"/>
20+
</service>
21+
</services>
22+
</container>

config/services/updater.xml

Lines changed: 26 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,26 @@
1+
<?xml version="1.0" encoding="UTF-8" ?>
2+
3+
<container xmlns="http://symfony.com/schema/dic/services" 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">
4+
<services>
5+
<defaults autowire="false" autoconfigure="false"/>
6+
<service
7+
id="bit_bag.sylius_user_com_plugin.updater.customer_without_key_updater"
8+
class="BitBag\SyliusUserComPlugin\Updater\CustomerWithoutKeyUpdater"
9+
>
10+
<argument type="service" id="bit_bag.sylius_user_com_plugin.builder.payload.customer_payload_builder"/>
11+
<argument type="service" id="sylius.context.channel.composite"/>
12+
<argument type="service" id="bit_bag.sylius_user_com_plugin.api.user_api"/>
13+
<argument type="service" id="bit_bag.sylius_user_com_plugin.manager.cookie_manager"/>
14+
</service>
15+
16+
<service
17+
id="bit_bag.sylius_user_com_plugin.updater.customer_with_key_updater"
18+
class="BitBag\SyliusUserComPlugin\Updater\CustomerWithKeyUpdater"
19+
>
20+
<argument type="service" id="bit_bag.sylius_user_com_plugin.builder.payload.customer_payload_builder"/>
21+
<argument type="service" id="sylius.context.channel.composite"/>
22+
<argument type="service" id="bit_bag.sylius_user_com_plugin.api.user_api"/>
23+
<argument type="service" id="bit_bag.sylius_user_com_plugin.manager.cookie_manager"/>
24+
</service>
25+
</services>
26+
</container>

src/Api/UserApi.php

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -113,10 +113,10 @@ public function updateUserByCustomId(UserComApiAwareInterface $resource, string
113113
);
114114
}
115115

116-
public function createEventForUser(UserComApiAwareInterface $resource, array $data): ?array
116+
public function createEventForUser(UserComApiAwareInterface $resource, string $userCustomId, array $data): ?array
117117
{
118118
return $this->request(
119-
$this->getApiEndpointUrl($resource, self::CREATE_EVENT_FOR_USER_BY_CUSTOM_ID_ENDPOINT),
119+
$this->getApiEndpointUrl($resource, sprintf(self::CREATE_EVENT_FOR_USER_BY_CUSTOM_ID_ENDPOINT, $userCustomId)),
120120
Request::METHOD_POST,
121121
$this->buildOptions($resource, [
122122
'json' => $data,

src/Api/UserApiInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -51,5 +51,5 @@ public function mergeUsers(UserComApiAwareInterface $resource, int $parentId, ar
5151

5252
public function updateUserByCustomId(UserComApiAwareInterface $resource, string $customId, array $data): ?array;
5353

54-
public function createEventForUser(UserComApiAwareInterface $resource, array $data): ?array;
54+
public function createEventForUser(UserComApiAwareInterface $resource, string $userCustomId, array $data): ?array;
5555
}
Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
<?php
2+
3+
/*
4+
* This file has been created by developers from BitBag.
5+
* Feel free to contact us once you face any issues or want to start
6+
* You can find more information about us on https://bitbag.io and write us
7+
* an email on hello@bitbag.io.
8+
*/
9+
10+
declare(strict_types=1);
11+
12+
namespace BitBag\SyliusUserComPlugin\Builder\Payload;
13+
14+
use Sylius\Component\Core\Model\AddressInterface;
15+
use Sylius\Component\Core\Model\CustomerInterface;
16+
17+
final class CustomerPayloadBuilder implements CustomerPayloadBuilderInterface
18+
{
19+
public function build(string $email, ?CustomerInterface $customer = null, ?AddressInterface $address = null): array
20+
{
21+
if (null !== $customer && null === $address) {
22+
$address = $customer->getDefaultAddress();
23+
}
24+
25+
$payload = [
26+
'custom_id' => $customer?->getEmail() ?? $email,
27+
'email' => $customer?->getEmail() ?? $email,
28+
'firstName' => $customer?->getFirstName(),
29+
'lastName' => $customer?->getLastName(),
30+
'phone_number' => $customer?->getPhoneNumber(),
31+
'country' => $address?->getCountryCode(),
32+
'region' => $address?->getProvinceCode(),
33+
'city' => $address?->getCity(),
34+
'gender' => null !== $customer ? self::GENDER_MAP[$customer->getGender()] : null,
35+
'status' => null !== $customer ? self::STATUS_USER : self::STATUS_VISITOR,
36+
'unsubscribed' => null !== $customer ? !$customer->isSubscribedToNewsletter() : null,
37+
];
38+
39+
return array_filter($payload, fn ($value) => null !== $value);
40+
}
41+
}
Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
<?php
2+
3+
/*
4+
* This file has been created by developers from BitBag.
5+
* Feel free to contact us once you face any issues or want to start
6+
* You can find more information about us on https://bitbag.io and write us
7+
* an email on hello@bitbag.io.
8+
*/
9+
10+
declare(strict_types=1);
11+
12+
namespace BitBag\SyliusUserComPlugin\Builder\Payload;
13+
14+
use Sylius\Component\Core\Model\AddressInterface;
15+
use Sylius\Component\Core\Model\CustomerInterface;
16+
17+
interface CustomerPayloadBuilderInterface
18+
{
19+
public const GENDER_MAP = [
20+
CustomerInterface::FEMALE_GENDER => 3,
21+
CustomerInterface::MALE_GENDER => 2,
22+
CustomerInterface::UNKNOWN_GENDER => 1,
23+
];
24+
25+
public const STATUS_USER = 2;
26+
27+
public const STATUS_VISITOR = 1;
28+
29+
public function build(string $email, ?CustomerInterface $customer = null, ?AddressInterface $address = null): array;
30+
}
Lines changed: 71 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,71 @@
1+
<?php
2+
3+
/*
4+
* This file has been created by developers from BitBag.
5+
* Feel free to contact us once you face any issues or want to start
6+
* You can find more information about us on https://bitbag.io and write us
7+
* an email on hello@bitbag.io.
8+
*/
9+
10+
declare(strict_types=1);
11+
12+
namespace BitBag\SyliusUserComPlugin\EventSubscriber;
13+
14+
use BitBag\SyliusUserComPlugin\Manager\CustomerUpdateManagerInterface;
15+
use Sylius\Component\Core\Model\CustomerInterface;
16+
use Sylius\Component\Core\Model\OrderInterface;
17+
use Symfony\Component\Form\FormEvent;
18+
use Symfony\Component\Form\FormEvents;
19+
20+
final class CustomerProfileUpdatedSubscriber implements CustomerProfileUpdatedSubscriberInterface
21+
{
22+
private const EVENTS = [
23+
FormEvents::POST_SUBMIT => 'postCustomerProfileUpdated',
24+
];
25+
26+
public function __construct(
27+
private readonly CustomerUpdateManagerInterface $customerUpdateManager,
28+
) {
29+
}
30+
31+
public function postCustomerProfileUpdated(FormEvent $event): void
32+
{
33+
$formName = $event->getForm()->getName();
34+
35+
$eventName = array_key_exists($formName, self::FORM_NAME_TO_EVENT_MAP)
36+
? self::FORM_NAME_TO_EVENT_MAP[$formName]
37+
: self::DEFAULT_EVENT
38+
;
39+
40+
$subject = $event->getData();
41+
42+
if ($subject instanceof CustomerInterface) {
43+
$this->customerUpdateManager->manageChange(
44+
$eventName,
45+
$subject,
46+
$subject->getDefaultAddress(),
47+
$subject->getEmail(),
48+
);
49+
50+
return;
51+
}
52+
53+
if ($subject instanceof OrderInterface) {
54+
$customer = $subject->getCustomer();
55+
if (null !== $customer && !$customer instanceof CustomerInterface) {
56+
throw new \RuntimeException('Customer is not set or is not an instance of CustomerInterface');
57+
}
58+
$this->customerUpdateManager->manageChange(
59+
$eventName,
60+
$customer,
61+
$subject->getShippingAddress(),
62+
$customer?->getEmail(),
63+
);
64+
}
65+
}
66+
67+
public static function getSubscribedEvents(): array
68+
{
69+
return self::EVENTS;
70+
}
71+
}

0 commit comments

Comments
 (0)