Skip to content

Commit 2ddef40

Browse files
committed
Add addresses endpoints
1 parent 66f06b2 commit 2ddef40

File tree

7 files changed

+762
-3
lines changed

7 files changed

+762
-3
lines changed

config/admin/services.yml

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,22 @@ services:
4141
tags:
4242
- { name: 'serializer.normalizer', priority: 100 }
4343

44+
PrestaShop\Module\APIResources\ApiPlatform\Normalizer\CartAddressNormalizer:
45+
autowire: true
46+
public: false
47+
arguments:
48+
$decorated: '@serializer.normalizer.object'
49+
tags:
50+
- { name: 'serializer.normalizer', priority: 300 }
51+
52+
PrestaShop\Module\APIResources\ApiPlatform\Normalizer\OrderAddressNormalizer:
53+
autowire: true
54+
public: false
55+
arguments:
56+
$decorated: '@serializer.normalizer.object'
57+
tags:
58+
- { name: 'serializer.normalizer', priority: 300 }
59+
4460
PrestaShopBundle\ApiPlatform\Serializer\CQRSApiSerializer:
4561
class: PrestaShop\Module\APIResources\Serializer\QueryParameterTypeCastSerializer
4662
decorates: 'api_platform.serializer'
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
/**
3+
* Copyright since 2007 PrestaShop SA and Contributors
4+
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
5+
*
6+
* NOTICE OF LICENSE
7+
*
8+
* This source file is subject to the Academic Free License version 3.0
9+
* that is bundled with this package in the file LICENSE.md.
10+
* It is also available through the world-wide-web at this URL:
11+
* https://opensource.org/licenses/AFL-3.0
12+
* If you did not receive a copy of the license and are unable to
13+
* obtain it through the world-wide-web, please send an email
14+
* to [email protected] so we can send you a copy immediately.
15+
*
16+
* @author PrestaShop SA and Contributors <[email protected]>
17+
* @copyright Since 2007 PrestaShop SA and Contributors
18+
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
19+
*/
20+
21+
namespace PrestaShop\Module\APIResources\ApiPlatform\Normalizer;
22+
23+
use PrestaShop\Module\APIResources\ApiPlatform\Resources\Address\CartAddress;
24+
use Symfony\Component\HttpFoundation\RequestStack;
25+
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
26+
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
27+
28+
class CartAddressNormalizer implements ContextAwareNormalizerInterface
29+
{
30+
private const NORMALIZED_FLAG = 'cart_address_normalized';
31+
32+
public function __construct(
33+
private readonly NormalizerInterface $decorated,
34+
private readonly RequestStack $requestStack,
35+
) {
36+
}
37+
38+
public function supportsNormalization(mixed $data, ?string $format = null, array $context = []): bool
39+
{
40+
if (!($data instanceof CartAddress)) {
41+
return false;
42+
}
43+
44+
return empty($context[self::NORMALIZED_FLAG]);
45+
}
46+
47+
public function normalize(mixed $object, ?string $format = null, array $context = []): mixed
48+
{
49+
if ($object instanceof CartAddress) {
50+
$request = $this->requestStack->getCurrentRequest();
51+
if (null !== $request) {
52+
$cartId = (int) $request->attributes->get('cartId', 0);
53+
if ($cartId > 0) {
54+
$object->cartId = $cartId;
55+
}
56+
}
57+
}
58+
59+
$context[self::NORMALIZED_FLAG] = true;
60+
61+
return $this->decorated->normalize($object, $format, $context);
62+
}
63+
}
Lines changed: 63 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
<?php
2+
/**
3+
* Copyright since 2007 PrestaShop SA and Contributors
4+
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
5+
*
6+
* NOTICE OF LICENSE
7+
*
8+
* This source file is subject to the Academic Free License version 3.0
9+
* that is bundled with this package in the file LICENSE.md.
10+
* It is also available through the world-wide-web at this URL:
11+
* https://opensource.org/licenses/AFL-3.0
12+
* If you did not receive a copy of the license and are unable to
13+
* obtain it through the world-wide-web, please send an email
14+
* to [email protected] so we can send you a copy immediately.
15+
*
16+
* @author PrestaShop SA and Contributors <[email protected]>
17+
* @copyright Since 2007 PrestaShop SA and Contributors
18+
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
19+
*/
20+
21+
namespace PrestaShop\Module\APIResources\ApiPlatform\Normalizer;
22+
23+
use PrestaShop\Module\APIResources\ApiPlatform\Resources\Address\OrderAddress;
24+
use Symfony\Component\HttpFoundation\RequestStack;
25+
use Symfony\Component\Serializer\Normalizer\ContextAwareNormalizerInterface;
26+
use Symfony\Component\Serializer\Normalizer\NormalizerInterface;
27+
28+
class OrderAddressNormalizer implements ContextAwareNormalizerInterface
29+
{
30+
private const NORMALIZED_FLAG = 'order_address_normalized';
31+
32+
public function __construct(
33+
private readonly NormalizerInterface $decorated,
34+
private readonly RequestStack $requestStack,
35+
) {
36+
}
37+
38+
public function supportsNormalization(mixed $data, ?string $format = null, array $context = []): bool
39+
{
40+
if (!($data instanceof OrderAddress)) {
41+
return false;
42+
}
43+
44+
return empty($context[self::NORMALIZED_FLAG]);
45+
}
46+
47+
public function normalize(mixed $object, ?string $format = null, array $context = []): mixed
48+
{
49+
if ($object instanceof OrderAddress) {
50+
$request = $this->requestStack->getCurrentRequest();
51+
if (null !== $request) {
52+
$orderId = (int) $request->attributes->get('orderId', 0);
53+
if ($orderId > 0) {
54+
$object->orderId = $orderId;
55+
}
56+
}
57+
}
58+
59+
$context[self::NORMALIZED_FLAG] = true;
60+
61+
return $this->decorated->normalize($object, $format, $context);
62+
}
63+
}
Lines changed: 131 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,131 @@
1+
<?php
2+
/**
3+
* Copyright since 2007 PrestaShop SA and Contributors
4+
* PrestaShop is an International Registered Trademark & Property of PrestaShop SA
5+
*
6+
* NOTICE OF LICENSE
7+
*
8+
* This source file is subject to the Academic Free License version 3.0
9+
* that is bundled with this package in the file LICENSE.md.
10+
* It is also available through the world-wide-web at this URL:
11+
* https://opensource.org/licenses/AFL-3.0
12+
* If you did not receive a copy of the license and are unable to
13+
* obtain it through the world-wide-web, please send an email
14+
* to [email protected] so we can send you a copy immediately.
15+
*
16+
* @author PrestaShop SA and Contributors <[email protected]>
17+
* @copyright Since 2007 PrestaShop SA and Contributors
18+
* @license https://opensource.org/licenses/AFL-3.0 Academic Free License version 3.0
19+
*/
20+
21+
namespace PrestaShop\Module\APIResources\ApiPlatform\Resources\Address;
22+
23+
use ApiPlatform\Metadata\ApiProperty;
24+
use ApiPlatform\Metadata\ApiResource;
25+
use PrestaShop\PrestaShop\Core\ConstraintValidator\Constraints\TypedRegex;
26+
use PrestaShop\PrestaShop\Core\Domain\Address\Command\EditCartAddressCommand;
27+
use PrestaShop\PrestaShop\Core\Domain\Address\Exception\AddressConstraintException;
28+
use PrestaShop\PrestaShop\Core\Domain\Address\Query\GetCustomerAddressForEditing;
29+
use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\CartNotFoundException;
30+
use PrestaShop\PrestaShop\Core\Domain\Cart\Exception\InvalidAddressTypeException;
31+
use PrestaShop\PrestaShop\Core\Domain\Country\Exception\CountryConstraintException;
32+
use PrestaShop\PrestaShop\Core\Domain\Country\ValueObject\CountryId;
33+
use PrestaShop\PrestaShop\Core\Domain\State\Exception\StateConstraintException;
34+
use PrestaShop\PrestaShop\Core\Domain\State\ValueObject\StateIdInterface;
35+
use PrestaShopBundle\ApiPlatform\Metadata\CQRSPartialUpdate;
36+
use Symfony\Component\HttpFoundation\Response;
37+
38+
#[ApiResource(
39+
operations: [
40+
new CQRSPartialUpdate(
41+
uriTemplate: '/addresses/carts/{cartId}',
42+
CQRSCommand: EditCartAddressCommand::class,
43+
CQRSQuery: GetCustomerAddressForEditing::class,
44+
scopes: [
45+
'address_write',
46+
],
47+
CQRSQueryMapping: self::QUERY_MAPPING,
48+
CQRSCommandMapping: self::COMMAND_MAPPING,
49+
validationContext: ['groups' => ['Default', 'Update']],
50+
),
51+
],
52+
exceptionToStatus: [
53+
AddressConstraintException::class => Response::HTTP_UNPROCESSABLE_ENTITY,
54+
CountryConstraintException::class => Response::HTTP_UNPROCESSABLE_ENTITY,
55+
StateConstraintException::class => Response::HTTP_UNPROCESSABLE_ENTITY,
56+
InvalidAddressTypeException::class => Response::HTTP_UNPROCESSABLE_ENTITY,
57+
CartNotFoundException::class => Response::HTTP_NOT_FOUND,
58+
],
59+
)]
60+
class CartAddress
61+
{
62+
// Identifiers from URI
63+
#[ApiProperty(identifier: true)]
64+
public int $cartId = 0;
65+
66+
public string $addressType;
67+
68+
// Optional address fields for update
69+
public ?string $addressAlias = null;
70+
71+
public ?string $firstName = null;
72+
73+
public ?string $lastName = null;
74+
75+
#[TypedRegex([
76+
'type' => TypedRegex::TYPE_ADDRESS,
77+
])]
78+
public ?string $address = null;
79+
80+
#[TypedRegex([
81+
'type' => TypedRegex::TYPE_ADDRESS,
82+
])]
83+
public ?string $address2 = null;
84+
85+
#[TypedRegex([
86+
'type' => TypedRegex::TYPE_CITY_NAME,
87+
])]
88+
public ?string $city = null;
89+
90+
#[TypedRegex([
91+
'type' => TypedRegex::TYPE_POST_CODE,
92+
])]
93+
public ?string $postCode = null;
94+
95+
public ?CountryId $countryId = null;
96+
97+
public ?StateIdInterface $stateId = null;
98+
99+
#[TypedRegex([
100+
'type' => TypedRegex::TYPE_PHONE_NUMBER,
101+
])]
102+
public ?string $homePhone = null;
103+
104+
#[TypedRegex([
105+
'type' => TypedRegex::TYPE_PHONE_NUMBER,
106+
])]
107+
public ?string $mobilePhone = null;
108+
109+
public ?string $company = null;
110+
111+
public ?string $vatNumber = null;
112+
113+
public ?string $other = null;
114+
115+
#[TypedRegex([
116+
'type' => TypedRegex::TYPE_DNI_LITE,
117+
])]
118+
public ?string $dni = null;
119+
120+
public const QUERY_MAPPING = [
121+
'[id]' => '[addressId]',
122+
];
123+
124+
public const COMMAND_MAPPING = [
125+
'[postCode]' => '[postcode]',
126+
'[homePhone]' => '[phone]',
127+
'[mobilePhone]' => '[phone_mobile]',
128+
'[vatNumber]' => '[vat_number]',
129+
'[stateId]' => '[id_state]',
130+
];
131+
}

0 commit comments

Comments
 (0)