Skip to content

Releases: shopware/shopware

Release v6.7.8.2

18 Mar 15:05
950e0a0

Choose a tag to compare

System requirements

  • tested on PHP 8.2, 8.4 and 8.5
  • tested on MySQL 8 and MariaDB 11

Critical Fixes

Webhook for order state change

Fixed an undefined array key warning within the webhook handling, which could lead to a server error, if strict error displaying is set up.

Digital product legacy states repair after update

We fixed a bug in the indexer for the product.states field, which lead to issues where rules (and flows depending on those rules) with the line item with product state condition did not work as expected. This especially affected the flows to deliver digital download products after purchase.

This release repairs digital products with missing legacy states via a one-time UpdatePostFinishEvent subscriber.

The repair runs automatically once per installation and is marked as completed in app_config.

What's Changed

Full Changelog: v6.7.8.1...v6.7.8.2

Get in touch

Discuss about decisions, bugs you might stumble upon, etc in our community discord. See you there ;)

Security Release v6.6.10.15

11 Mar 11:25
31c6861

Choose a tag to compare

Security Release v6.7.8.1

11 Mar 11:25
7176944

Choose a tag to compare

System requirements

  • tested on PHP 8.2, 8.4 and 8.5
  • tested on MySQL 8 and MariaDB 11

Critical Fixes

Double signature verification in app-reregistration flow

Introduces a secure, asynchronous app secret rotation feature to the app system, including both API and CLI interfaces.
Added a new API endpoint and command for rotating app secrets, implemented the underlying rotation logic, and adjusted the app registration process to support secret updates and dual signature confirmation.
This increases security by enforcing a two-step verification process during app re-registration, ensuring that only authorized parties can update app secrets.

LoginRoute and AccountService don't throw CustomerNotFoundException

The LoginRoute and AccountService have been updated to no longer throw a CustomerNotFoundException when a login attempt is made with an email address that does not exist in the system.
Instead, they will now throw a generic BadCredentialsException without revealing whether the email address is registered or not.
This change enhances security by preventing potential attackers from enumerating valid email addresses through error messages.

Improve OrderRoute deepLinkCode filter type validation

Improve the logic in \Shopware\Core\Checkout\Order\SalesChannel\OrderRoute::load to ensure the deepLinkCode filter is an instance of \Shopware\Core\Framework\DataAbstractionLayer\Search\Filter\EqualsFilter.

What's Changed

Full Changelog: v6.7.8.0...v6.7.8.1

Get in touch

Discuss about decisions, bugs you might stumble upon, etc in our community discord. See you there ;)

Release v6.6.10.14

05 Mar 11:14
fa45e0f

Choose a tag to compare

Release v6.7.8.0

03 Mar 11:04
8139b19

Choose a tag to compare

System requirements

  • tested on PHP 8.2, 8.4 and 8.5
  • tested on MySQL 8 and MariaDB 11

Features

New internal comment for state machine state history entries

A new internal comment field was added to the state change modal which can be used to add additional information about a state change.
The internal comment is only visible in the administration and not shown to customers.
It can be found in the state machine state history modal (state change modal) on the detail page of an order.

API

Core

Indexing the product's custom fields

Custom fields used in product sorting and product streams, as well as those belonging to apps, are now included when indexing products with Elasticsearch.

Deprecation of increment-based message queue statistics

The increment-based message queue statistics system is deprecated and will be removed in v6.8.0.0.

What's changing:

  • The Administration notification center will no longer show indexing progress notifications (e.g., "X products will be indexed")
  • API endpoint GET /api/_info/queue.json is deprecated - use GET /api/_info/message-stats.json instead

Deprecated configuration options:

  • shopware.admin_worker.enable_queue_stats_worker
  • shopware.increment.message_queue

Deprecated code:

  • IncrementGatewayRegistry::MESSAGE_QUEUE_POOL constant
  • Increment-based handling in MessageQueueStatsSubscriber::onMessageHandled()

