10 KiB
UPGRADE FROM 2.2 TO 2.3
Configuration
-
The default value of
sylius_core.order_by_identifierhas been changed fromtruetofalse. (#18956)The
OrderByIdentifierSqlWalkeris no longer enabled by default. If your application relies on ordering by identifier, enable it explicitly in your configuration:sylius_core: order_by_identifier: true -
Configuration changes related to the broadened Doctrine support (see the Dependencies section). These only matter once you opt into DoctrineBundle 3 / DBAL 4:
-
The
auto_generate_proxy_classes: "%kernel.debug%"option was removed from Sylius' Doctrine configuration (it no longer exists in DoctrineBundle 3, and since PHP 8.4 Doctrine uses native lazy objects). If you are still on DoctrineBundle 2 and rely on this behavior, set it explicitly in your own application configuration. -
The ORM metadata/query/result cache configuration was switched from wrapped
Doctrine\Common\Cacheservices to PSR-6 cache pools (type: pool). This change lives in the application configuration (config/packages/{prod,test}/doctrine.yaml), which is not updated automatically on existing installations, update those files in your project accordingly:doctrine: orm: entity_managers: default: metadata_cache_driver: - type: service - id: doctrine.system_cache_provider + type: pool + pool: doctrine.system_cache_poolAs part of this switch, the
doctrine.result_cache_provideranddoctrine.system_cache_providerservices (defined in Sylius' application configuration, wrapping the PSR-6 pools viaDoctrine\Common\Cache\Psr6\DoctrineProvider) were removed. If you referenced them by id, use the cache pools directly (doctrine.system_cache_pool,doctrine.result_cache_pool) withtype: poolas shown above. -
On PostgreSQL, Sylius now forces the
SEQUENCEidentity generation strategy (identity_generation_preferencesforPostgreSQLPlatform) to keep the database schema backward compatible with existing installations.
-
Dependencies
-
The
behat/transliteratorpackage has been deprecated and will be removed in Sylius 3.0.Slug generation now primarily uses
symfony/string(Symfony\Component\String\Slugger\SluggerInterface). When no$sluggeris injected, the system falls back toBehat\Transliterator\Transliterator, but this fallback behavior is deprecated and will be removed in Sylius 3.0.The following classes have been updated — if you have extended or decorated them, update your constructor accordingly:
-
Sylius\Component\Product\Generator\SlugGenerator:-public function __construct() +public function __construct(private ?SluggerInterface $slugger)Deprecated: Passing
nullas$slugger(or omitting it) is deprecated since Sylius 2.3. Whennullis passed, the generator falls back toBehat\Transliterator\Transliterator. Both the nullable argument and thebehat/transliteratorfallback will be removed in Sylius 3.0. -
Sylius\Component\Taxonomy\Generator\TaxonSlugGenerator:-public function __construct() +public function __construct(private ?SluggerInterface $slugger)Deprecated: Same as above.
-
Sylius\Bundle\AdminBundle\Generator\TaxonSlugGenerator:public function __construct( private BaseTaxonSlugGeneratorInterface $slugGenerator, + private ?SluggerInterface $slugger, )Deprecated: Same as above.
The
StringInflector::nameToSlug()method has been deprecated and will be removed in Sylius 3.0. -
-
The
knplabs/gaufretteandknplabs/knp-gaufrette-bundlepackages have been removed.The Gaufrette integration has been unusable as a filesystem adapter. Since Sylius 2.0 the default filesystem adapter uses Flysystem instead.
If your application depends on the Gaufrette packages directly, require them explicitly in your
composer.json. -
The
symfony/proxy-manager-bridgeandfriendsofphp/proxy-manager-ltspackages have been removed.They are no longer needed, lazy services now rely on PHP's native lazy proxies provided by
symfony/var-exporter(the default since Symfony 6.4). No change is required in your application.If your application depends on these packages directly, require them explicitly in your
composer.json. -
The supported Doctrine version ranges have been broadened to allow the newer stack (
doctrine/doctrine-bundle^2.13 || ^3.0,doctrine/dbal^3.9 || ^4.0,doctrine/persistence^3.3 || ^4.0,doctrine/data-fixtures^1.7 || ^2.2).DBAL 4 removes the built-in
objectandarraycolumn types. Since Sylius maps two fields astype="object"(PaymentSecurityToken.detailsandPaymentRequest.payload), it registers a customSylius\Bundle\PaymentBundle\Doctrine\DBAL\Type\ObjectTypeto keep them working.
Validation
-
Passing an array of options to configure a Sylius validation constraint is deprecated since Sylius 2.3 and will be removed in Sylius 3.0. Use named arguments instead.
All Sylius validation constraints now declare explicit constructors with named arguments (marked with
#[HasNamedArguments]). The legacy array syntax keeps working, it only triggers deprecation.Configuring constraints via XML / YAML / PHP attributes is not affected and requires no changes; the validator loaders pass the options as named arguments automatically. Only direct instantiation in PHP should be migrated:
-new ProvinceAddressConstraint(['message' => 'My custom message']) +new ProvinceAddressConstraint(message: 'My custom message') -
Several constraint message options have been renamed to follow the consistent
*Messageconvention. The old option names and public properties are deprecated since Sylius 2.3 and will be removed in Sylius 3.0. Both keep working and stay in sync in the meantime; switch to the new*Messagename:Constraint Old New ApiBundle\...\ChosenPaymentMethodEligibilitynotAvailable,notExist,paymentNotFoundnotAvailableMessage,notExistMessage,paymentNotFoundMessageApiBundle\...\ChosenPaymentRequestActionEligibilitynotAvailable,notExistnotAvailableMessage,notExistMessageApiBundle\...\AddingEligibleProductVariantToCartproductVariantNotSufficientproductVariantNotSufficientMessageApiBundle\...\ChangedItemQuantityInCartproductVariantNotLongerAvailable,productVariantNotSufficientproductVariantNotLongerAvailableMessage,productVariantNotSufficientMessagePromotionBundle\...\PromotionRuleType,PromotionActionType,CatalogPromotionActionType,CatalogPromotionScopeTypeinvalidTypeinvalidTypeMessagePaymentBundle\...\GatewayFactoryExistsinvalidGatewayFactoryinvalidGatewayFactoryMessageShippingBundle\...\ShippingMethodCalculatorExistsinvalidShippingCalculatorinvalidShippingCalculatorMessageShippingBundle\...\ShippingMethodRuleinvalidTypeinvalidTypeMessage
New Features
-
New post-flush cart events have been added to
Sylius\Component\Order\SyliusCartEvents.The following events are now dispatched after
$manager->flush(), allowing listeners to react once the cart has been safely persisted to the database:New constant Event name SyliusCartEvents::CART_ITEM_POST_ADDsylius.cart_item_post_addSyliusCartEvents::CART_ITEM_POST_REMOVEsylius.cart_item_post_removeSyliusCartEvents::CART_POST_CHANGEsylius.cart_post_changeSyliusCartEvents::CART_POST_CLEARsylius.cart_post_clearExample usage — sending a cart to an external service only after it is stored:
use Sylius\Component\Order\SyliusCartEvents; use Symfony\Component\EventDispatcher\Attribute\AsEventListener; use Symfony\Component\EventDispatcher\GenericEvent; #[AsEventListener(event: SyliusCartEvents::CART_ITEM_POST_ADD)] final class SendCartToMarketingAutomationListener { public function __invoke(GenericEvent $event): void { // Cart is already persisted — safe to send to external service. } }The existing pre-flush events (
CART_ITEM_ADD,CART_ITEM_REMOVE,CART_CHANGE,CART_CLEAR) remain unchanged.
Deprecations
-
Passing a
Sylius\Component\Core\Calculator\ProductVariantPricesCalculatorInterfacedirectly to the following catalog-facing classes is deprecated since Sylius 2.3. ImplementSylius\Component\Core\Calculator\CatalogPricesCalculatorInterfaceinstead, which extendsProductVariantPricesCalculatorInterfacewith no additional methods. It will be required in Sylius 3.0.Affected classes:
Sylius\Bundle\CoreBundle\Twig\PriceExtensionSylius\Bundle\ApiBundle\Serializer\Normalizer\ProductVariantNormalizerSylius\Bundle\ShopBundle\Twig\Component\Product\PriceComponentSylius\Bundle\ShopBundle\Twig\Component\Product\CardComponentSylius\Component\Core\Provider\ProductVariantMap\ProductVariantPriceMapProviderSylius\Component\Core\Provider\ProductVariantMap\ProductVariantOriginalPriceMapProviderSylius\Component\Core\Provider\ProductVariantMap\ProductVariantLowestPriceMapProvider
If you have a custom calculator used for catalog display, make it implement
CatalogPricesCalculatorInterface:use Sylius\Component\Core\Calculator\CatalogPricesCalculatorInterface; final class MyCustomCatalogPriceCalculator implements CatalogPricesCalculatorInterface { // ... }This allows you to decorate catalog display pricing independently from cart/order pricing (
sylius.order_processing.order_prices_recalculator,sylius.filter.promotion.price_range), which remain onProductVariantPricesCalculatorInterface.