System requirements
Php 8.3 - 8.4
- New dependencies
- ext-amqp - indirectly required by symfony/amqp-messenger
- ext-redis - indirectly required by symfony/redis-messenger
- ext-intl
- ext-soap
- monolog/monolog - aldready required indirectly
- pear/archive_tar - migrated from lib/*
- psr/simple-cache - already required indirectly via require-dev
- sabberworm/php-css-parser - aldready required indirectly
- scienta/doctrine-json-functions
- symfony/intl - aldready required indirectly
- symfony/lock - aldready required indirectly
- symfony/webpack-encore-bundle
- Removed dependencies
- ext-dom - still present as an indirect dependency
- doctrine/annotations - still present as an indirect dependency, not used explicitly
- doctrine/doctrine-bundle - still present as an indirect dependency
- maxbanton/cwh
- sensio/framework-extra-bundle
- New dependencies
NodeJS version 22
- yarn version 1.22
Redis version must be 6.2.0 or higher.
Two separate databases are required: one for cache and one for sessions
###> Redis ###
# Primary Redis instance. Should be configured with large memory limit and no persistence.
# Suitable for all kinds of caches.
REDIS_HOST="localhost"
REDIS_PORT="6379"
REDIS_DSN=redis://localhost
# Additional Redis instance for sessions and locks. Should be configured with persistence and lower memory limit.
REDIS_EXTRA_HOST="localhost"
REDIS_EXTRA_PORT="6379"
REDIS_EXTRA_DSN=redis://localhost
###< Redis ###
liblpsolve55.so - for Order Routing
# Path to the lpsolve library (e.g., liblpsolve55.so, liblpsolve55.dll, or liblpsolve55.dylib).
# If only the file name is provided (without a full path), the system will attempt to locate
# the library in standard system library paths based on OS settings.
LP_SOLVE_LIB_PATH=liblpsolve55.soAdded support for image flow https://sellerlabs.atlassian.net/browse/ECOM-8524
Added support for libvips https://sellerlabs.atlassian.net/browse/ECOM-8525
To enable asynchronous data processing (such as import, email dispatch, image resizing, QuickData calculation, etc.), a background message processing worker must be running on the server.
- A full list of queues -
./bin/console xcart:messenger:receivers:list -x
- Example command to start a worker for a specific queue -
./bin/console messenger:consume async
- A full list of queues -
Removed modules
Payment modules
- CDev-AuthorizeNet
- CDev-Quantum
- CDev-TwoCheckout
- QSL-AuthorizenetAcceptjs
- QSL-CCBill
- QSL-EGateway
- QSL-Giropay
- QSL-GlobalTransport
- QSL-Pagseguro
- QSL-Paysafecard
- QSL-RealexHostedPayment
- QSL-SecurePay
- QSL-TenPay
- Qualiteam-CoinPayments
- XC-Beanstream
- XC-BitPay
- XC-BlueSnap
- XC-ChronoPay
- XC-DIBSFlexWin
- XC-EBSIndia
- XC-EPDQ
- XC-ESelectHPP
- XC-EWAYStoredShared
- XC-DatatransUPP
- XC-Heartland
- XC-IdealPayments
- XC-InternetSecure
- XC-NetbanxHostedPayment
- XC-OgoneEcommerce
- XC-PayFort
- XC-PayTabs
- XC-PayUIndia
- XC-PoliPayment
- XC-SagePay
- XC-SecureTrading
- XC-SimplifyCommerce
- XC-SofortBanking
- XC-VirtualMerchant
- XC-WorldpayHPP
Skins
- QSL-Linen
- QSL-Multistore
- QSL-UltimateSkin
- TemplateMonster-KitchenSuppliesStore
- TemplateMonster-Organica
- XC-DarkSparkleSkin
- XC-DelicatePinkSkin
- XC-DewyGreenSkin
- XC-ForestGreenSkin
- XC-MarbleGreySkin
- XC-SoftBlueSkin
- XC-SpaceVioletSkin
Languages
- CDev-RuTranslation
- XC-GbTranslation
- XC-NlTranslation
- XC-ZhTranslation
Miscellaneous
- CDev-Catalog
- CDev-Demo
- CDev-DemoAdmin
- CDev-PINCodes
- QSL-AMP
- QSL-AdvancedSecurity
- QSL-AgeVerification
- QSL-OAuth2Client
- QSL-OrderReports
- QSL-PDFInvoice - функционал перенесен в ядро
- QSL-SEOCheck
- QSL-TreeLikeCategoriesMenu
- QSL-XLSExportImport
- XC-DisqusComments
- XC-MultiVendor
- XC-NotFinishedOrders
- XC-Onboarding
- XC-ProductVariants
- XC-TrustedVendors
- XC-UpdateInventory
- XC-VendorPartners
Discontinuation of XC-ProductVariants
- The XC-ProductVariants module has been removed.
- It is now recommended to use the XC-ProductVariations module instead.
- A data migration from XC-ProductVariants to XC-ProductVariations is provided as part of version 5.5.1. Important: This migration must be completed before updating from 5.5.1 to 5.6.0
API
Library Replacement
- Removed packages:
- xcart/api-platform-bridge-bundle
- xcart/common-bundle
- xcart/doctrine-bridge-bundle
- xcart/dto-generator-bundle
- xcart/logic-bundle
- New package (Note: internal namespaces remain unchanged.)
- xcart/api-core-bundle
Usage
- A unified stack and approach is used for both AdminAPI and StorefrontAPI.
- Improvements
- New fields have been added to logic layer definitions:
- doctrineRepository
- doctrineEntityIdName
- registerRepositoryService
- registerDataSourceService
- The generation method for logicShortServiceSuffix has been updated.
- In the UpdateOne operation, usage of Enricher has been replaced with Transformer (Logic → Entity)
- All transformers now use the MethodBasedTransformer logic
- Transformers: The transform method now includes a $target parameter. If this parameter is provided, the passed object will be used instead of creating a new one.
- New fields have been added to logic layer definitions:
XMLHttpRequestFrontend (js, css)
These changes apply exclusively to the storefront (customer area):
- Styles and JS in the Customer area
- Bundles
- Not used on the storefront:
- getJSFiles
- getCSSFiles
- getCommonFiles
- getResources
- getThemeFiles
- Bundles are built using nodejs & yarn
- xcart:assets:install (src/bin/assets_install.sh)
- Modules
- …
- Not used on the storefront:
- LESS → SCSS
- The parent theme concept has been removed.
- Node-based dependencies
- Core only
- JS
- fetch is used instead of XMLHttpRequest
Cart calculation, Multiple Locations, Split Sipments
Multiple Locations
- New entity - Location (Warehouse) (\XLite\Model\Location)
- Product inventory is now tied to a specific warehouse (\XLite\Model\LocationStock)
- The fields \XLite\Model\Product::$amount and \XLite\Model\Product::$availableAmount (used for backorders) are effectively utilized.
- The values are calculated automatically.
- New entity - DataProvider (Product price source) (\XLite\Model\ProductDataProvider)
- Product pricing is linked through \XLite\Model\ProductDataProviderProduct
- The final product price is calculated based on prices from the providers
Split Shipments
- Migrated from 5.5.1 XC-SplitShipment, but with significant changes.
- New entities introduced:
- \XLite\Model\Shipment
- \XLite\Model\ShipmentItem
- In an order (\XLite\Model\Order), deliverable items are distributed across multiple shipments. Each item can appear in several shipments, but the total quantity across shipments must match the quantity ordered.
- Each shipment has its own status and a separate list of tracking numbers.
- The distribution of items across shipments is handled automatically, based on the following enabled rules:
- Minimization of the number of shipments per order
- Rule priority defined in the Shipping Profile
- For distribution, linear optimization powered by the libsolve library is used.
Shopping cart/order calculation
Cart calculation has been moved into a set of separate services, almost completely isolated from the rest of the code.
All logic is located under the namespace XCart\Domain\Action\Order\Calculate
Interaction with the calculation in modules (creating a surcharge)
Instead of declaring a modifier via the database, for example
XLite\Model\Order\Modifier:
- class: CDev\Coupons\Logic\Order\Modifier\Discount
weight: 50
- class: CDev\Coupons\Logic\Order\Modifier\CouponFreeCheapestShipping
weight: 51
- class: CDev\Coupons\Logic\Order\Modifier\CouponFreeShippingMethod
weight: 52It is necessary to create a class that implements the
\XCart\Domain\Action\Order\Calculate\SurchargeModifier\SurchargeModifierInterface
interface (This class must be registered as a Symfony service.)
Import/Export and other asynchronous processes
Processes Executed Asynchronously
Core
- Import
- Export
- CategoriesStructure - category tree calculation, used during import
- MergeProductClasses - merging of classes
- ProductPrice - product price updates, price management
- QuickData
- ResizeImage
- SendMail
- Widget - asynchronous widget rendering into cache
Modules
- CDev-AmazonS3Images - processes related to file transfer
- CDev-XMLSitemap
- QSL-ShopByBrand - brand product price calculation
- XC-AmazonSPAPI
- XC-CustomProductTabs - tab creation during import
- XC-FacebookMarketing
- XC-GoogleFeed
- XC-MailChimp
Auto integrations
- Data import in auto integrations also runs asynchronously but uses separate queues
- async_auto_import
- async_auto_resources
- async_auto_vehicles
Feedback
To receive feedback during queue task execution, X-Cart uses the \XLite\Model\Messenger\Task
and \XLite\Model\Messenger\Action
objects.
Before sending a message to the queue, a new
\XLite\Model\Messenger\Task
object is created (or an existing one is loaded from the database if the message is part of a larger task).The object's ID is sent along with the message into the queue.
The handler updates the corresponding
\XLite\Model\Messenger\Task
object as needed.At any moment, you can retrieve the information of a specific object from the database
\XLite\Model\Messenger\Task
The
\XLite\Model\Messenger\Action
object is used when a task is split into multiple steps. This is, for example, the case for imports — import data is broken into chunks and processed separately, sometimes in parallel.
CleanURL
To simplify the CleanURL parsing system, prefixes corresponding to targets have been introduced.
If you need to use cleanurl for custom objects, the following is required:
- An appropriate alias must be added to the configuration
x_cart:
clean_urls:
aliases:
news_message: news
- To add your own parser, you need to create a Symfony service that implements the interface \XCart\CleanUrl\Parser\CleanUrlWithPrefixParserInterface and tag it with
clean_url.parser.with_prefix
. In most cases, this is not required. - To add your own builder, you need to implement the interface \XCart\CleanUrl\Builder\CleanUrlBuilderFactoryInterface. In most cases, this is not required.
Logging for Payment Methods
A dedicated service monolog.logger.payments is used for logging in payment modules. This allows logging to be independent of the main application logging level.
- You can access this service via DI in other services using the constructor parameter name:
public function __construct(
protected LoggerInterface $paymentsLogger
) {
} - Or by using the service locator in legacy code, for example:
$logger = Container::getContainer()->get('monolog.logger.payments')->withName('Amazon-PayWithAmazon');