Why?
The increment-based statistics were often inaccurate due to hardcoded multipliers and missing decrements in edge cases. The replacement functionality was introduced in #8698

Immediate disable:
To disable the deprecated functionality before v6.8.0.0:

shopware:
    admin_worker:
        enable_queue_stats_worker: false

Internal product streams

A new boolean field internal has been added to product streams with a default value of false.
This allows you to mark product streams as internal for system or plugin use, preventing them from appearing in merchant-facing selection lists throughout the Administration (e.g., in categories, cross-selling, CMS elements, or sales channels).

Use this feature when you need to create product streams programmatically that should not be modified or selected by shop administrators.

Database table helper class

A new helper class \Shopware\Core\Framework\Util\Database\TableHelper was introduced,
which could be used to check the table for existence, columns, indexes, and foreign keys.

Deprecation of helper methods in \Shopware\Core\Framework\DataAbstractionLayer\Dbal\EntityDefinitionQueryHelper

As consequence of the introduction of the new table helper class following methods are deprecated and will be removed with the next major version:

  • \Shopware\Core\Framework\DataAbstractionLayer\Dbal\EntityDefinitionQueryHelper::columnExists
  • \Shopware\Core\Framework\DataAbstractionLayer\Dbal\EntityDefinitionQueryHelper::columnIsNullable
  • \Shopware\Core\Framework\DataAbstractionLayer\Dbal\EntityDefinitionQueryHelper::tableExists

Migration generator improvements

The migration generator previously used a fixed format: fk.<table-name>.<column> for foreign key names.
Doctrine does not support this format and creates broken migrations; therefore, we changed to the format fk__<table-name>__<column> for foreign key names.

Also, the generator now sets CASCADE DELETE on foreign keys for the translation table references.

CategoryIndexer selective indexing optimization

The CategoryIndexer now skips tree/child-count updaters when parentId hasn't changed, and breadcrumb updater when name hasn't changed. All updaters still run for INSERT and DELETE operations.

Updated doctrine/dbal dependency

The doctrine/dbal dependency was updated to the new 4.4 minor version.
They introduced many deprecations, especially in the SchemaManager tool, which also might affect you.
Read more about it in their upgrade guide.

Primary key validation in dal:validate command

The dal:validate command now includes validation to detect mismatches between database PRIMARY KEY constraints and entity definition PrimaryKey flags.
This validation prevents silent failures where queries return correct total counts but empty data arrays due to entity hydration failures caused by inconsistent primary key definitions.
When a mismatch is detected, the command provides a clear error message indicating which fields differ between the database schema and the entity definition.

Deprecation of default value for serializer in #[Serialized] field attribute

When you use #[Serialized] field in your attribute entity you should always pass the serializer explicitly, as the default serializer does not work as expected.
Additionally, the SerializerField will become internal in the next major release, as that field should be only used for attribute entities, but never directly in classic EntityDefinitions.

Administration

Product detail variants: configSettingGroups as computed and deprecations

In sw-product-detail-variants, the following changes were made:

  • configSettingGroups (now computed): Previously a data() property set by loadConfigSettingGroups(). It is now a computed property derived from productEntity.configuratorSettings and groups.
  • loadConfigSettingGroups() (deprecated): Marked as @deprecated tag:v6.8.0. It will be removed in 6.8.0 without replacement.

Deprecation of items prop in sw-entity-listing component

The items prop in the sw-entity-listing component has been deprecated and will be removed in v6.8.0.
Please use the dataSource prop instead to align with the parent sw-data-grid component.

Before (deprecated):

<sw-entity-listing
    :items="entityList"
    :repository="entityRepository"
    :columns="columns"
/>

After (recommended):

<sw-entity-listing
    :data-source="entityList"
    :repository="entityRepository"
    :columns="columns"
/>

The component will continue to work with the items prop for backward compatibility, but you will see a deprecation warning in the browser console.

Notification translations now update when language changes

