mirror of
https://github.com/Sylius/Sylius.git
synced 2026-07-05 20:57:12 +00:00
Merge 22db3e1df1 into 9b6799e2b8
This commit is contained in:
commit
503aeb590e
15 changed files with 93 additions and 31 deletions
63
UPGRADE-API-2.3.md
Normal file
63
UPGRADE-API-2.3.md
Normal file
|
|
@ -0,0 +1,63 @@
|
|||
# UPGRADE FROM `2.2` TO `2.3`
|
||||
|
||||
## DateTime Serialization Format
|
||||
|
||||
The `sylius_api.normalizer.date_time` service has been removed. Previously, Sylius registered a custom
|
||||
`DateTimeNormalizer` that overrode Symfony's built-in normalizer globally, forcing the `Y-m-d H:i:s` format
|
||||
on all `DateTime` fields across the entire API.
|
||||
|
||||
All `DateTime` fields are now serialized using Symfony's default `DateTimeNormalizer`, which produces
|
||||
the RFC 3339 format (`Y-m-d\TH:i:sP`).
|
||||
|
||||
**Before:**
|
||||
```json
|
||||
{
|
||||
"startDate": "2022-01-01 00:00:00",
|
||||
"endDate": "2022-01-02 00:00:00",
|
||||
"birthday": "2023-10-24 11:00:00",
|
||||
"expiresAt": "2020-01-01 12:00:00"
|
||||
}
|
||||
```
|
||||
|
||||
**After:**
|
||||
```json
|
||||
{
|
||||
"startDate": "2022-01-01T00:00:00+00:00",
|
||||
"endDate": "2022-01-02T00:00:00+00:00",
|
||||
"birthday": "2023-10-24T11:00:00+00:00",
|
||||
"expiresAt": "2020-01-01T12:00:00+00:00"
|
||||
}
|
||||
```
|
||||
|
||||
**Affected fields (non-exhaustive):** `startDate`, `endDate`, `startsAt`, `endsAt`, `expiresAt`, `birthday`,
|
||||
`createdAt`, `updatedAt`, `archivedAt` and any other `DateTime` field exposed via the API.
|
||||
|
||||
**Migration guide:**
|
||||
|
||||
If your API client depends on the old `Y-m-d H:i:s` format, update it to parse RFC 3339 dates instead.
|
||||
RFC 3339 is the standard format for REST APIs and is natively supported by all modern date libraries.
|
||||
|
||||
If you need to restore the old format or apply a custom one globally, register your own `DateTimeNormalizer`
|
||||
with a higher priority than Symfony's default (`-910`):
|
||||
|
||||
```php
|
||||
// config/services.php
|
||||
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
|
||||
|
||||
$services
|
||||
->set('app.normalizer.date_time', DateTimeNormalizer::class)
|
||||
->args([['datetime_format' => 'Y-m-d H:i:s']])
|
||||
->tag('serializer.normalizer', ['priority' => 1])
|
||||
;
|
||||
```
|
||||
|
||||
Alternatively, you may set the format for a specific field only by adding a serialization context
|
||||
to the attribute definition in your serialization XML:
|
||||
|
||||
```xml
|
||||
<attribute name="startDate">
|
||||
<context>
|
||||
<entry name="datetime_format">Y-m-d</entry>
|
||||
</context>
|
||||
</attribute>
|
||||
```
|
||||
|
|
@ -860,7 +860,11 @@ final readonly class ManagingCatalogPromotionsContext implements Context
|
|||
Assert::true(
|
||||
$this->responseChecker->hasItemWithValues(
|
||||
$response,
|
||||
['name' => $catalogPromotion->getName(), 'startDate' => $startDate . ':00', 'endDate' => $endDate . ':00'],
|
||||
[
|
||||
'name' => $catalogPromotion->getName(),
|
||||
'startDate' => (new \DateTime($startDate))->format(\DateTimeInterface::RFC3339),
|
||||
'endDate' => (new \DateTime($endDate))->format(\DateTimeInterface::RFC3339),
|
||||
],
|
||||
),
|
||||
sprintf(
|
||||
'Cannot find catalog promotions with name "%s" operating between "%s" and "%s" in the list',
|
||||
|
|
@ -902,15 +906,15 @@ final readonly class ManagingCatalogPromotionsContext implements Context
|
|||
$response,
|
||||
[
|
||||
'name' => $catalogPromotion->getName(),
|
||||
'startDate' => (new \DateTime('yesterday'))->format('Y-m-d H:i:s'),
|
||||
'endDate' => (new \DateTime('tomorrow'))->format('Y-m-d H:i:s'),
|
||||
'startDate' => (new \DateTime('yesterday'))->format(\DateTimeInterface::RFC3339),
|
||||
'endDate' => (new \DateTime('tomorrow'))->format(\DateTimeInterface::RFC3339),
|
||||
],
|
||||
),
|
||||
sprintf(
|
||||
'Cannot find catalog promotions with name "%s" operating between "%s" and "%s" in the list',
|
||||
$catalogPromotion->getName(),
|
||||
(new \DateTime('yesterday'))->format('Y-m-d H:i:s'),
|
||||
(new \DateTime('tomorrow'))->format('Y-m-d H:i:s'),
|
||||
(new \DateTime('yesterday'))->format(\DateTimeInterface::RFC3339),
|
||||
(new \DateTime('tomorrow'))->format(\DateTimeInterface::RFC3339),
|
||||
),
|
||||
);
|
||||
}
|
||||
|
|
|
|||
|
|
@ -351,7 +351,10 @@ final class ManagingCustomersContext implements Context
|
|||
#[Then('he should be registered since :registrationDate')]
|
||||
public function hisRegistrationDateShouldBe(string $registrationDate): void
|
||||
{
|
||||
Assert::true($this->responseChecker->hasValue($this->client->getLastResponse(), 'createdAt', $registrationDate));
|
||||
Assert::same(
|
||||
(new \DateTime($this->responseChecker->getValue($this->client->getLastResponse(), 'createdAt')))->format(\DateTimeInterface::RFC3339),
|
||||
(new \DateTime($registrationDate))->format(\DateTimeInterface::RFC3339),
|
||||
);
|
||||
}
|
||||
|
||||
#[Then('their email should be :email')]
|
||||
|
|
|
|||
|
|
@ -755,7 +755,7 @@ final readonly class ManagingOrdersContext implements Context
|
|||
|
||||
Assert::same(
|
||||
$this->responseChecker->getValue($response, 'shippedAt'),
|
||||
(new \DateTime($dateTime))->format('Y-m-d H:i:s'),
|
||||
(new \DateTime($dateTime))->format(\DateTimeInterface::RFC3339),
|
||||
);
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -269,8 +269,7 @@ final readonly class ManagingPromotionCouponsContext implements Context
|
|||
#[Then('this coupon should be valid until :date')]
|
||||
public function thisCouponShouldBeValidUntil(\DateTime $date): void
|
||||
{
|
||||
$actualDate = \DateTime::createFromFormat(
|
||||
'Y-m-d h:i:s',
|
||||
$actualDate = new \DateTime(
|
||||
$this->responseChecker->getValue($this->client->getLastResponse(), 'expiresAt'),
|
||||
);
|
||||
|
||||
|
|
|
|||
|
|
@ -588,8 +588,8 @@ final readonly class ManagingPromotionsContext implements Context
|
|||
$this->client->index(Resources::PROMOTIONS),
|
||||
[
|
||||
'name' => $promotion->getName(),
|
||||
'startsAt' => $startsDate->format('Y-m-d H:i:s'),
|
||||
'endsAt' => $endsDate->format('Y-m-d H:i:s'),
|
||||
'startsAt' => $startsDate->format(\DateTimeInterface::RFC3339),
|
||||
'endsAt' => $endsDate->format(\DateTimeInterface::RFC3339),
|
||||
],
|
||||
),
|
||||
);
|
||||
|
|
|
|||
|
|
@ -36,7 +36,6 @@ use Sylius\Bundle\ApiBundle\Serializer\Normalizer\ProductOptionValueNormalizer;
|
|||
use Sylius\Bundle\ApiBundle\Serializer\Normalizer\ProductVariantNormalizer;
|
||||
use Sylius\Bundle\ApiBundle\Serializer\Normalizer\ShippingMethodNormalizer;
|
||||
use Symfony\Component\HttpFoundation\RequestStack;
|
||||
use Symfony\Component\Serializer\Normalizer\DateTimeNormalizer;
|
||||
|
||||
return static function (ContainerConfigurator $container) {
|
||||
$services = $container->services();
|
||||
|
|
@ -173,12 +172,6 @@ return static function (ContainerConfigurator $container) {
|
|||
->tag('serializer.normalizer', ['priority' => 64])
|
||||
;
|
||||
|
||||
$services
|
||||
->set('sylius_api.normalizer.date_time', DateTimeNormalizer::class)
|
||||
->args([['datetime_format' => 'Y-m-d H:i:s']])
|
||||
->tag('serializer.normalizer')
|
||||
;
|
||||
|
||||
$services
|
||||
->set('sylius_api.denormalizer.channel_price_history_config', ChannelPriceHistoryConfigDenormalizer::class)
|
||||
->args([
|
||||
|
|
|
|||
|
|
@ -5,8 +5,8 @@
|
|||
"id": "@integer@",
|
||||
"name": "T-Shirts discount",
|
||||
"code": "tshirts_discount",
|
||||
"startDate": "2022-01-01 00:00:00",
|
||||
"endDate": "2022-01-02 00:00:00",
|
||||
"startDate": "@date@",
|
||||
"endDate": "@date@",
|
||||
"priority": 100,
|
||||
"state": "@string@",
|
||||
"channels": [
|
||||
|
|
|
|||
|
|
@ -8,7 +8,7 @@
|
|||
"email": "api@example.com",
|
||||
"firstName": "John",
|
||||
"lastName": "Doe",
|
||||
"birthday": "2023-10-24 11:00:00",
|
||||
"birthday": "@date@",
|
||||
"gender": "m",
|
||||
"group": null,
|
||||
"phoneNumber": "+48123456789",
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
"email": "api@example.com",
|
||||
"firstName": "John",
|
||||
"lastName": "Doe",
|
||||
"birthday": "2023-10-24 11:00:00",
|
||||
"birthday": "@date@",
|
||||
"gender": "m",
|
||||
"group": "\/api\/v2\/admin\/customer-groups\/vip",
|
||||
"phoneNumber": "+48123456789",
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@
|
|||
"email": "api@example.com",
|
||||
"firstName": "John",
|
||||
"lastName": "Lim",
|
||||
"birthday": "2023-09-24 11:00:00",
|
||||
"birthday": "@date@",
|
||||
"gender": "f",
|
||||
"group": "\/api\/v2\/admin\/customer-groups\/premium",
|
||||
"phoneNumber": "+48987654321",
|
||||
|
|
|
|||
|
|
@ -14,8 +14,8 @@
|
|||
"usageLimit": 3,
|
||||
"used": 0,
|
||||
"archivedAt": null,
|
||||
"startsAt": "2023-10-04 12:30:00",
|
||||
"endsAt": "2023-11-04 12:30:00",
|
||||
"startsAt": "@date@",
|
||||
"endsAt": "@date@",
|
||||
"couponBased": true,
|
||||
"coupons": [],
|
||||
"rules": [
|
||||
|
|
|
|||
|
|
@ -9,7 +9,7 @@
|
|||
"usageLimit": 10,
|
||||
"used": 0,
|
||||
"promotion": "\/api\/v2\/admin\/promotions\/50_off",
|
||||
"expiresAt": "2020-01-01 12:00:00",
|
||||
"expiresAt": "@date@",
|
||||
"createdAt": "@date@",
|
||||
"updatedAt": "@date@"
|
||||
},
|
||||
|
|
@ -23,7 +23,7 @@
|
|||
"usageLimit": 10,
|
||||
"used": 0,
|
||||
"promotion": "\/api\/v2\/admin\/promotions\/50_off",
|
||||
"expiresAt": "2020-01-01 12:00:00",
|
||||
"expiresAt": "@date@",
|
||||
"createdAt": "@date@",
|
||||
"updatedAt": "@date@"
|
||||
},
|
||||
|
|
@ -37,7 +37,7 @@
|
|||
"usageLimit": 10,
|
||||
"used": 0,
|
||||
"promotion": "\/api\/v2\/admin\/promotions\/50_off",
|
||||
"expiresAt": "2020-01-01 12:00:00",
|
||||
"expiresAt": "@date@",
|
||||
"createdAt": "@date@",
|
||||
"updatedAt": "@date@"
|
||||
},
|
||||
|
|
@ -51,7 +51,7 @@
|
|||
"usageLimit": 10,
|
||||
"used": 0,
|
||||
"promotion": "\/api\/v2\/admin\/promotions\/50_off",
|
||||
"expiresAt": "2020-01-01 12:00:00",
|
||||
"expiresAt": "@date@",
|
||||
"createdAt": "@date@",
|
||||
"updatedAt": "@date@"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -10,5 +10,5 @@
|
|||
"promotion": "\/api\/v2\/admin\/promotions\/dollar_off",
|
||||
"createdAt": "@date@",
|
||||
"updatedAt": "@date@",
|
||||
"expiresAt": "2020-01-01 12:00:00"
|
||||
"expiresAt": "@date@"
|
||||
}
|
||||
|
|
|
|||
|
|
@ -14,6 +14,6 @@
|
|||
"fullName": "John Wick",
|
||||
"phoneNumber": "666777888",
|
||||
"gender": "m",
|
||||
"birthday": "2023-10-24 11:00:00",
|
||||
"birthday": "@date@",
|
||||
"subscribedToNewsletter": true
|
||||
}
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue