|
1 | 1 | UPGRADE FROM 6.3.x.x to 6.4
|
2 | 2 | =======================
|
3 | 3 |
|
| 4 | +# 6.4.11.0 |
| 5 | +## Introduce BeforeDeleteEvent |
| 6 | +The event is dispatched before delete commands are executed, so you can add success callbacks into the event when the delete command is successfully executed. Or you add error callbacks to the event when the execution meets some errors. |
| 7 | + |
| 8 | +**Reference: Shopware\Core\Framework\DataAbstractionLayer\Event\BeforeDeleteEvent** |
| 9 | + |
| 10 | +**Examples:** |
| 11 | + |
| 12 | +```php |
| 13 | +class YourBeforeDeleteEvent implements EventSubscriberInterface |
| 14 | + public static function getSubscribedEvents() |
| 15 | + { |
| 16 | + return [ |
| 17 | + BeforeDeleteEvent::class => 'beforeDelete', |
| 18 | + ]; |
| 19 | + } |
| 20 | + |
| 21 | + public function beforeDelete(BeforeDeleteEvent $event): void |
| 22 | + { |
| 23 | + $context = $event->getContext(); |
| 24 | + |
| 25 | + // Delete ids of the given entity |
| 26 | + // At the given point, the ids are not deleted yet |
| 27 | + $ids = $event->getIds(CustomerDefinition::ENTITY_NAME); |
| 28 | + |
| 29 | + $event->addSuccess(function (): void { |
| 30 | + // Implement the hook when the entities got deleted successfully |
| 31 | + // At the given point, the $ids are deleted |
| 32 | + }); |
| 33 | + |
| 34 | + $event->addError(function (): void { |
| 35 | + // At the given point, the $ids are not deleted due to failure |
| 36 | + // Implement the hook when the entities got deleted unsuccessfully |
| 37 | + }); |
| 38 | + } |
| 39 | +} |
| 40 | +``` |
| 41 | +## Modal Refactoring |
| 42 | + |
| 43 | +Previously you had to use the following snippet: |
| 44 | +```js |
| 45 | +import AjaxModalExtension from 'src/utility/modal-extension/ajax-modal-extension.util'; |
| 46 | +new AjaxModalExtension(false); |
| 47 | +``` |
| 48 | +to activate modals on elements that match the selector `[data-toggle="modal"][data-url]`. |
| 49 | +This is error-prone when used multiple times throughout a single page lifetime as it will open up modals for every execution of this rigid helper. |
| 50 | +In the future you can use the new storefront plugin `AjaxModalPlugin` which has more configuration and entrypoints for developers to react to or adjust behaviour. |
| 51 | +The plugin is registered to the same selector to ensure non-breaking upgrading by default. |
| 52 | +## Removal of deprecated route specific annotations |
| 53 | + |
| 54 | +The following annotations has been removed `@Captcha`, `@LoginRequired`, `@Acl`, `@ContextTokenRequired` and `@RouteScope` and replaced with Route defaults. See below examples of the migration |
| 55 | + |
| 56 | +### @Captcha |
| 57 | + |
| 58 | +```php |
| 59 | +/** |
| 60 | + * @Captcha |
| 61 | + * @Route("/account/register", name="frontend.account.register.save", methods={"POST"}) |
| 62 | + */ |
| 63 | +``` |
| 64 | + |
| 65 | +to |
| 66 | + |
| 67 | +```php |
| 68 | +/** |
| 69 | + * @Route("/account/register", name="frontend.account.register.save", methods={"POST"}, defaults={"_captcha"=true}) |
| 70 | + */ |
| 71 | +``` |
| 72 | + |
| 73 | +### @LoginRequired |
| 74 | + |
| 75 | +```php |
| 76 | +/** |
| 77 | + * @LoginRequired |
| 78 | + * @Route("/account/register", name="frontend.account.register.save", methods={"POST"}) |
| 79 | + */ |
| 80 | +``` |
| 81 | + |
| 82 | +to |
| 83 | + |
| 84 | +```php |
| 85 | +/** |
| 86 | + * @Route("/account/register", name="frontend.account.register.save", methods={"POST"}, defaults={"_loginRequired"=true}) |
| 87 | + */ |
| 88 | +``` |
| 89 | + |
| 90 | +### @Acl |
| 91 | + |
| 92 | +```php |
| 93 | +/** |
| 94 | + * @Acl({"my_plugin_do_something"}) |
| 95 | + * @Route("/account/register", name="frontend.account.register.save", methods={"POST"}) |
| 96 | + */ |
| 97 | +``` |
| 98 | + |
| 99 | +to |
| 100 | + |
| 101 | +```php |
| 102 | +/** |
| 103 | + * @Route("/account/register", name="frontend.account.register.save", methods={"POST"}, defaults={"_acl"={"my_plugin_do_something"}}) |
| 104 | + */ |
| 105 | +``` |
| 106 | + |
| 107 | + |
| 108 | +### @ContextTokenRequired |
| 109 | + |
| 110 | +```php |
| 111 | +/** |
| 112 | + * @ContextTokenRequired |
| 113 | + * @Route("/account/register", name="frontend.account.register.save", methods={"POST"}) |
| 114 | + */ |
| 115 | +``` |
| 116 | + |
| 117 | +to |
| 118 | + |
| 119 | +```php |
| 120 | +/** |
| 121 | + * @Route("/account/register", name="frontend.account.register.save", methods={"POST"}, defaults={"_contextTokenRequired"=true}) |
| 122 | + */ |
| 123 | +``` |
| 124 | + |
| 125 | +### @RouteScope |
| 126 | + |
| 127 | +```php |
| 128 | +/** |
| 129 | + * @RouteScope(scopes={"api"}) |
| 130 | + * @Route("/account/register", name="frontend.account.register.save", methods={"POST"}) |
| 131 | + */ |
| 132 | +``` |
| 133 | + |
| 134 | +to |
| 135 | + |
| 136 | +```php |
| 137 | +/** |
| 138 | + * @Route("/account/register", name="frontend.account.register.save", methods={"POST"}, defaults={"_routeScope"={"api"}}) |
| 139 | + */ |
| 140 | +``` |
| 141 | +## New Twig filter sw_icon_cache |
| 142 | +From now on, all icons implemented via `sw_icon` is wrapped with `sw_icon_cache`. |
| 143 | +This causes all icons only be defined once per html page and multiple occurences be referenced by id. |
| 144 | +### Example |
| 145 | +First implementation of the `star` icon: |
| 146 | +```html |
| 147 | +<svg xmlns="http://www.w3.org/2000/svg" |
| 148 | + xmlns:xlink="http://www.w3.org/1999/xlink" |
| 149 | + width="24" height="24" viewBox="0 0 24 24"> |
| 150 | + <defs> |
| 151 | + <path id="icons-solid-star" |
| 152 | + d="M6.7998 23.3169c-1.0108.4454-2.1912-.0129-2.6367-1.0237a2 2 0 0 1-.1596-1.008l.5724-5.6537L.7896 11.394c-.736-.8237-.6648-2.088.1588-2.824a2 2 0 0 1 .9093-.4633l5.554-1.2027 2.86-4.9104c.556-.9545 1.7804-1.2776 2.7349-.7217a2 2 0 0 1 .7216.7217l2.86 4.9104 5.554 1.2027c1.0796.2338 1.7652 1.2984 1.5314 2.378a2 2 0 0 1-.4633.9093l-3.7863 4.2375.5724 5.6538c.1113 1.0989-.6894 2.08-1.7883 2.1912a2 2 0 0 1-1.008-.1596L12 21.0254l-5.2002 2.2915z"> |
| 153 | + </path> |
| 154 | + </defs> |
| 155 | + <use xlink:href="#icons-solid-star"></use> |
| 156 | +</svg> |
| 157 | +``` |
| 158 | +Following implementations of the `star` icon: |
| 159 | +```html |
| 160 | +<svg xmlns="http://www.w3.org/2000/svg" |
| 161 | + xmlns:xlink="http://www.w3.org/1999/xlink" |
| 162 | + width="24" height="24" viewBox="0 0 24 24"> |
| 163 | + <use xlink:href="#icons-solid-star"></use> |
| 164 | +</svg> |
| 165 | +``` |
| 166 | +This behaviour can be disabled by setting the system config `core.storefrontSettings.iconCache` to `false`. |
| 167 | +The Setting can be found in the administration under `Settings`-> `System`->`Storefront`->`Activate icon cache` |
| 168 | +From 6.5.0.0 on this will be enabled by default. |
| 169 | + |
| 170 | +You can enable and disable this behaviour on a template basis by calling the new twig function `sw_icon_cache_enable` |
| 171 | +and `sw_icon_cache_disable`. |
| 172 | + |
| 173 | +## New Command theme:prepare-icons |
| 174 | +The new command `theme:prepare-icons` prepares svg icons for usage in the storefront with compatibility with the icon cache. |
| 175 | +The command requires a path for the icons to prepare and a package name for the icons and will save all updated icons to a subdirectory `prepared`. |
| 176 | +Optional you can also set the following options: |
| 177 | +* --cleanup (true|false) - This will remove all unnecessary attributes from the icons. |
| 178 | +* --fillcolor (color) - This will add this colorcode to the `fill` attribute. |
| 179 | +* --fillrule (svg fill rule) - This will add the fill rule to the `fill-rule` attribute |
| 180 | +``` |
| 181 | +/bin/console theme:prepare-icons /app/platform/src/Storefront/Resources/app/storefront/dist/assets/icon/default/ default -c true -r evenodd -f #12ef21 |
| 182 | +``` |
| 183 | +## Better profiling integration |
| 184 | +Shopware now supports better profiling for multiple integrations. |
| 185 | +To activate profiling and a specific integration, add the corresponding integration name to the `shopware.profiler.integrations` parameter in your shopware.yaml file. |
| 186 | +## Translation overwrite priority specified for write payloads |
| 187 | + |
| 188 | +We specified the following rules for overwrites of translation values in write-payloads inside the DAL. |
| 189 | +1. Translations indexed by `iso-code` take precedence over values indexed by `language-id` |
| 190 | +2. Translations specified on the `translations`-association take precedence over values specified directly on the translated field. |
| 191 | + |
| 192 | +For a more information on those rules refer to the [according ADR](../../adr/2022-03-29-specify-priority-of-translations-in-dal-write-payloads.md). |
| 193 | + |
| 194 | +Let's take a look on some example payloads, to see what those rules mean. |
| 195 | +**Note:** For all examples we assume that `en-GB` is the system language. |
| 196 | + |
| 197 | +### Example 1 |
| 198 | +Payload: |
| 199 | +```php |
| 200 | +[ |
| 201 | + 'name' => 'default', |
| 202 | + 'translations' => [ |
| 203 | + 'name' => [ |
| 204 | + 'en-GB' => 'en translation', |
| 205 | + ], |
| 206 | + ], |
| 207 | +] |
| 208 | +``` |
| 209 | +Result: `en translation`, because values in `translations` take precedence over those directly on the translated fields. |
| 210 | +### Example 2 |
| 211 | +Payload: |
| 212 | +```php |
| 213 | +[ |
| 214 | + 'name' => 'default', |
| 215 | + 'translations' => [ |
| 216 | + 'name' => [ |
| 217 | + Defaults::SYSTEM_LANGUAGE => 'en translation', |
| 218 | + ], |
| 219 | + ], |
| 220 | +] |
| 221 | +``` |
| 222 | +Result: `en translation`, because of the same reasons as above. |
| 223 | +### Example 3 |
| 224 | +Payload: |
| 225 | +```php |
| 226 | +[ |
| 227 | + 'name' => [ |
| 228 | + Defaults::SYSTEM_LANGUAGE => 'id translation', |
| 229 | + 'en-GB' => 'iso-code translation', |
| 230 | + ], |
| 231 | +] |
| 232 | +``` |
| 233 | +Result: `iso-code translation`, because `iso-code` take precedence over `language-id`. |
| 234 | +### Example 4 |
| 235 | +Payload: |
| 236 | +```php |
| 237 | +[ |
| 238 | + 'name' => 'default', |
| 239 | + 'translations' => [ |
| 240 | + 'name' => [ |
| 241 | + Defaults::SYSTEM_LANGUAGE => 'id translation', |
| 242 | + 'en-GB' => 'iso-code translation', |
| 243 | + ], |
| 244 | + ], |
| 245 | +] |
| 246 | +``` |
| 247 | +Result: `iso-code translation`, because `iso-code` take precedence over `language-id`. |
| 248 | +### Example 5 |
| 249 | +Payload: |
| 250 | +```php |
| 251 | +[ |
| 252 | + 'name' => [ |
| 253 | + Defaults::SYSTEM_LANGUAGE => 'default', |
| 254 | + ], |
| 255 | + 'translations' => [ |
| 256 | + 'name' => [ |
| 257 | + Defaults::SYSTEM_LANGUAGE => 'en translation', |
| 258 | + ], |
| 259 | + ], |
| 260 | +] |
| 261 | +``` |
| 262 | +Result: `en translation`, because values in `translations` take precedence over those directly on the translated fields. |
| 263 | +### Example 6 |
| 264 | +Payload: |
| 265 | +```php |
| 266 | +[ |
| 267 | + 'name' => [ |
| 268 | + 'en-GB' => 'default', |
| 269 | + ], |
| 270 | + 'translations' => [ |
| 271 | + 'name' => [ |
| 272 | + Defaults::SYSTEM_LANGUAGE => 'en translation', |
| 273 | + ], |
| 274 | + ], |
| 275 | +] |
| 276 | +``` |
| 277 | +Result: `default`, because `iso-code` take precedence over `language-id`, and that rule has a higher priority then the second "association rule". |
| 278 | +## Webhooks contain unique event identifier |
| 279 | +All webhooks now contain a unique identifier that allows your app to identify the event. |
| 280 | +The identifier can be found in the JSON-payload under the `source.eventId` key. |
| 281 | + |
| 282 | +```json |
| 283 | +{ |
| 284 | + "source": { |
| 285 | + "url": "http:\/\/localhost:8000", |
| 286 | + "appVersion": "0.0.1", |
| 287 | + "shopId": "dgrH7nLU6tlE", |
| 288 | + "eventId": "7b04ebe416db4ebc93de4d791325e1d9" |
| 289 | + } |
| 290 | +} |
| 291 | + |
| 292 | +``` |
| 293 | +This identifier is unique for each original event, it will not change if the same request is sent multiple times due to retries, |
| 294 | +because your app maybe did not return a successful HTTP-status on the first try. |
| 295 | +## Redis store for number range increments |
| 296 | +You can now generate the number range increments using redis instead of the Database. |
| 297 | +In your `shopware.yaml` specify that you want to use the redis storage and the url that should be used to connect to the redis server to activate this feature: |
| 298 | +```yaml |
| 299 | +shopware: |
| 300 | + number_range: |
| 301 | + increment_storage: "Redis" |
| 302 | + redis_url: "redis://redis-host:port/dbIndex" |
| 303 | +``` |
| 304 | +
|
| 305 | +To migrate the increment data that is currently stored in the Database you can run the following CLI-command: |
| 306 | +```shell |
| 307 | +bin/console number-range:migrate SQL Redis |
| 308 | +``` |
| 309 | +This command will migrate the current state in the `SQL` storage to the `Redis` storage. |
| 310 | +**Note:** When running this command under load it may lead to the same number range increment being generated twice. |
| 311 | +## Apps can now require additional ACL privileges |
| 312 | + |
| 313 | +In addition to requiring CRUD-permission on entity basis, apps can now also require additional ACL privileges. |
| 314 | +```xml |
| 315 | +<?xml version="1.0" encoding="UTF-8"?> |
| 316 | +<manifest xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" |
| 317 | + xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/shopware/platform/trunk/src/Core/Framework/App/Manifest/Schema/manifest-1.0.xsd"> |
| 318 | + <meta> |
| 319 | + ... |
| 320 | + </meta> |
| 321 | + <permissions> |
| 322 | + <create>product</create> |
| 323 | + <update>product</update> |
| 324 | + <permission>user_change_me</permission> |
| 325 | + </permissions> |
| 326 | +</manifest> |
| 327 | +``` |
| 328 | + |
4 | 329 | # 6.4.9.0
|
5 | 330 | ## Bootstrap v5 preview
|
6 | 331 |
|
|
0 commit comments