Notifications now store translation keys directly in their title and message fields instead of translating them immediately.
The template checks if the text is a translation key and translates it reactively, allowing notifications to update automatically when the user changes the interface language.

Help text support for color picker custom fields

The color picker type for custom fields now supports adding a help text. When creating or editing a custom field of type "Colorpicker" in Settings > Content > Custom fields, you can now specify a help text that will be displayed to users in the Administration.

sw-select-base clearable button default behavior changed

The showClearableButton prop in sw-select-base now defaults based on the required attribute:

  • When required is false or not set: clearable button is shown by default
  • When required is true: clearable button is hidden by default

Previously, the clearable button was always hidden by default (showClearableButton: false).

Migration: If you relied on the previous behavior where the clearable button was hidden by default, explicitly set :show-clearable-button="false" on your select components.

Storefront

Selling and packaging information in the product detail page

  • Display the selling and packaging information with the product that has advanced pricing.
  • Deprecated block buy_widget_price_unit and it childrens in Resources/views/storefront/component/buy-widget/buy-widget-price.html.twig, will be moved into Resources/views/storefront/component/buy-widget/buy-widget.html.twig.

Default theme breakpoints now available in theme config

The default layout breakpoints in the Storefront were hard-coded before and couldn't easily be overriden. Now you will find new theme config fields in the default config, which serve as the default values. The fields are hidden in the visual configuration, so they serve as a feature for theme developers for now. You can override the following config fields in your custom theme.json file to change the default breakpoints. The fields are mapped to the existing hard-coded configuration. The configuration is only passed in Twig and JS currently and there is no direct usage in SCSS, as they represent the Bootstrap default breakpoints. If you want to make a full override, you can simply configure the Bootstrap breakpoints in your custom SCSS and use the theme config values for that.

  • sw-breakpoint-xs
  • sw-breakpoint-sm
  • sw-breakpoint-md
  • sw-breakpoint-lg
  • sw-breakpoint-xl
  • sw-breakpoint-xxl

Make static alerts announced in the screenreader

Static alert boxes that are rendered in the DOM on page load were previously not read out by screenreaders.
The role="alert" did not have an effect. Only role="alerts" added to the DOM by JavaScript were read out.

To solve the screenreader issue with static alerts, we introduced a new parameter announceOnLoad.
When announceOnLoad is set to true, the alert box content will be announced in the screenreader right after the page is loaded.
The alert box will apply an additional JavaScript plugin that attempts to trigger the screenreader.
This is done by changing the DOM within the aria-live region after a short delay, which tells the screenreader to read it.

{% sw_include '@Storefront/storefront/utilities/alert.html.twig' with {
    type: "primary",
    content: "An important mess...
Read more

Release v6.6.10.13

05 Feb 10:46
d370199

Choose a tag to compare

Release v6.7.7.1

05 Feb 10:16
88349fa

Choose a tag to compare

System requirements

  • tested on PHP 8.2, 8.4 and 8.5
  • tested on MySQL 8 and MariaDB 11

What's Changed

  • fix: getAddress inAddressDetailPageLoader (backport: 6.7.7.x) by @shopware-octo-sts-app-2[bot] in #14736
  • fix: elasticsearch requirement in core bundle (backport: 6.7.7.x) by @shopware-octo-sts-app[bot] in #14725
  • fix: order edit loading (backport: 6.7.7.x) by @shopware-octo-sts-app[bot] in #14746

Full Changelog: v6.7.7.0...v6.7.7.1

Get in touch

Discuss about decisions, bugs you might stumble upon, etc in our community discord. See you there ;)

Release v6.6.10.12

Release v6.7.7.0

02 Feb 13:25
44a0f49

Choose a tag to compare

System requirements

  • tested on PHP 8.2, 8.4 and 8.5
  • tested on MySQL 8 and MariaDB 11

Features

Symfony 7.4 update

All symfony packages have been updated to version 7.4.
Take a look at the Symfony 7.4 release post for more information.
Especially note that Symfony now requires php-redis extension v6.1 or higher: https://github.com/symfony/symfony/blob/7.4/UPGRADE-7.4.md#cache.
If you note compatibility issues with the Redis extension please check the installed version php-redis.

Changed maintenance mode redirect

After maintenance ends, users are now redirected back to the page they were on before maintenance.
Previously, users were always redirected to the shop homepage.

Support of media paths with up to 2046 characters

Previously the maximum length for media paths was limited to 255 characters (due to default StringField limit) while the
database field already supported up to 2046 characters. This limitation has now been lifted and media paths can be up to
2046 characters long.

Configurable Custom Field Searchability

Custom fields are now not searchable by default. To make a custom field searchable, you need to enable the "Include in search" option in the custom field detail modal when creating or updating a custom field in Settings > System > Custom fields. This change helps optimize index storage size and improve search performance, especially for stores with many custom fields.

Important: When enabling searchability for an existing product custom field, you must rebuild the search index or update the products manually to include the custom field data in search results.

Media Model Viewer

From now on you are able to inspect your 3D models directly in the Media module in the Administration. Simply select a model file and you will find an interactive 3D viewer in the Preview collapsable in the item sidebar on the right. This new component is called sw-model-viewer.

API

Improved tagged based cache invalidation

Next routes now support cache tagging, enabling automatic invalidation when relevant entities are written:

  • /store-api/breadcrumb/{id}
  • /store-api/media
  • /store-api/product/{productId}/find-variant
  • /store-api/product/{productId}/cross-selling

Core

Rework of DAL query generation for nested filters groups

The DAL criteria builder has been adjusted to generate EXISTS subqueries instead of LEFT JOINs for nested filter groups.

Previously, each level of nested filters resulted in an additional LEFT JOIN, even when the join was only required to check for the existence of a related entity subject to some filter.
In complex criteria trees with multiple filters on the same entity, this led to an exponential explosion of joins and significant performance degradation (e.g., the same table being joined multiple times only to evaluate existence conditions).

An example of this is a query such as "find orders that have a line item of type A and one of type B and one of type C".
According to aadr/2020-11-19-dal-join-filter.md, this would look like:

$criteria->addFilter(
    new EqualsFilter('lineItems.type', 'product'),
    new EqualsFilter('lineItems.type', 'custom'),
    new EqualsFilter('lineItems.type', 'other'),
);

Previously, the generated query would LEFT JOIN order_line_item multiple times onto order, causing the query to be extremely slow. The new EXISTS checks prevent this, making the query much faster.

Introduce Immutable DAL flag

A new Immutable flag is available for Data Abstraction Layer fields. Fields marked as immutable can be set during entity creation but cannot be updated later. This prevents accidental renames of technical identifiers that other subsystems rely on. Core entities now using the flag include:

  • custom_field.name
  • custom_field.type
  • custom_field_set.name

Trying to update these columns now results in a WriteConstraintViolationException with the message The field foo is immutable and cannot be updated., giving developers clear feedback when attempting to change these values.
If the value is not set in the payload, or the value won't change, no exception is thrown.

Performance Improvement for ProductCategoryDenormalizer

The SQL Query inside the ProductCategoryDenormalizer has been optimized to run faster, especially on large catalogues.
Previously MySql needed to perform a full table scan based on the where condition, now the result set is already limited by indexed columns.
This lead to performance improvements from up to 3s for the query down to less than 1ms on large catalogues (3000%).

Deprecation of product states in favor of the new product type

The product.states field is deprecated and will be removed in the next major release.
A new field product.type was introduced to clearly indicate whether a product is digital or physical, or other types registered by third-party developers.

As part of this change, the following deprecations were made:

  • The order_line_item.states field is deprecated in favor of order_line_item.payload.product_type.
  • \Shopware\Core\Checkout\Cart\LineItem\LineItem::$states is deprecated in favor of \Shopware\Core\Checkout\Cart\LineItem\LineItem::$payload['productType'].
  • The LineItemProductStatesRule is deprecated in favor of the new LineItemProductTypeRule.
  • The StatesUpdater service and its related dispatched events (ProductStatesBeforeChangeEvent, ProductStatesChangedEvent) are deprecated.
  • A new parameter shopware.product.allowed_types was introduced to allow third-party developers to register additional product types.
  • For more details, please refer to the 2025-11-14-introduce-product-type-and-deprecate-states.md

If you are using the rule LineItemProductStatesRule, product stream filters, or product listing filters that rely on product.states, you should update them to use the new product.type field instead.
If you create digital products using admin api, you should explicitly set the type field to digital when creating new products instead of relying on backend handling.

New RequestParamHelper

Symfony deprecated the "magic" Request::get() method, which was used to retrieve parameters from the request, by checking the attribute, query or request parameter bags.
For easier backward compatibilty we backported the old behaviour in the new RequestParamHelper class, however, it should only be used in explicit cases, where the parameter could be in any of those parameter bags.
The best practice is to check the explicit parameter bag, where you expect the parameter to be.
However, as we have a lot of API routes that support being called by GET and POST methods both, the helper is handy in such cases.

Before:

$parameter = $request->get($parameterName, $default);

After:

$parameter = RequestParameterHelper::get($request, $parameterName, $default);

To provide full backward compatibility, the helper currently also checks the attribute bag for the parameter first.
However, it should be possible to strictly differentiate between request attributes (which are generally controlled and set by the application itself) and input parameters (which are provided by the client, and based on how they are passed are either part of the query bag or the request bag) in the future.
Therefore the check of the attribute bag is deprecated and will be removed in the next major release.
When you need to get a value from the request attributes, you should use the Request::attributes->get() method directly.
In case you used to set request attributes to override specific parameters, you should instead overwrite the parametes in the query or request parameter bags directly.

The TranslationLoader class is now decoratable

The TranslationLoader class extends from the new AbstractTranslationLoader class and implements the decoratable pattern. This allows third-party developers to decorate the loader to add custom logic when a translation is loaded.

DomainExceptions don't create \RuntimeException anymore

All factory methods for domain exceptions now return specific exception classes instead of creating a generic \RuntimeException.
Changing the type of the thrown exception from \RuntimeException to a specific domain exception is not considered a breaking change, since all Domain Exceptions extend from \RuntimeException.

This means code like this will stay valid:

try {
    $this->someService->willThrowDomainException();
} catch (\RuntimeException $e) {
    // handle exception
}

Additionally all changed factory methods were marked as deprecated, because the \RuntimeException return type will be removed in the next major release.
This affects the following exception factory methods:

  • DataAbstractionLayerException::cannotBuildAccessor(...)
  • DataAbstractionLayerException::onlyStorageAwareFieldsAsTranslated(...)
  • DataAbstractionLayerException::onlyStorageAwareFieldsInReadCondition(...)
  • DataAbstractionLayerException::primaryKeyNotStorageAware(...)
  • DataAbstractionLayerException::missingTranslatedStorageAwareProperty(...)
  • DataAbstractionLayerException::noTranslationDefinition(...)
  • DataAbstractionLayerException::missingVersionField(...)
  • DataAbstractionLayerException::unexpectedFieldType(...)
  • WebhookException::invalidDataMapping(...)
  • WebhookException::unknownEventDataType(...)

More fine-grained caching control in HttpCacheCookieEvent

A new doNotStore property was added to the HttpCacheCookieEvent to allow fine-grained control over caching behavior.
This new property...

Read more

Release v6.7.6.2

20 Jan 10:03
061e131

Choose a tag to compare

System requirements

  • tested on PHP 8.2, 8.4 and 8.5
  • tested on MySQL 8 and MariaDB 11

What's Changed

Full Changelog: v6.7.6.0...v6.7.6.2

Get in touch

Discuss about decisions, bugs you might stumble upon, etc in our community discord. See you there ;)