# Plugins & Apps


# Confirmation Mails for Forms


# 1. Description

When a customer submits a form, by default only the shop owner receives an e-mail with the summary. With this plugin you get the possibility to send automatic confirmation emails to the customer, if he has completed and sent a form.

You can use the Shopware backend module for email templates to create new templates and link them to your forms. In your templates you can use the fields and their names and also the values filled in by the customer. The important thing is that your form contains a field of the type "email", because the confirmation email is sent to the email address entered there. Without an e-mail field, the plugin can not know where to send the confirmation e-mail.

If a form has multiple e-mail fields, the confirmation e-mail will be sent to the address entered in the first e-mail field. Position your fields accordingly.

You can decide yourself which form is linked to which mail template. On forms without a linked template no mail will be sent to the customer.

The plugin is also compatible with sub and language shops. If the translation is present for the mail template, the sender receives the confirmation mail in the language that is configured for his current shop.

The plugin requires at least PHP 5.6. It was developed and tested for Shopware 5.3.0 to 5.6.x. Should you notice any bugs, I'll be happy if you let me know about it via the Shopware support tool. If you have a suggestion for improvement or individual adjustment wishes, you can contact me via <moritz@momocode.de>.

### Compatibility with other plugins

#### BogxEmbeddedForm (Formulare Widget)

With the BogxEmbeddedForm Plugin you can add forms e.g. to emotions. I have added a compatibility to this plugin. So you can use confirmation mails for forms of this plugin, too. However, please note that compatibility with other plugins is not guaranteed for every version of the plugin because you have no control over what other developers do with their plugins. The BogxEmbeddedForm was tested in version 3.3.2. If you have a version that is no longer compatible with my plugin, please contact me at <moritz@momocode.de>.

### You also want to send a HTML email to the recipient of a form?

With my plugin "HTML Mail for Forms" this is possible. The plugin also sends the recipient a mail with a selected email template. Take the opportunity and purchase directly both plugins in one bundle!


# 2. Installation

1. Download the plugin and upload the ZIP file via the plugin manager in your Shopware backend
2. Click on the install icon to install the plugin and then activate it
3. The plugin installation creates a new attribute field for forms. Open a form in the backend under "Content -> Forms" and check whether the new free text field is available in the "Free text fields" area.


# 3. Configuration

Under "Configuration -> Email templates" or from Shopware 5.6 under "Configuration -> E-mail management -> Email templates" you can create new templates for your forms in the folder "User emails". In this templates you have access to different variables. For example the names of the fields of the form and the values submitted by the customer. For example, if you link a template to the standard Contact Form, the following variables are available:

{$sShop}: Shopware Demo\
{$sShopURL}: <http://example.com\\>
{$momoFormData.anrede.label}: Title\
{$momoFormData.anrede.value}: Mr\
{$momoFormData.vorname.label}: First name\
{$momoFormData.vorname.value}: Moritz\
{$momoFormData.nachname.label}: Last name\
{$momoFormData.nachname.value}: Müller\
{$momoFormData.email.label}: eMail-Adress\
{$momoFormData.email.value}: <moritz@momocode.de>\
{$momoFormData.telefon.label}: Phone\
{$momoFormData.telefon.value}:\
{$momoFormData.betreff.label}: Subject\
{$momoFormData.betreff.value}: Contact request\
{$momoFormData.kommentar.label}: Comment\
{$momoFormData.kommentar.value}: Dear Ladies and Gentlemen...

So for every field you have access to the label and to the value submitted by the customer. As of version 1.1.0 of the plugin, fields of type "text2" are also supported. For example, if the field has the name "plz;ort" with the label "Postal Code ; City", the following variables are available separately in the e-mail template:

{$momoFormData.plz.label}: Postal Code\
{$momoFormData.plz.value}: ...\
{$momoFormData.ort.label}: City\
{$momoFormData.ort.value}: ...

If your field names contain special characters or umlauts, the variables must be built into the template as follows:

{$momoFormData\['straße'].label}: Street\
{$momoFormData\['straße'].value}: Hauptstraße\
{$momoFormData\['nationalität'].label}: Nationality\
{$momoFormData\['nationalität'].value}: German

When your new mail template is created, you can link it to your form by choosing the template in the free text field of your form. On forms without a linked template there will be no confirmation mail sent to the customer.

The important thing is that your form contains a field of the type "email", because the confirmation email is sent to the email address entered there. Without an e-mail field, the plugin can not know where to send the confirmation e-mail. If a form has multiple e-mail fields, the confirmation e-mail will be sent to the address entered in the first e-mail field. Position your fields accordingly.


# HTML Mail for Forms


# 1. Description

By default, only a plain text email can be configured for a form. The email that then arrives at the form recipient looks unstyled and cluttered. With this plugin you get the possibility to assign an email template to forms. Thus, a beautiful and clear HTML email can be sent to the recipient.

You can create any templates via the Shopware backend module for email templates and link them to your forms. In the email templates, you can access both the fields and their names, as well as the values filled in by the sender, so that the form recipient can evaluate the data.

You can determine which forms are linked to which email templates. For forms that are not linked to an email template, the plain text email will continue to be sent. For forms that have been assigned an e-mail template, the plain text e-mail will be replaced, i.e. not both e-mails will be sent, but then only the HTML e-mail. In both cases, the e-mail address that is stored with the form is taken as the recipient. For HTML e-mails there is no extra field for the recipient, but the recipient is taken from the standard field.

The plugin requires at least PHP 5.6. It was developed and tested for Shopware 5.3.0 to 5.6.x. Should you notice any bugs, I'll be happy if you let me know about it via the Shopware support tool. If you have a suggestion for improvement or individual adjustment wishes, you can contact me via <moritz@momocode.de>.

### You also want to send a confirmation email to the sender of a form?

With my plugin "Confirmation Mails for Forms" this is possible. The plugin also sends the sender a mail with a selected email template. Take the opportunity and purchase directly both plugins in one bundle!


# 2. Installation

1. Download the plugin and upload the ZIP file via the plugin manager in your Shopware backend
2. Click on the install icon to install the plugin and then activate it
3. The plugin installation creates a new attribute field for forms. Open a form in the backend under "Content -> Forms" and check whether the new free text field is available in the "Free text fields" area.


# 3. Configuration

Under "Configuration -> Email templates" or from Shopware 5.6 under "Configuration -> E-mail management -> Email templates" you can create new templates for your forms in the folder "User emails". In this templates you have access to different variables. For example the names of the fields of the form and the values submitted by the customer. For example, if you link a template to the standard Contact Form, the following variables are available:

{$sShop}: Shopware Demo\
{$sShopURL}: <http://example.com\\>
{$momoFormData.anrede.label}: Anrede\
{$momoFormData.anrede.value}: Herr\
{$momoFormData.vorname.label}: Vorname\
{$momoFormData.vorname.value}: Moritz\
{$momoFormData.nachname.label}: Nachname\
{$momoFormData.nachname.value}: Müller\
{$momoFormData.email.label}: eMail-Adresse\
{$momoFormData.email.value}: <moritz@momocode.de>\
{$momoFormData.telefon.label}: Telefon\
{$momoFormData.telefon.value}:\
{$momoFormData.betreff.label}: Betreff\
{$momoFormData.betreff.value}: Kontaktanfrage\
{$momoFormData.kommentar.label}: Kommentar\
{$momoFormData.kommentar.value}: Sehr geehrte Damen und Herren...

So you can see that per field you can access the label and the value sent by the sender. As of version 1.1.0 of the plugin, fields of type "text2" are also supported. For example, if the field has the name "plz;ort" with the label "Postal Code ; City", the following variables are available separately in the e-mail template:

{$momoFormData.plz.label}: Postal Code\
{$momoFormData.plz.value}: ...\
{$momoFormData.ort.label}: City\
{$momoFormData.ort.value}: ...

If your field names contain special characters or umlauts, the variables must be built into the template as follows:

{$momoFormData\['straße'].label}: Street\
{$momoFormData\['straße'].value}: Hauptstraße\
{$momoFormData\['nationalität'].label}: Nationality\
{$momoFormData\['nationalität'].value}: German

Once the email template is created, you can link it to the form by selecting it in the free text field of the form. For forms where nothing is selected in the free text field, the normal plain text email maintained with the form will continue to be sent.

As it is the case with the plain text email, the email is then sent to the email address that is maintained with the form.


# Confirmation Mails for Forms


# 1. Description

Since the current Shopware 6 version does not yet have individual forms, but only the contact and newsletter form, this app is, in contrast to the Shopware 5 version, only limited to the contact form. For the newsletter form there is already a mail to the sender of the form by default. As soon as individual forms are possible in Shopware 6, the app will be extended and the restriction to the contact form will be removed.

If a visitor sends the contact form, only the shop owner receives an e-mail with the summary by default. With this app you get the possibility to send automatic confirmation mails to the sender, if he has filled out and sent the contact form.

You can create any e-mail templates via the Shopware Administration and link them to your contact form via the form configuration. In the e-mail templates, you can access the values filled in by the sender if you want to refer to them in the e-mail. In contrast to the Shopware 5 version of the app, in this version unfortunately the labels of the form fields in the e-mail are not available as variables, but only the filled in values. The e-mail to the sender is sent to the address that he/she entered in the e-mail field of the contact form.

If you do not select an e-mail template for your contact form, no e-mail will be sent to the sender.

The app is also compatible with sub- and language shops. If the appropriate translation is available for the email template, the sender will receive the confirmation email in the language that is configured for the shop in which he is currently located.


# 2. Installation

1. Download the app and upload the ZIP file in the plugin manager of Shopware Administration
2. Install the app via the buttons and activate it afterwards


# 3. Configuration

A new type for e-mail templates was created by the app installation. You can now create any e-mail templates for your contact form in the administration under "Settings -> Email templates". It is important that the new type "Form confirmation to customer" is selected as "Type". You can configure the remaining settings as you wish. It is not necessary to select a sales channel for the e-mail template. In the mail text you have access to the values sent by the sender. For the contact form these are the following variables:

`{{ contactFormData.firstName}}`: Moritz\
`{{ contactFormData.lastName }}`: Müller\
`{{ contactFormData.email}}`: <moritz@momocode.de>\
`{{ contactFormData.phone}}`: 123456789\
`{{ contactFormData.subject}}`: Question regarding "XY"\
`{{ contactFormData.comment}}`: Hello! I have a question about article "XY"...\
`{{ contactFormData.salutation.salutationKey }}`: mr\
`{{ contactFormData.salutation.displayName}}`: Mr\
`{{ contactFormData.salutation.letterName}}`: Dear Mr.

So you can see that for each field you can access the value sent by the sender.

To link the e-mail template to your contact form now and thus activate the confirmation e-mail to the customer, you must proceed as follows:

Go to "Content -> Shopping Experiences" in the Shopware Administration. Now you have two possibilities to create a new layout with a contact form. Either you duplicate the locked standard template "Default shop page layout with contact form" and edit the newly created template, or you go to "Create new layout", then select "Shop page" and enter the other configurations requested. If you have duplicated the standard template, the contact form already exists as a block. If you have created a new layout, you have to click on the + in the right column, then select "Form" under "Block Category" and drag the form element to the left into the preview area. If you now click on the element and move the mouse over it, a cogwheel symbol appears in the upper right corner of the element. When you click on the icon, a popup appears with the form settings. If the form "Contact" is selected in the tab "Content" under "Form type", the tab "Confirmation Mail" added by the app also exists. If you switch to this tab, you can select the previously created e-mail template there. The subject of the e-mail template is displayed in the selection field, as this is the most meaningful mandatory field for e-mail templates. Please note that the selection field only offers e-mail templates of the type "Form confirmation to customers". Now select your e-mail template and click on "Done" and save the layout. For further use of the layout please follow the Shopware documentation.


# Confirmation Mails for Forms of CMS-Extension


# 1. Description

When a visitor submits a form (of the CMS extension), by default only the shop owner receives an email with the summary. This app gives you the option of sending automatic confirmation emails to the sender when they have completed and sent the form.

The configuration for the confirmation emails takes place via the Flow Builder. The app provides a trigger for the flow builder for each individual form. You can therefore create a separate flow for each form, select one of the triggers provided by the plugin and then configure the email dispatch as the action. You have various options for sending emails, including the confirmation email to the sender. The email is then sent to the address that the sender has entered in the email field of the form.

You can create any email templates via Shopware Administration and select them for email dispatch in the Flow configuration. In the email templates, you can access the values filled in by the sender if you want to refer to them in the email.


# 2. Installation

1. Download the app and upload the ZIP file in the extension manager of Shopware Administration
2. Install the app via the buttons and activate it afterwards

**Note:**

Before you can install the app, the CMS extension must be installed and activated.


# 3. Configuration

As soon as you have created a new form of the CMS extension, a new trigger is automatically provided in the Flow Builder. To activate the confirmation email, you must first create a new flow in the Flow Builder. You can then select the trigger of the form and select "Send email" as the action. In the action settings, you can then select the option "Form confirmation" under "Recipient". This will send the email to the address specified by the sender in the form. It is important that there is a field in the form with the internal name "email", as the confirmation email will then be sent to the address entered in this field.

You can choose any template as an email template. If you want to refer to the data sent by the sender in the template, you can use the same variables that are available in the template for the email to the shop owner. You can copy these from the email template with the type "Custom Form" that was created by the CMS extension.

**Attention:**

If you change the internal name of a form for which a flow has already been configured, you must then reconfigure the flow, as the triggers are based on the internal names of the forms and the old name is then still stored as the trigger of the flow. Such flows are then automatically deactivated as long as they have not been updated.


# Shop the Look


# 1. Description

This app offers you the possibility to place a "Shop the Look" element on product pages. With this element you can present the customer directly on the product page a selection of looks that match the visited product. This encourages the customer to buy additional products.

It was tried to make the maintenance of the looks as comfortable as possible. There are different ways and automatisms to create looks. For example, it is possible to create a look for one variant and then automatically create it for all other variants that have, for example, the same color but a different size. Alternatively, it is also possible to create looks only for the main product and automatically display them for all variants of the product. More about the different possibilities can be found in the configuration part of this documentation.

In addition to the options for automatic adoption of looks within a product, there are two different types of looks that can be used depending on the desired use case. The first type is "Global Looks". Global looks can be created in a new tab for the product configuration or via an extra module. You can define an internal name for the look and the products that belong to the look. The look is then automatically displayed on the product pages of all products contained in the look.

In the second procedure, looks can be created individually for a product. This is also done via the new tab for the product configuration. Here you can now also create looks with internal names and contained products. The difference to the first procedure is that this look is then only created for the current product and not for the other products contained in the look. This can be used, for example, if you want to create a look for exactly the products in the product image, but the linked products do not have these products in the product images and therefore this look should not exist for them.

For the "Shop the Look" element on product pages, various settings can be made, such as the position or product layout within the element. These settings can be maintained via another new module in the administration. In addition to the global configuration, these settings can also be individually adjusted for a product using the new tab in the product configuration.

On the "Shop the Look" element on the product page, the customer has the option of clicking a button to go to an extra page on which all the products of the Look are displayed again. This page exists as a experience world, so you can customize the page via the administration.

The structure and look of the "Shop the Look" element on the product pages was developed based on the standard Shopware theme. All requirements have been met so that the element can be easily extended and redesigned according to your wishes in your own theme. You are welcome to test the app by purchasing a trial version and check the feasibility of your change requests.


# 2. Installation

1. Download the app and upload the ZIP file in the app manager of Shopware Administration
2. Install the app via the buttons and activate it afterwards


# 3. Configuration

After the app has been installed, the basic settings must first be configured. Since the normal app configurations could not yet be translated at the time of the development of the app, an extra module for the administration was developed. This can be found in your administration under "Settings", then in the left submenu on "Plugins" or from Shopware 6.4 on "Extensions" and there on "STL - Configuration". Here you can make the following settings.

## 3.1 General

### 3.1.1 Inheritance

With the help of automatic inheritance, looks of the root product are always displayed for all variants as well. A classic use case would be that you have products in different sizes. Since the size of a product should usually not play a role in a look and a look should therefore apply to all sizes, it is sufficient in this case to activate the inheritance and create the look for the root product. The look is then automatically displayed for all size variants. Thus, the look does not have to be created separately for each size variant.

However, looks that are created in the root product and transferred to the variants by inheritance are not displayed in the administration for the variants in this case. It is possible that different looks are displayed for a variant in the administration than for the root product. Nevertheless, the looks of the root product are displayed on the product page of the variant. So, theoretically, you can still create certain looks only for variants, but they will not be displayed in the store until the inheritance mode is disabled.

This mode is not so good, for example, if your products also have different colors. This is because the color usually plays a role within a Look. Thus, for example, a Look applies to the blue variant, but not to the red variant. In this case, it would not make sense for the same Look to be displayed for all variants. However, there is an automation for this. You can find out more about this under "Properties for automatic looks".

### 3.1.2 Properties for automatic looks

This configuration is only active if you have not activated inheritance. Here you can select properties for which looks should be automatically applied to variants with the same value in this property. This makes sense, for example, if your products have different colors and different sizes. In this case, it would make sense to select the "Color" property in this configuration. If, for example, a look is created for the variant "Red - XL", this look will also be created for all variants that are also red, i.e. that have the same value in the "Color" property. Since the color can play a role in the Look, this is a good way to create a Look automatically for all sizes of a color. Since the size usually does not play a role in a Look, it would not make sense here to select the "Size" property. Because then the Look would be applied to all other colors with the size "XL", which doesn't make much sense for the Look.

Note that the properties available for selection here are not specified by the app, but by your store. So here you will see all the properties you have created under "Catalogues -> Properties".

In contrast to the automatic inheritance (see above), the looks adopted with this logic are also displayed in the administration at the corresponding variants. However, the look can only be edited at the variant where it was originally created.

If after some time of app usage you consider adding another property or removing a property, you can then click the "Reassign looks based on current selection" button. Previously automatically applied looks will then first be deleted and then a new assignment will be performed based on the currently selected properties.

## 3.2 Shop the Look Element

The settings for the Shop the Look element can initially be maintained globally here and then also customized individually for products.

### 3.2.1 Activate Shop the Look on product page

Here you can globally activate or deactivate the display of the "Shop the Looks" element on product pages with just one checkbox.

### 3.2.2 Show cover of currently visited product next to slider

Here you can specify whether the cover of the currently visited product should still be displayed next to the Look slider in the "Shop the Look" element. Depending on where the element is placed, it is recommended to activate this option so that you always have the entire Look in view.

### 3.2.3 Headline

Here you can optionally define a headline that will be displayed above the "Shop the Look" element. Note that this field must be filled in per language.

### 3.2.4 Position on the product page

Here you can specify the position of the "Shop the Look" element on the product page. The choices are currently "Above the Tabs" and "Below the Tabs". In this case, "Tabs" means the tabs on the product page where, for example, the description and ratings are located.

### 3.2.5 Product Box Layout

Here you can define how the products of a look should be displayed within the "Shop the Look" element. The following options are available:

* **Image Only (Plugin)**: This is a layout provided by the app that displays only the cover image of the products.
* **Custom Layout**: This allows you to select a custom layout. As soon as the option is selected, a new text field appears in which you can enter the name of your custom layout. The template of the custom layout must then exist according to the original templates (same path and structure of the name) in an own theme or app. For example, if the template is called "storefront/product/card/box-image-with-button.html.twig", "image-with-button" must be entered in the text field for the custom layout. Tip: The layouts "standard", "image" and "minimal" from Shopware can also be used. These were deliberately not included as an option here, as they did not meet the Responsive requirements for Shopware apps within the "Shop the Look" element. If you still want to use the layouts, you can write their names in the custom layout field.

## 3.3 Shop the Look Page

### 3.3.1 Shop page for "Shop the Look" page

Here you can select the experience world to be used for the "Shop the Look" page. Only the default template from the app is available here, or your own templates that you have duplicated from the default template. For more on customizing the "Shop the Look" page, see "Customize the Shop the Look Page" below.

## 3.4 Customize Shop the Look page

You can get to the "Shop the Look" page in the store after clicking on the "To Look" button in the "Shop the Look" element. On this page all products of the look are listed again. You can customize this page. To do so, go to "Content -> Shopping Experiences" in the administration. In the category "Shop pages" you will find the layout "Default "Shop the Look" page". You cannot edit this layout directly. Click on the small menu icon next to the layout and duplicate the layout. Now click on the duplicated layout. First click on the gear icon and choose a different layout name and then save the layout. Now you can, for example, edit the text element or place other elements in other locations. Note that the "Shop the Look Product listing" block cannot be deleted. This takes care of the output of the Look's products. However, you can open the block's settings and customize the layout type for the product boxes, for example. After you have customized your layout, you need to select it in the basic settings. To do this, go to "Settings -> Plugins / Extensions -> STL - Configuration" again. In the field "Shop page for "Shop the Look" page" your layout is now available.

## 3.5 Note about inactive and sold out products in Looks

In the "Shop the Look" element on the product page and on the look page, inactive products are not displayed. For sold out products, it depends on your shop settings. In the administration, under "Settings -> Shop -> Products", you can determine whether products without stock should be hidden. This app is also based on this setting. If the setting is active, no sold out products will be displayed in looks.

If it happens that a look can no longer display a valid product, then the entire look will be hidden.


# 4. Maintain Looks

After the basic settings have been saved, the looks can be created. This is not possible before.

## 4.1 Creating Looks

### 4.1.1 New module for global looks

For global looks, there is a new module in the administration, which can be found under "Settings", then on the left in the submenu on "Plugins" or from Shopware 6.4 on "Extensions" and there on "STL - Global Looks". Before global looks can be created, the basic settings must first be configured (see 3. Configuration). In addition, the system language must be selected. Clicking on "Create look" opens an area where you can maintain a name, which is only used for internal identification of the look, and the product assignment. Both root articles and variant articles can be added to the look. After clicking "Save", the look will be saved and assigned to all products contained in the look.

You can also edit existing looks by clicking on the menu icon in the corresponding row in the table and then clicking on "Edit". Now you can add, delete or change the position of products. When products are deleted, the look is also removed from them. When new products are added, this look will be assigned to them as well. You can also delete entire looks via the menu icon in the corresponding row.

Via the menu icon in the table header you can deactivate the "Compact View", which should be activated by default. In the compact view, only the names of the products are displayed in the column "Products" and if you deactivate the compact view, the cover images of the products are displayed. Choose the one that suits you more.

### 4.1.2 Individual looks, global looks and settings in new tab of product configuration

If you want to create a look or settings specifically for a product, you can go to "Catalogues -> Products" in the Administration and click on the desired product. Then go to the "Shop the Look" tab. This tab also exists when you are editing a specific variant of a product. For example, you can assign different looks to different color variants.

If you want to make individual settings for this product, activate the checkbox "Use individual configuration for this product". You can then make the settings and save the product at the end. If you want the product to take the default settings again, you have to uncheck the "Use individual configuration for this product" checkbox again and save it again. If you change something in the global settings, this is of course not automatically applied to the individual settings. For these, you may have to apply the setting again separately. Individual settings can only be maintained for the root product, not for variants. However, the variants then inherit the settings of the root product.

If you want to add individual looks for the product that only apply to the product and not to the other products contained in the look, you can also do this in the "Shop the Look" tab in the product configuration. To do this, switch to the system language and then click on "Create Look" in the "Looks" section and make the settings. Make sure that the "Global Look" checkbox is not active, so that the look is only created individually for the current product. Note that the currently configured product is always already included in the look and cannot be deleted. When you click on "Save", the look is saved directly, so you do not have to save the product again. The Look will then only be displayed in the "Shop the Look" element on the product page for this product. You can also delete looks, edit looks and use the search function to find looks by internal name or product name. You can also specify the position of the looks within the "Shop the Look" element on the product page.

You can also create global looks in the same way. For this, you just need to check the "Global Look" checkbox. The look will then be applied to all products contained in the look. The position of the look will be the last position of each product. In order to place the look in a different position for each product, you have to call up all products and change the position accordingly and then save the product.

Note also the different automatisms, which are explained under "3. Configuration".


# Redirect to previous page after login


# 1. Description

This app gives you the option to redirect the customer back to the previous page after login, instead of redirecting to the home page of the account area. In doing so, you can specify for which type of pages this function should be active, so that, for example, there is only a redirect to the previous page if the customer was on a product page before logging in.

You can enable login redirection for the following page types. If the customer goes to the login from one of these pages and you have enabled the redirection for this page type, then the customer will be redirected back to this page after login.

* Home Page
* Category Pages
* Search Pages
* Product Detail Pages
* Cart Page
* Wishlist Page
* Landingpages

Note: The redirection only works for the normal login under "/account/login". If someone clicks on "Proceed to checkout" in the shopping cart, he comes to the page "/checkout/register". If he logs in there, the logic of the plugin does not apply, so in that case after the login he is still forwarded to the checkout.


# 2. Installation

1. Download the app and upload the ZIP file in the app manager of Shopware Administration
2. Install the app via the buttons and activate it afterwards


# 3. Configuration

After the app has been installed, you need to open the app configuration.

### Classification of cookies

The app uses cookies, you can determine whether the login redirect should be classified as technically necessary or as a comfort function. If you classify it as technically necessary, the redirect is always active, without explicit consent of the customer. If you classify it as a comfort function, the customer must first allow cookies in the Cookie Consent Tool in order for login redirect to work for them. If you are unsure how the function should be classified in your case according to the data protection regulations best to contact a data protection advisor.

### Redirect for different page types

You can now enable login forwarding for the following page types:

* Home Page
* Category Pages
* Search Pages
* Product Detail Pages
* Cart Page
* Wishlist Page
* Landingpages

For example, if you now enable only the "Product Detail Pages" page type, then login redirection will take place only if one went to the login from a product detail page. If one went to the login from one of the other pages, then it will redirect to the account area home page.

How to add page types in a custom plugin, if necessary, can be found in [4. Add custom page types](https://docs.momocode.de/v/en/shopware-6/login-redirect/4.-custom-page-types).


# 4. Add custom page types

The following describes how you can activate additional page types for login forwarding in your own plugin. This might be necessary if a standard Shopware page type you use is not yet supported by the plugin, or if you have already added new pages in your own plugin or through a third-party plugin. For this tutorial you need programming knowledge.

## 4.1 Create a Subscriber

First you need to create a subscriber anywhere in your plugin. Here is a complete example first and further below the example is explained:

```php
<?php declare(strict_types=1);

namespace MyPlugin\Subscriber;

use Momocode\MomoLoginRedirectSW6\Redirect\Event\RedirectActiveCheckEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class LoginRedirectSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [
            RedirectActiveCheckEvent::class => 'onRedirectActiveCheck',
        ];
    }

    public function onRedirectActiveCheck(RedirectActiveCheckEvent $event): void
    {
        if ($event->getRoute() === 'frontend.home.page') {
            $event->setIsActive(true);
        }
    }
}
```

The example describes the page type "Home Page", which already exists in the plugin. However, you can integrate any other page type according to this logic. The subscriber reacts to the "RedirectActiveCheckEvent". This is triggered after logging in and when the plugin checks if a redirect to the previous page is enabled for this page type. In the example, it then checks if the route stored in the event (the page called before login) is the route "frontend.home.page". This is the Symfony route of the home page. If it is this route, the event will store the information that the redirection to this page should be active. You can include any logic here, and you can also override the plugin's logic for individual routes so that the plugin configuration is ignored and your own logic is executed. You should find the exact name of your route in the corresponding controller of your page type.

## 4.2 Register your Subscriber

Now you only have to register your subscriber in the service container. To do this, add the following entry to your `services.xml`:

```xml
<service id="MyPlugin\Subscriber\LoginRedirectSubscriber">
    <tag name="kernel.event_subscriber"/>
</service>
```

**Note:** If you are not familiar with Shopware plugin development and absolutely need a new page type, feel free to contact me at <moritz@momocode.de>.


# 5. Custom Login Page

If you have programmed your own login page on which the Shopware login form is integrated, you must add another code extension to your shop so that the login redirect also works with your login page. The app offers a corresponding option for this from version 2.1.0. Below is a description of what needs to be done.

## 5.1 Create a Subscriber

First you need to create a subscriber anywhere in your plugin. Here is a complete example first and further below the example is explained:

```php
<?php declare(strict_types=1);

namespace MyPlugin\Subscriber;

use Momocode\MomoLoginRedirectSW6\Redirect\Event\RedirectLoginRoutesEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;

class RedirectLoginRoutesSubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [
            RedirectLoginRoutesEvent::class => 'onRedirectLoginRoutes',
        ];
    }

    public function onRedirectLoginRoutes(RedirectLoginRoutesEvent $event): void
    {
        $routes = $event->getLoginRoutes();
        $routes[] = 'frontend.account.custom-login.page';
        $event->setLoginRoutes($routes);
    }
}

```

The subscriber responds to the "RedirectLoginRoutesEvent". This is triggered when a shop page is visited and the app checks whether it is the login page and thus the redirect parameters must be set. In the example, the previously set login routes (by default only "frontend.account.login.page") are then first stored in an array variable, then the route name of your own page is added and the finished array is then passed to the event. Thus, your own login page will also be recognized as such and thus the redirect parameters will be set.

## 5.2 Register your Subscriber

Now you only have to register your subscriber in the service container. To do this, add the following entry to your `services.xml`:

```xml
<service id="MyPlugin\Subscriber\RedirectLoginRoutesSubscriber">
    <tag name="kernel.event_subscriber"/>
</service>
```

**Note:** If you are not familiar with Shopware plugin development and need help enabling redirection for custom login pages, feel free to contact me at <moritz@momocode.de>.


# Shopware Update Notifications (App)


# 1. Description

With this app you have the possibility to be notified by mail and/or by notification in the administration when your store has been updated to a new Shopware version.

This extension is mainly intended for cloud stores, as they are updated automatically and you have no influence on the timing of the updates. With the app, you will then be notified immediately and then you can directly test the important processes in your store and, if necessary, react quickly in case of errors.

By configuration, the mail and administration notification can be enabled or disabled separately. Since the administration notification is only displayed for a few seconds (the app has no influence on this), we recommend activating the mail notification. For the mail dispatch you can configure as many recipients as you like.


# 2. Installation

1. Download the app and upload the ZIP file in the app manager of Shopware Administration
2. Install the app via the buttons and activate it afterwards


# 3. Configuration

After the app is installed, you need to open the app configuration.

### General configuration

#### Language

Select here the language in which you want to receive the notifications.

### Notifications

#### Activate admin notifications

If you enable this option, you will receive a notification in the administration. However, since this is only displayed by Shopware for a few seconds and can therefore be quickly lost, we recommend activating the email notification.

#### Activate mail notifications

If you enable this option, you will receive an email notification to the email addresses configured under "Mail recipients".

#### Mail recipients (comma separated)

Please write in this field all e-mail addresses separated by comma, which should receive the e-mail notification.


# Percentage Based Advanced Pricing


# 1. Description

## Manage Advanced Prices with Percentage Discounts

**Percentage Based Advanced Pricing** lets you define tiered prices and customer-specific prices using simple percentage values. Enter your desired discount and the price is calculated automatically.

## The Problem

Shopware's advanced prices are a powerful tool for tiered pricing and B2B pricing strategies. However, all prices must be entered as absolute values. This creates ongoing maintenance overhead:

* Every base price change requires manual recalculation of all advanced prices
* Percentage-based discount structures (e.g., "10% discount from 10 units") must be manually converted to absolute prices
* Error-prone and time-consuming when managing many products

## The Solution

This plugin adds a **percentage column** to the advanced prices table in the Shopware Administration. Enter the desired discount as a negative percentage value (e.g., `-10` for a 10% discount) — the absolute price is calculated and saved automatically.

![Advanced prices table with percentage column](/files/jaMByJrFHR5z5kTuIyAg)

## Automatic Recalculation

When you update a product's base price, all percentage-based advanced prices are **automatically recalculated**. Your discount structures stay consistent without any manual effort.

## Flexible Calculation Base

For each price type (price, list price, regulation price) you can individually choose whether the percentage is calculated from the **sale price** or the **purchase price**. This enables scenarios like "list price = purchase price + 20%".

![Base selection toggle for sale price and purchase price](/files/9zYULmXeeLELbSoLZxhn)

## Feature Overview

| Feature             | Description                                                    |
| ------------------- | -------------------------------------------------------------- |
| Percentage column   | New input column in the advanced prices grid                   |
| Instant calculation | Price is calculated as soon as you enter a percentage          |
| Calculation base    | Choose between sale price and purchase price per price type    |
| Automatic updates   | Recalculation when sale price or purchase price changes        |
| Bulk edit support   | Apply percentage prices to many products at once via bulk edit |
| Multi-currency      | Works with all configured currencies                           |
| Console command     | Bulk recalculation of all percentage prices                    |
| Clean uninstall     | Plugin data is fully removed on uninstall                      |

## Ideal for B2B

Percentage-based discount structures are standard in B2B. With this plugin, you can finally manage customer group prices and tiered prices the way you think about them — in percentages.

## Compatibility

* Version 1.x.x: Shopware 6.6
* Version 2.x.x: Shopware 6.7
* Seamlessly integrated into the existing Administration
* No storefront changes required


# 2. Installation

## Installing the Plugin

1. Purchase and download the plugin from the **Shopware Store**
2. Open the Shopware Administration and go to **Extensions → My Extensions**
3. Find **Percentage Based Advanced Pricing** in the list
4. Click **Install**
5. After installation, click **Activate**
6. Clear the cache under **Settings → System → Caches & Indexes → Clear cache**

## Getting Started

Once activated, the percentage column is immediately available in the advanced prices table for all products.

1. Open any product under **Catalogues → Products**
2. Navigate to the **Advanced prices** tab
3. You will see a new **Percentage** column in the pricing table

![Advanced prices tab with percentage column](/files/jaMByJrFHR5z5kTuIyAg)

## Verification

The plugin is correctly installed if:

* The **Percentage** column appears in the advanced prices table
* Entering a percentage value automatically calculates and fills in the price
* The base toggle (sale price / purchase price) is visible next to the percentage field

## Uninstalling

1. Go to **Extensions → My Extensions**
2. Deactivate the plugin
3. Click **Uninstall**

When uninstalling, you have two options:

* **With "Remove all app data permanently":** The database table with all stored percentage values is completely removed. Absolute product prices are not affected.
* **Without this option:** The percentage data remains in the database. If you reinstall the plugin later, all previously configured percentage values will be available again.


# 3. Configuration

This plugin has no system-wide settings. The percentage pricing feature is available immediately after installation on the **Advanced prices** tab of every product.

## Defining Percentage-Based Prices

### Step by Step

1. Open a product under **Catalogues → Products**
2. Navigate to the **Advanced prices** tab
3. Click **Add price** or edit an existing price row
4. Enter a value in the **Percentage** column:
   * Negative value → discount (e.g., `-10` for 10% off)
   * Positive value → markup (e.g., `5` for 5% above base price)
5. The absolute price in the **Price** column is calculated automatically
6. Click **Save**

![Price row with percentage value and calculated price](/files/jaMByJrFHR5z5kTuIyAg)

### Input Notes

* Enter plain numbers — no % symbol required
* Positive values increase the price, negative values reduce it
* Existing advanced prices without a percentage value are not affected
* All configured currencies are handled correctly

## Choosing a Calculation Base

For each of the three price types (price, list price, regulation price), you can separately choose whether the percentage is calculated from the product's **sale price** or **purchase price**.

### How the Base Selection Works

Next to each percentage input field, you will see a toggle with two options:

* **Sale price** (default) — calculation uses the product's regular sale price
* **Purchase price** — calculation uses the product's purchase price

![Base toggle next to the percentage field](/files/9zYULmXeeLELbSoLZxhn)

### Example

To define the list price as "purchase price + 20%":

1. Select **Purchase price** as the base for the list price percentage
2. Enter `20` as the percentage value
3. The list price is automatically calculated as purchase price + 20%

### Notes

* The base selection is **always visible**, even before entering a percentage value
* If you select **Purchase price** as the base but no purchase price has ever been set on the product, the calculation is skipped and the existing price remains unchanged. Note: once a purchase price has been entered, clearing the field in the admin sets it to `0` — in that case the calculation runs normally using `0` as the base
* When a product's purchase price changes, all percentage prices using "purchase price" as their base are automatically recalculated

## List Price Field Visibility

When you disable the **Show list prices** toggle in the advanced prices grid, the percentage input fields for list price and regulation price are automatically hidden as well. Only the standard price percentage field is shown.

Re-enabling the toggle restores the fields with their previously entered values — no data is lost.

## Bulk Edit

You can also apply percentage prices to many products at once using Shopware's **bulk edit** feature:

1. Select multiple products under **Catalogues → Products**
2. Click **Bulk edit**
3. Open the **Advanced prices** section
4. Enter the desired percentage values
5. Fill in the absolute price fields with a placeholder value (e.g., `0`)
6. Confirm the bulk edit

The absolute prices are **automatically calculated server-side** for each product individually — based on each product's actual base price. You do not need to open each product separately.

![Bulk edit with percentage values filled in](/files/YkDVQB0Wwdt7ZstCFRu8)

### Bulk Edit Notes

* The instant calculation in the UI is disabled during bulk edit since no single base price is available
* Server-side calculation runs immediately after saving
* You can set both percentage values and calculation base (sale price / purchase price) in bulk edit

## Automatic Recalculation

Absolute prices are automatically recalculated in the following situations:

| Trigger                                     | Effect                                                                 |
| ------------------------------------------- | ---------------------------------------------------------------------- |
| Product's sale price changes                | All percentage prices using "sale price" as base are updated           |
| Product's purchase price changes            | All percentage prices using "purchase price" as base are updated       |
| Percentage value saved via bulk edit or API | Absolute prices are immediately calculated from the current base price |

## Bulk Recalculation (Console Command)

To force a recalculation of all percentage-based prices — for example after a data import or a bulk price update:

```bash
bin/console momo:percentage-prices:recalculate
```

This command recalculates the absolute prices for all percentage-based advanced prices across all products, using the current base prices. The configured calculation base (sale price / purchase price) is respected.

**When is this useful?**

* After a data import that changed base prices
* To verify all prices are up to date
* After migrating from another Shopware version

## How It Interacts with Existing Prices

The plugin extends Shopware's existing pricing — it does not replace it:

* Advanced prices without a percentage value continue to work as before
* Percentage-based and absolute prices can coexist in the same pricing table
* Only rows with a percentage value are automatically recalculated


# Media Cleanup Dashboard


# 1. Description

Unused media files accumulate in every Shopware store over time — especially after product imports, layout changes, or manufacturer logo updates. While Shopware includes the `media:delete-unused` CLI command, most merchants don't have server access to run it.

**Media Cleanup Dashboard** brings this functionality directly into the Shopware Administration: a visual dashboard that safely identifies, displays, and deletes unused files — no command-line access required.

![Start view with "Start scan" button](/files/1so04pXIbaspEsMXmfBh)

## Features at a Glance

### Dashboard with File List

The dashboard displays all unused media files in a paginated list — with a preview thumbnail (or a file-type icon for PDFs, videos, etc.), file name, type, size, and upload date. A summary bar at the top shows the total file count and combined storage size at a glance.

### Async Background Scan

As of version 1.1 / 2.1, the scan runs asynchronously in the background — no HTTP timeout, even for very large media libraries. Results appear immediately once the scan completes. Results are cached for up to 4 hours: page navigation and delete operations never trigger a full re-scan. The **Rescan** button refreshes results on demand at any time.

![Result list with unused media files after the scan](/files/ZObCfRG5jzoISh6VBf5W)

### Bulk Selection and Safe Deletion

Select individual files via checkbox or use "Select all" — even across multiple pages. Before any deletion, a confirmation dialog shows the number of files and total size. A progress indicator is displayed during deletion; the result (deleted / skipped / failed) is reported in detail when complete.

In addition, the plugin performs a real-time last-mile verification immediately before every deletion — checking whether a file has been re-assigned since the scan — so no actively used files are ever deleted.

![Confirmation dialog before deleting](/files/RajuCTYS44Gb4UxafPD4)

### Filters and Sorting

Filter the list by file type (image, video, document, other), minimum file size, or upload age. Sort by file name, file size, or date — ascending or descending. A single click resets all active filters.

![File type filter "Image" applied](/files/YCBbO9ZirGn8RUMaD1Dn)

### User Permissions (ACL)

The plugin adds two separate privileges:

* **momo\_media\_cleanup:read** — access to the dashboard and the unused media list
* **momo\_media\_cleanup:delete** — permission to delete unused media files

Staff can review the list without having delete access.

## Technical Details

| Property               | Value                                                               |
| ---------------------- | ------------------------------------------------------------------- |
| Shopware compatibility | 6.6.x and 6.7.x                                                     |
| PHP                    | 8.2+                                                                |
| External services      | None — the plugin communicates only with your own Shopware instance |
| Database migrations    | None — the plugin does not create any custom tables                 |
| Background scan        | Async via Symfony Messenger (requires a running worker)             |


# 2. Installation

## Install the Plugin

1. Download the plugin from the Shopware Store or as a ZIP file.
2. In the Shopware Administration, navigate to **Extensions → My Extensions**.
3. Click **Upload extension** (for ZIP installation) or find the plugin in the list.
4. Click **Install** and then **Activate**.
5. No database migration is required — the plugin does not create any custom tables.

## Getting Started

1. Navigate to **Content → Media Cleanup** in the Administration.
2. Click **Start scan** to begin the analysis. The scan runs in the background — you can wait for the results or leave the page and return later.
3. Once the scan is complete, the list of unused media files appears. Results remain valid for 4 hours — page navigation and delete operations do not trigger a full re-scan.
4. Use the filters (file type, minimum size, age) to narrow down the results.
5. Select individual files via checkbox or click **Select all**.
6. Click **Delete selected** — a confirmation dialog appears showing the count and total size.
7. Confirm the deletion. The result (deleted / skipped / failed) will be displayed.
8. To refresh results, click **Rescan**.

## Setting Up User Permissions

The plugin adds two ACL privileges. To grant access to staff members:

1. Navigate to **Settings → System → Users & Permissions → Roles**.
2. Select the desired role (or create a new one).
3. Find **Media Cleanup** in the permissions section.
4. Assign the required privilege(s):
   * **Read** — access to the dashboard and the unused media list
   * **Delete** — permission to delete unused media files
5. Save the role.

## Notes

* Compatible with Shopware 6.6.x and 6.7.x (PHP 8.2+). Version 2.x supports Shopware 6.7, version 1.x supports Shopware 6.6.
* The plugin communicates only with your own Shopware instance — no external services.
* The async background scan (from version 1.1 / 2.1) requires a running Symfony Messenger worker. Without an active worker, the scan runs synchronously in the HTTP request — timeout protection for very large media libraries is not active in that case.
* Deleted files cannot be recovered. Please review your selection carefully before confirming.
* For very large media libraries, consider using the filters to process deletions in smaller batches.
* **Detection is based on Shopware's native logic:** The plugin uses Shopware's built-in unused media detection — the same logic that powers the `media:delete-unused` CLI command. The plugin is not responsible if Shopware classifies a file as unused that is still in use. Always review your selection carefully before deleting.

## Support

If you have questions or issues, please use the Shopware support tool or contact us at <moritz@momocode.de>.


# Admin Category Tree Memory


# 1. Description

Shops with many categories know the problem: the Shopware admin category tree loads fully expanded by default — hundreds of entries at once, hard to navigate, endless scrolling. The **Admin Category Tree Memory** plugin solves this by starting the tree collapsed and remembering what you last had open.

![Collapsed category tree with Catalogue #1 and Catalogue #2](/files/ueoi87TVYeNR9AxhD90D)

## Features

### Start collapsed — configurable depth

Set your preferred starting depth in the plugin configuration:

* **Depth 0** — only root categories visible (default)
* **Depth 1** — first level expanded (native Shopware behaviour)
* **Depth 2** — first two levels expanded
* **Depth 99** — fully expanded (can lead to performance issues if there are many categories)

### Automatic state persistence

Every time you expand or collapse a branch, the plugin saves your personal state in the browser (localStorage). The next time you open the category management, you see exactly what you had open before — no manual re-expanding needed.

The state is device-specific: each browser and device maintains its own independent state.

### "Collapse all" button

Click the **Collapse all** button in the category tree header to instantly collapse all open branches and save that state. A quick way to return to a clean overview at any time.

### Auto-expand to the active category

When you navigate directly to a category (via URL or search), the plugin automatically expands the path to that category and scrolls it into view — so you always know where you are in the tree.

![Auto-expanded path to an active category](/files/RhlNQSYEL0GDWB7ZEMct)

### Consistent across the admin

The plugin works in all areas of the Shopware admin where the category tree appears:

* **Catalogues → Categories** — the main category management
* **Product editing → Categories** — when assigning categories to products
* **Settings → Sales Channels → \[Channel] → General** — when selecting the navigation entry category

![Category dropdown in product assignment with collapsed categories and Collapse all button](/files/BkmcEHgOclKrNhPk2h1u)

## Technical Details

* Compatible with Shopware 6.6 (version 1.x) and Shopware 6.7 (version 2.x)
* Frontend-only plugin — no changes to backend, database, or API
* State is stored locally in the browser (localStorage) — no server communication
* No impact on shop performance or the storefront
* PHP 8.2+ required


# 2. Installation

## Installing the Plugin

### Via the Shopware Store

1. Log in to the Shopware admin.
2. Navigate to **Extensions → Store**.
3. Search for "Admin Category Tree Memory" and click **Buy** or **Download for free**.
4. After the download, click **Install**.
5. Activate the plugin using the toggle in the extension list.

### Via ZIP upload

1. Navigate to **Extensions → My Extensions**.
2. Click **Upload plugin** and select the ZIP file.
3. Install and activate the plugin.

## Getting Started

The plugin is active immediately after installation. The category tree will start collapsed by default (depth 0).

To adjust the starting depth:

1. Navigate to **Extensions → My Extensions**.
2. Click the three-dot menu on the plugin and select **Configuration**.
3. Set your preferred **Default Start Depth**.
4. Click **Save**.

## Notes

* The saved tree state is browser- and device-specific. Different browsers or devices maintain independent states.
* After uninstalling the plugin, the category tree returns to Shopware's default behavior. Any state data remaining in the browser's localStorage becomes inactive.
* Compatible with Shopware 6.6 (version 1.x) and Shopware 6.7 (version 2.x).

## Support

For questions or issues, please use the Shopware support tool or contact us at <moritz@momocode.de>.


# 3. Configuration

The plugin configuration is available under **Extensions → My Extensions → Admin Category Tree Memory → Configuration**.

![Plugin configuration page with default start depth setting](/files/pWDD7QhxikzK0jMqiypM)

## Settings

### Default Start Depth

| Setting | Value          |
| ------- | -------------- |
| Type    | Integer (0–99) |
| Default | 0              |

Defines how deep the category tree is expanded on initial load.

| Value | Behavior                                                                     |
| ----- | ---------------------------------------------------------------------------- |
| `0`   | All collapsed — only root categories visible (default)                       |
| `1`   | First level expanded (native Shopware behaviour)                             |
| `2`   | First two levels expanded                                                    |
| `99`  | Fully expanded (can lead to performance issues if there are many categories) |

This setting acts as the starting point when no saved state exists in the browser yet. Once you manually adjust the tree, your personal state takes over.


# Accessory Lock — Require Main Product


# 1. Description

**Accessory Lock** prevents customers from purchasing accessory products without having the required main product in their cart. Validation is fully server-side and cannot be bypassed via JavaScript or browser manipulation.

## What the plugin does

Some products only make sense when the matching main product is also purchased — for example, a camera strap without a camera, or a charging cable without the compatible device. The plugin lets you configure these dependencies directly in the Shopware Admin and automatically enforces them at checkout.

**Key features:**

* **Cart validation:** Accessories cannot be ordered without a matching main product in the cart. The error message names the missing product by name.
* **Admin UI:** Every product detail page gets a dedicated "Accessory Lock" tab where you can assign and review dependencies.
* **Storefront hints:** Customers are guided on accessory product pages by a "Buy Together" widget. Main product pages automatically display a compatible accessories section.
* **Variant inheritance:** Configure the lock once on the parent product — all variants inherit the setting automatically.
* **n:n relationships:** An accessory can accept multiple main products (any one of them in the cart is sufficient).

## Storefront views

### "Compatible accessories" section on the main product page

On a main product's detail page, a section with all compatible accessories is automatically displayed below the product description. Customers can add both products to the cart together with a single click.

![Compatible accessories section on the main product page](/files/jGcpXfRFX0Wg4lVAMAPD)

### "Buy Together" widget on the accessory product page

On an accessory product's detail page, a widget replaces the standard purchase area. It lists all compatible main products as selectable options. Once a main product is already in the cart, the widget switches to an adapted view — showing the in-cart product as such and revealing the standard buy button.

![Buy Together widget on the accessory product page](/files/Pg51vod5577BJrDmpLYe)

## Technical details

* Compatible with **Shopware \~6.6.0** (plugin 1.x) and **Shopware \~6.7.0** (plugin 2.x)
* Requires **PHP 8.2+**
* No external services or API connections required
* Server-side validation via `CartValidatorInterface`
* Variant inheritance via Shopware's native DAL inheritance mechanism


# 2. Installation

## Installing the plugin

### Via the Shopware Store

1. Log in to the Shopware Admin.
2. Navigate to **Extensions → Store**.
3. Search for "Accessory Lock" and click **Install**.
4. Go to **Extensions → My Extensions**.
5. Click **Activate** next to the plugin.

### Manual installation (ZIP file)

1. Log in to the Shopware Admin.
2. Navigate to **Extensions → My Extensions**.
3. Click **Upload extension** in the top right and select the ZIP file.
4. Click **Install**, then **Activate**.

## First steps after activation

The plugin is ready to use immediately after activation. No additional setup is required before you can create your first accessory locks.

1. Navigate to **Catalogues → Products** and open the product you want to lock as an accessory.
2. Click the **Accessory Lock** tab.
3. In the **"Required Main Products"** section, add at least one main product.
4. Save the product.

From this point on, the accessory can only be added to a completed order if at least one of the assigned main products is also in the cart.

## Notes

* Compatible with **Shopware \~6.6.0** (plugin 1.x) and **Shopware \~6.7.0** (plugin 2.x). Requires **PHP 8.2+**.
* On uninstall, all plugin data is removed unless you choose **"Keep user data"**.
* No external services or API connections are required.


# 3. Usage

## Assigning an accessory lock to a product

Open the product you want to lock as an accessory (not the main product). Click the **Accessory Lock** tab.

![Accessory Lock tab with assigned main products and reverse view](/files/P4g6iWFTlDXTSWbxAsLf)

### Card: "Required Main Products"

The top card shows all main products that this product requires in the cart.

1. Click the product search field and type the name of the main product.
2. Select the desired product from the results.
3. The product appears in the table immediately.
4. Click **Save** in the top right to confirm the assignment.

**Multiple main products:** You can assign multiple main products. It is sufficient for any one of them to be in the cart — the customer does not need all of them.

**Removing an entry:** Click the three-dot menu in the relevant row and select **Delete**.

**Navigate to the main product:** Click the **Go to product** button in a row to jump directly to that product's detail page.

### Card: "Used as Main Product by"

The bottom card is a read-only information view. It shows all accessory products that require the current product as their main product. To change these assignments, open the respective accessory product.

Click on an accessory product's name to navigate directly to its detail page.

## How cart validation works

Once an accessory lock is configured, the plugin checks server-side on every cart update whether the required main product is present. If it is missing, an error message appears in the cart, naming both the accessory and the missing main product. The order cannot be completed until the main product is added.

Validation is fully server-side and cannot be bypassed by disabling JavaScript or through browser manipulation.

## Storefront behavior

### On the accessory product page

Customers see the **"Buy Together" widget**, which lists all compatible main products as selectable options. Clicking **"Add together to cart"** adds both the main product and the accessory to the cart at once.

If a main product is already in the cart, the widget switches to an adapted view: the in-cart main product is labeled as such, and the standard buy button is shown.

### On the main product page

A **"Compatible accessories"** section with a product slider is automatically shown below the product description. Each accessory card includes an **"Add together to cart"** button that adds both products at once.

Whether this section is displayed is controlled by the [configuration option](https://github.com/momocode-de/plugin-gitbook/blob/en/shopware-6/accessory-lock/configuration.md) **"Show 'Compatible accessories' section"**. Cart validation works independently of this setting.


# 4. Variant Inheritance

## Basic principle

If a product has variants (for example, a cable in different colors), you only need to configure the accessory lock **once on the parent product**. All variants inherit this configuration automatically via Shopware's native DAL inheritance mechanism.

## Configuring on the parent product

1. Open the **parent product** (the base product, not an individual variant).
2. Click the **Accessory Lock** tab.
3. Assign the desired main products in the **"Required Main Products"** card.
4. Click **Save**.

All variants of this product are now automatically linked to the same main products.

## Viewing and overriding inheritance on a variant

When you open an individual variant's detail page and switch to the **Accessory Lock** tab, you will see an **inheritance switch** next to the "Required Main Products" card.

![Variant inheritance: inheritance switch in the Admin tab](/files/kAkEgMDAsvdBvK5uQ8Q9)

**While inheritance is active:**

* The table shows the parent product's assigned main products in a read-only view.
* The inheritance switch is enabled (chain icon highlighted).

**Breaking inheritance:**

1. Click the inheritance switch to disable inheritance for this variant.
2. The table switches to edit mode.
3. Assign individual main products to this variant (or leave the list empty to disable the lock for this specific variant).
4. Click **Save**.

**Restoring inheritance:** Click the inheritance switch again. The variant will resume inheriting the parent product's settings and any individual assignments are removed.

## Cart behavior with variants

The cart validator respects inheritance automatically: when checking a variant in the cart, the effective assignment is used — either the variant's own (if inheritance was broken) or the parent product's.


# 5. Configuration

The plugin configuration is located at **Extensions → My Extensions → Accessory Lock → Configuration** (or via the three-dot menu next to the plugin and **Configuration**).

![Plugin configuration page](/files/tFbkOEw7GHDWN1QPcCAg)

## Settings

### Section: Storefront

| Option                                | Default | Description                                                                              |
| ------------------------------------- | ------- | ---------------------------------------------------------------------------------------- |
| Show "Compatible accessories" section | Enabled | Controls whether a compatible accessories section is shown on main product detail pages. |

### Show "Compatible accessories" section

When enabled, a product slider with all compatible accessories is automatically displayed below the product description on main product detail pages. Customers can add both the main product and an accessory to the cart from there with a single click.

**Disabling:** If you want to hide the section — for example, because you present accessories in a different way — turn this option off. Cart validation is completely independent of this setting: accessory products still cannot be purchased without the main product in the cart, even with the section hidden.

**Per sales channel configuration:** The setting applies globally to all sales channels by default. You can select a specific sales channel at the top of the configuration page and override the setting for that channel individually.

## Customising storefront texts

All texts the plugin outputs in the storefront — including widget headings, button labels, and cart error messages — are Shopware snippets. You can customise these texts via **Settings → Snippets**.

This is particularly useful if you use a different term than "accessory" in your shop, for example "spare part", "extension", or a product-specific term.

**How to customise:**

1. Navigate to **Settings → Snippets** and select the desired snippet set.
2. Search for the key prefix `momoAccessoryLock` to filter all plugin snippets.
3. Edit the desired texts and save.


# Product Completeness & Data Quality


# 1. Description

**Product Completeness & Data Quality** analyses your product catalog and calculates a completeness score from 0 to 100% for every product. At a glance you can see which products have incomplete descriptions, missing images, or insufficient SEO metadata — and where there is room to improve conversions.

## What the plugin does

The plugin adds three areas to the native Shopware Admin:

### Dashboard

The dashboard gives you an immediate overview of your catalog's data quality:

* **Score distribution**: How many products are "Good", "Average", or "Critical"?
* **Average score**: A single number summarising the overall catalog health
* **Missing fields**: The five most common data gaps across your products
* **Validation summary**: How many products pass your mandatory field checks?

![Dashboard with score distribution and missing fields](/files/iKYiA9Hl5LC5QTw13Zqz)

### Dedicated product list

The **Product List** tab provides a dedicated product overview with score and validation status columns, plus filters by score range, missing field, and validation status.

![Dedicated product list with scores and filters](/files/k8YulJHPHvAkCdOpze3Y)

### Score and validation columns in the product list

Two new columns appear automatically in the native Shopware product list:

* **Completeness**: A color-coded badge (Green / Orange / Red) showing the current score
* **Valid**: A status badge indicating whether the product passes all validation rules

Both columns are filterable and sortable — no configuration required.

![Score and validation columns in the product list](/files/rZrO8j1vcEpEsOA90rrG)

### Score card on the product detail page

On every product detail page, the plugin displays a score card. It shows the current score and lists exactly which fields are still missing or incomplete for that specific product.

![Score card on the product detail page](/files/tZzp8e2Bs8ah1QYrBdUt)

## Rule-based evaluation

Scores are not calculated with a fixed formula — they are driven by configurable **rule sets** that you define yourself:

* Which fields matter (name, description, images, categories, custom fields, …)
* How much weight each field carries
* Whether a field should be checked as a binary pass/fail (validation rule)
* Which sales channels and languages a rule set applies to

The plugin automatically detects all compatible fields from Shopware's `ProductDefinition` — text fields, numbers, images, categories, tags, custom fields, and more.

## Asynchronous calculation

Score calculation runs via the **Symfony Messenger** in the background. Product saves in the Admin return immediately — no timeouts, no waiting. Scores are automatically recalculated every time a product is saved.


# 2. Installation

## Installing the plugin

Install the plugin via the Shopware Store, or upload the ZIP file manually:

1. Go to **Settings → System → Plugins → Upload Plugin**
2. Select the downloaded ZIP file
3. Click **Activate plugin**
4. Clear the cache under **Settings → System → Caches & Indexes → Clear Cache**

## Getting started

After activation, you will find the plugin under **Catalogues → Product Completeness**.

The dashboard will not show any scores yet — they need to be calculated first. Follow these steps:

1. Navigate to **Catalogues → Product Completeness → Rule Sets**
2. Create your first rule set and add conditions (e.g. Name: required, Description: required, Images: count\_min 1)
3. Save the rule set
4. Go to the **Dashboard** and click **Recalculate Scores**
5. Calculation runs asynchronously in the background — scores will appear in the dashboard shortly

## Configuring score thresholds

The color boundaries for "Good" and "Critical" are adjustable under **Settings → System → Configuration → Momo Product Completeness**. Defaults:

* **Good**: score ≥ 70%
* **Critical**: score ≤ 39%

## ACL privileges

The plugin includes dedicated ACL privileges. Assign them to roles under **Settings → System → Users & Permissions**:

| Privilege                   | Actions                      |
| --------------------------- | ---------------------------- |
| `momo_completeness_rule`    | Read, create, update, delete |
| `momo_product_completeness` | Recalculate scores           |

## Notes

* Score calculation runs asynchronously via Symfony Messenger. Make sure workers are running (`messenger:consume async`).
* Scores are automatically recalculated on every product save. Manual recalculation is only needed after major rule set changes.
* The plugin is compatible with Shopware \~6.6.0.


# 3. Rule Sets & Validation

The plugin supports two types of rules: **completeness rules** (weighted score) and **validation rules** (binary pass/fail). Both are managed through rule sets.

## Managing rule sets

Go to **Catalogues → Product Completeness → Rule Sets** to view, create, and edit your rule sets.

### Creating a rule set

Click **Add rule set** and fill in the form:

* **Name**: An internal name for the rule set (e.g. "Standard Checklist" or "SEO Audit")
* **Sales channels** *(optional)*: Restrict the rule set to one or more sales channels. Leave empty to apply it across all channels.
* **Language** *(optional)*: Limit the rule set to a specific language. Leave empty to evaluate all languages.

### Adding conditions

Each rule set contains one or more conditions. For each condition, you configure:

| Setting                          | Description                                                                       |
| -------------------------------- | --------------------------------------------------------------------------------- |
| **Field**                        | The product field to evaluate (auto-detected from Shopware's `ProductDefinition`) |
| **Operator**                     | The check logic: `required`, `min_length`, `count_min`, `regex`, and more         |
| **Value** *(operator-dependent)* | The comparison value, e.g. minimum length or minimum count                        |
| **Weight**                       | Completeness rules only: how much this field contributes to the score             |
| **Rule type**                    | Completeness rule (score) or validation rule (valid/invalid)                      |

![Rule set form with conditions](/files/JPCxGz6KaO8t693skJby)

### Supported operators

| Operator     | Description                                           |
| ------------ | ----------------------------------------------------- |
| `required`   | Field must be present and non-empty                   |
| `min_length` | Text must be at least N characters long               |
| `count_min`  | Collection (e.g. images) must have at least N entries |
| `regex`      | Field value must match a regular expression           |

All regex inputs are validated against ReDoS patterns before saving.

## Completeness rules

Completeness rules contribute to the **weighted score** (0–100%). A product reaches 100% when all conditions in its applicable rule sets are satisfied.

**Example configuration:**

| Field       | Operator        | Weight |
| ----------- | --------------- | ------ |
| Name        | required        | 20     |
| Description | min\_length 100 | 30     |
| Cover image | required        | 25     |
| Categories  | count\_min 1    | 15     |
| Meta title  | required        | 10     |

## Validation rules

Validation rules check **binary conditions** — a product is either valid or invalid. They are shown separately from the score in the dashboard and product list.

Use validation rules for mandatory fields that must always be present (e.g. EAN, manufacturer number) where weighted scoring doesn't make sense.

## Scope: sales channel & language

A rule set only applies to products assigned to the selected sales channel. This lets you define different quality requirements for different shops or export channels:

* **No filter**: The rule set applies to all products in all channels
* **Sales channel filter**: Only products in these channels are evaluated against this rule set
* **Language filter**: Only product translations in this language are evaluated

## Managing rule sets

All configured rule sets are shown in an overview with their name, scope badge, and condition count. Use the toggle in the **Active** column to temporarily disable individual rule sets without deleting them.

![List of completeness rule sets](/files/vTt9YU6xRkyA1YjjryhF)

## Recalculating scores

After changes to rule sets, scores are **not** automatically recalculated for all products. Click **Recalculate Scores** on the dashboard to trigger a full recalculation. This runs asynchronously — depending on catalog size, it may take a few minutes.

Individual product scores are updated automatically every time that product is saved.


# 4. Configuration

The plugin configuration is available under **Extensions → My extensions → Product Completeness & Data Quality → Configure**.

![Plugin configuration page](/files/4REvNlE7IcW6WR8M1DAB)

## Configuration options

### Score thresholds

The score badges in the product list and dashboard are color-coded. The boundaries for the "Good" and "Critical" categories are freely configurable.

| Option                   | Description                                                   | Default |
| ------------------------ | ------------------------------------------------------------- | ------- |
| **"Good" threshold**     | Products with a score at or above this value are marked green | 70      |
| **"Critical" threshold** | Products with a score at or below this value are marked red   | 39      |

Products with scores between the two thresholds receive an orange badge.

**Example with default values:**

| Score   | Category | Badge color |
| ------- | -------- | ----------- |
| 70–100% | Good     | Green       |
| 40–69%  | Average  | Orange      |
| 0–39%   | Critical | Red         |

### Notes

* The "Good" threshold must be greater than the "Critical" threshold
* Both values must be between 0 and 100
* Changes to the thresholds take effect immediately — no score recalculation is required


# Dynamic Delivery Countdown


# 1. Description

**Dynamic Delivery Countdown** adds a live countdown timer to your product detail pages — just like Amazon: "Order within 3h 22m for delivery by Wednesday, March 19."

This concrete delivery promise motivates customers to order immediately, increasing conversion rates.

![Countdown on the product detail page in fixed mode](/files/7ZaHu6Tkmm5rZXfyZe3b)

## What the plugin does

The plugin calculates the expected delivery date server-side for each product and passes it as JSON data to the product detail page. A JavaScript plugin updates the countdown every second in the browser — no page reload required. When the daily order deadline passes, the JavaScript automatically recalculates the delivery date for the next business day.

## Four delivery date modes

Choose the mode that best fits your product catalog:

| Mode                                      | Description                                                                   |
| ----------------------------------------- | ----------------------------------------------------------------------------- |
| **Fixed shipping days**                   | Always uses the configured shipping days, regardless of product delivery time |
| **Product delivery time — earliest date** | Uses the minimum value from the product's Shopware delivery time              |
| **Product delivery time — latest date**   | Uses the maximum value from the product's Shopware delivery time              |
| **Product delivery time — date range**    | Shows a range: "Delivery between \[earliest] and \[latest date]"              |

![Storefront countdown in range mode](/files/ZzSa9SICcNuYbem14XSi)

## Weekends and holidays

The plugin accounts for non-delivery days: weekends can be excluded globally, and individual public holidays can be entered as a date list in `YYYY-MM-DD` format. If a calculated delivery date falls on an excluded day, the next available business day is shown automatically.

## Threshold for long delivery times

For products with long lead times, you can configure a threshold in days. When exceeded, you can either hide the countdown entirely or show the countdown without a concrete date — "For fastest possible delivery."

![Plugin configuration: excluded days and long delivery time threshold](/files/dEQJF0JG7yS7SIRHnZkj)

## Technical details

* Compatible with Shopware 6.6
* Requires PHP 8.2 or higher
* All calculations run in the customer's browser — no external services, no additional server requests
* Configurable per sales channel
* Available in German and English


# 2. Installation

## Installing the plugin

### Via the Shopware Store

1. In the admin, go to **Extensions → Store**.
2. Search for "Dynamic Delivery Countdown" and click **To Shop**.
3. After purchase, navigate to **Extensions → My Extensions**.
4. Click **Install** next to the plugin, then activate it using the toggle.

### Via ZIP upload

1. Download the ZIP file from your Shopware account.
2. In the admin, go to **Extensions → My Extensions**.
3. Click **Upload extension** and select the ZIP file.
4. Click **Install**, then activate the plugin using the toggle.

## Initial configuration

1. Click the three dots (⋯) next to the plugin and select **Configure**.
2. Make sure **Enable Delivery Countdown** is turned on.
3. Under **Daily Order Deadline**, enter the time by which orders are dispatched the same day (e.g. `14:00`).
4. Under **Delivery Date Source**, choose the mode that fits your business.
5. Save the configuration.

## Verify it works

Open any product detail page in your storefront. The delivery countdown should appear below the add-to-cart button, provided the product is in stock.

![Countdown on the product detail page in fixed mode](/files/7ZaHu6Tkmm5rZXfyZe3b)

## Notes

* The daily order deadline is interpreted in the server's PHP timezone. Make sure the server time is configured correctly.
* In the **Earliest date**, **Latest date**, and **Date range** modes, the product's Shopware delivery time is used. Products without an assigned delivery time automatically fall back to the configured shipping days.
* The plugin is configurable per sales channel. Settings apply to all sales channels by default but can be overridden per channel.


# 3. Configuration

Open the configuration under **Extensions → My Extensions**, click the three dots (⋯) next to the plugin, and select **Configure**.

![Plugin configuration: enable toggle and delivery date calculation](/files/GRFAQMepXjNLPuQCeTEP)

## Card 1: Delivery Countdown

### Enable Delivery Countdown

Globally enables or disables the countdown. When disabled, no countdown appears on any product detail page.

**Default:** Enabled

***

## Card 2: Delivery Date Calculation

### Daily Order Deadline (HH:MM, server timezone)

The time by which an order must be placed to be dispatched the same day. Orders placed after this time are counted towards the next business day. The time is interpreted in the server's PHP timezone.

**Format:** `HH:MM`, e.g. `14:00` **Default:** `14:00`

### Delivery Date Source

Determines how the delivery date is calculated.

| Option                                    | Description                                                                    |
| ----------------------------------------- | ------------------------------------------------------------------------------ |
| **Fixed shipping days**                   | Always uses the configured shipping days, ignoring the product's delivery time |
| **Product delivery time — earliest date** | Uses the minimum value from the product's Shopware delivery time               |
| **Product delivery time — latest date**   | Uses the maximum value from the product's Shopware delivery time               |
| **Product delivery time — date range**    | Shows a delivery range: earliest to latest date                                |

**Default:** Fixed shipping days

### Shipping Days (Fixed Mode & Fallback)

The number of business days for delivery. Always used in Fixed mode. In all other modes, this value serves as a fallback for products that have no Shopware delivery time assigned.

**Type:** Integer (business days) **Default:** `2`

***

## Card 3: Excluded Days

### No delivery on weekends

Excludes Saturday and Sunday as delivery days. If a calculated delivery date falls on a weekend, the next business day is shown automatically.

**Default:** Enabled

### Holidays (Non-Delivery Days)

A list of dates on which no delivery takes place. Enter one date per line in `YYYY-MM-DD` format.

**Example:**

```
2025-12-25
2025-12-26
2026-01-01
```

**Default:** Empty (no holidays excluded)

***

## Card 4: Long Delivery Times

### Threshold (days)

When the calculated delivery time exceeds this number of days, the display behavior below takes effect. Leave empty or set to `0` to disable the threshold logic.

**Type:** Integer (days), optional **Default:** Disabled (empty)

### Display above threshold

Determines what is shown when the delivery time exceeds the threshold.

| Option                                     | Description                                                                                        |
| ------------------------------------------ | -------------------------------------------------------------------------------------------------- |
| **Hide the delivery countdown**            | The countdown is hidden entirely for this product                                                  |
| **Show countdown only (no delivery date)** | The countdown is displayed without a concrete delivery date — e.g. "For fastest possible delivery" |

**Default:** Hide the delivery countdown

![Plugin configuration: excluded days and long delivery time threshold](/files/dEQJF0JG7yS7SIRHnZkj)


# Margins & Purchase Prices in Product Listing


# 1. Description

The **Margins & Purchase Prices in Product Listing** plugin extends the product list in the Shopware administration with four additional columns that make purchase prices and profit margins visible at a glance — without opening individual products.

![Product listing with margin columns and color-coded indicators](/files/48xc5f2ZZRa0Hd3kIjfs)

## What the plugin does

After installation, you will see four new columns in **Catalogues → Products**:

| Column             | Description                                                                  |
| ------------------ | ---------------------------------------------------------------------------- |
| **Purchase Price** | The stored purchase price of the product                                     |
| **Net Price**      | Automatically calculated from gross price and tax rate                       |
| **Margin**         | Absolute margin (net price − purchase price), formatted in the shop currency |
| **Margin %**       | Percentage margin with color-coded indicators                                |

Products without a stored purchase price display a dash (–) in all margin columns.

## Color-coded margin indicators

The **Margin %** column shows colored badges so you can spot problematic products at a glance:

* **Red** — Margin below the low threshold (default: below 10%)
* **Yellow** — Margin between thresholds (default: 10–30%)
* **Green** — Margin above the high threshold (default: 30% and above)

You can customize the thresholds in the plugin configuration.

## Sorting and filtering

The plugin also adds:

* **Server-side sorting** by purchase price, margin, and margin % — click a column header to sort ASC/DESC across all pages, even for large catalogs.
* **Purchase price filter** in the native Shopware filter panel: "With purchase price" or "Without purchase price" — to quickly find products missing purchase price data.

![Server-side sorting by margin %](/files/hoAqMKhAz7BUFgEeVAPu)

## Calculation method

The percentage margin can be switched between two methods in the plugin configuration:

* **Gross Margin** (default): `(Net Price − Purchase Price) / Net Price × 100`
* **Markup**: `(Net Price − Purchase Price) / Purchase Price × 100`

The plugin stores both values pre-computed in the database. Switching the method takes effect immediately — no re-indexing or waiting required.

## Compatibility

| Plugin version | Shopware version |
| -------------- | ---------------- |
| 1.0.0          | Shopware 6.6     |
| 2.0.0          | Shopware 6.7     |

* Fully translated (German and English)
* No changes to the checkout process or storefront


# 2. Installation

## Installing the plugin

### Via the Shopware Store (recommended)

1. Open **Extensions → Store** in the Shopware administration.
2. Search for "Margins & Purchase Prices in Product Listing".
3. Click **Buy** or **Install**.
4. The plugin is downloaded and installed automatically.

### Manual installation via ZIP

1. Download the plugin ZIP file from your Shopware account.
2. Open **Extensions → My Extensions** in the administration.
3. Click **Upload plugin** and select the ZIP file.
4. The plugin will appear in the plugin list.

## Activating the plugin

1. Open **Extensions → My Extensions**.
2. Find **Margins & Purchase Prices in Product Listing** in the list.
3. Toggle the switch to **activate** the plugin.
4. Confirm the cache clear if prompted.

## First steps after installation

Once activated, the plugin automatically starts a background indexing run to calculate margin data for all existing products. The new columns are immediately visible:

1. Open **Catalogues → Products**.
2. Scroll right in the table — you will see four new columns: **Purchase Price**, **Net Price**, **Margin**, and **Margin %**.
3. While the background indexing is in progress, the margin columns may still show a dash (–). This is normal — values fill in as the indexing completes.
4. Products without a stored purchase price will always show a dash (–) in the margin columns. Add purchase prices directly on the product page under the **List price → Purchase price** field.

## Using the purchase price filter

To quickly find all products without a purchase price:

1. Open **Catalogues → Products**.
2. Click the **Filter** icon (funnel) in the upper right corner.
3. Scroll down in the filter panel to the **Purchase Price** section.
4. Select **Without purchase price**.
5. The product list will show only products without a stored purchase price.

![Filter panel with active purchase price filter](/files/zno8w6DSPwEfFOXysftz)

## Notes

* The **Margin** and **Margin %** columns are calculated based on the net price in the default currency and the stored purchase price.
* For products with variants, each variant must have its purchase price set individually.
* Sorting by margin and margin % is server-side and uses a precomputed database table. The plugin stores both calculation methods (Gross Margin and Markup) simultaneously, so switching the method in the configuration takes effect immediately without a re-index. The table is updated automatically whenever prices change.


# 3. Configuration

Plugin settings are located at **Extensions → My Extensions → Margins & Purchase Prices in Product Listing → ... → Configure**.

![Plugin configuration page](/files/v4wO2jPU9i2lyI88x3fp)

## Calculation Method

### Percentage Calculation Method

Determines how the percentage margin in the **Margin %** column is calculated.

| Option                                | Formula                                               | Description                                  |
| ------------------------------------- | ----------------------------------------------------- | -------------------------------------------- |
| **Margin (Gross Margin)** *(default)* | `(Net Price − Purchase Price) / Net Price × 100`      | Profit as a percentage of the selling price  |
| **Markup**                            | `(Net Price − Purchase Price) / Purchase Price × 100` | Profit as a percentage of the purchase price |

**Example:** Purchase price €60, net price €100

* Gross Margin: (100 − 60) / 100 × 100 = **40%**
* Markup: (100 − 60) / 60 × 100 = **66.7%**

The plugin stores both methods pre-computed in the database. Switching the method takes effect immediately in the product listing — no re-index required.

***

## Margin Thresholds

The thresholds control the color coding in the **Margin %** column.

### Low Margin Threshold (%)

**Default: 10**

Margins below this value are shown in **red**. Red indicates that the margin is critically low or even negative (selling below purchase price).

### Medium Margin Threshold (%)

**Default: 30**

* Margins between the low threshold and this value are shown in **yellow**.
* Margins at or above this value are shown in **green**.

**Example with default values:**

* Margin < 10% → Red
* 10% ≤ Margin < 30% → Yellow
* Margin ≥ 30% → Green


# Sold Count Display & Social Proof


# 1. Description

**Sold Count Display & Social Proof** shows real sales figures directly on product detail pages and in product listings. Instead of fake FOMO popups, this plugin uses credible, static badges backed by actual order data.

![Badge on the product detail page](/files/ty6PfIPfLaSi5KHHPYRI)

## What the plugin does

The plugin aggregates sold counts from completed and paid orders daily and stores them in a dedicated database table. These figures are then surfaced in your shop in two ways:

* **Product detail page:** A badge in the buy widget area shows how often a product has been sold (e.g. "1,800+ sold")
* **Product listings:** Compact badges on product cards in categories and search results

## Top Sellers widget in the admin

The plugin adds a **Top Sellers** widget to the admin dashboard, listing the 10 best-selling products with their rank, name, product number, and sold count. Each row links directly to the product detail page in the admin.

![Top Sellers widget on the admin dashboard](/files/FksaprAzOHbePBkKL4vm)

## Key highlights

* **Real data:** Only completed and paid orders are included in the aggregation
* **Variant rollup:** Sales from all variants are summed to the parent product
* **Configurable:** Minimum threshold, rounding options, and a time period filter control what gets displayed
* **Performant:** Aggregation runs once a day as a background task — not on every page load

## Areas extended in Shopware

| Area                                   | Extension                                         |
| -------------------------------------- | ------------------------------------------------- |
| Storefront – Product detail page       | Sold count badge in the buy widget                |
| Storefront – Product listings & search | Compact badge on product cards                    |
| Admin – Dashboard                      | Top Sellers widget                                |
| Admin – Plugin configuration           | Settings for threshold, rounding, and time period |


# 2. Installation

## Installing the plugin

### Via the Shopware Store

1. Log in to the **Shopware Administration**
2. Navigate to **Extensions → Store**
3. Search for "Sold Count Display" and click **Install**
4. The plugin is downloaded and activated automatically

### Manual installation via ZIP

1. Download the plugin ZIP file
2. In the Administration, navigate to **Extensions → My extensions**
3. Click **Upload extension** and select the ZIP file
4. Once uploaded, the plugin appears in the list — click **Install**
5. Enable the plugin using the toggle switch

## First steps after installation

The plugin is ready to use right after activation. However, sold count badges will only appear once the first aggregation run has completed (scheduled to run once per day by default).

**For immediate results**, trigger the aggregation manually:

```bash
bin/console momo:sold-count:aggregate
```

Once the aggregation finishes, badges will appear on product detail pages and in listings.

## CLI command

The plugin provides a console command for manual aggregation:

```bash
# Run the aggregation
bin/console momo:sold-count:aggregate

# Preview without writing to the database (dry run)
bin/console momo:sold-count:aggregate --dry-run
```

The `--dry-run` flag shows what would be aggregated without making any database changes.

## Notes

* Only orders with status **Completed** or **Paid (partially)** are included in the aggregation
* For products with variants, sales from all variants are rolled up to the parent product
* Changes to the time period filter in the configuration take effect on the next aggregation run
* The daily aggregation run is managed by Shopware's scheduled task system


# 3. Configuration

You can find the plugin configuration under **Extensions → My extensions → Sold Count Display → Configuration** (three-dot menu).

![Plugin configuration page](/files/br6wuhPz2bfHBWS42f6J)

All settings can be configured independently per sales channel.

## Configuration options

### Show badge on product detail page

| Property | Value    |
| -------- | -------- |
| Type     | Yes / No |
| Default  | Enabled  |

Controls whether the sold count badge appears on the product detail page. When disabled, no badge is shown in the buy widget area, even if sold count data exists.

***

### Show badge in product listings

| Property | Value    |
| -------- | -------- |
| Type     | Yes / No |
| Default  | Enabled  |

Controls whether compact badges appear on product cards in category listings and search results. Can be toggled independently from the detail page badge.

***

### Show Top Sellers widget on dashboard

| Property | Value    |
| -------- | -------- |
| Type     | Yes / No |
| Default  | Enabled  |

Controls whether the **Top Sellers** widget appears on the admin dashboard. When disabled, the widget is not loaded at all.

***

### Minimum sold count to display badge

| Property | Value   |
| -------- | ------- |
| Type     | Integer |
| Default  | 0       |

Sets a minimum threshold. Products with a sold count below this value will not show a badge. A value of `0` shows badges for all products with at least 1 sale.

**Example:** With a threshold of `50`, a badge only appears once a product has been sold at least 50 times.

> The threshold is checked against the raw (unrounded) sold count.

***

### Rounding mode

| Property | Value     |
| -------- | --------- |
| Type     | Selection |
| Default  | Exact     |

Determines how sold counts are formatted for display.

| Option           | Description                        | Example     |
| ---------------- | ---------------------------------- | ----------- |
| **Exact**        | Shows the precise sold count       | "523 sold"  |
| **Round to 10**  | Rounds down to the nearest ten     | "520+ sold" |
| **Round to 50**  | Rounds down to the nearest fifty   | "500+ sold" |
| **Round to 100** | Rounds down to the nearest hundred | "500+ sold" |

Rounded values get a "+" suffix. Exact multiples are displayed without "+" (e.g. 500 with "Round to 100" → "500 sold").

> Rounding applies to storefront badges only. The Top Sellers widget in the admin always shows exact counts.

***

### Aggregation time period

| Property | Value     |
| -------- | --------- |
| Type     | Selection |
| Default  | All time  |

Determines which orders are included in the aggregation.

| Option           | Description                          |
| ---------------- | ------------------------------------ |
| **All time**     | All orders since the shop was set up |
| **Last 30 days** | Only orders from the past 30 days    |
| **Last 7 days**  | Only orders from the past 7 days     |

> Changes to the time period take effect on the next scheduled aggregation run. To apply immediately, run `bin/console momo:sold-count:aggregate` manually.


# Admin Activity Log


# 1. Description

The **Admin Activity Log** automatically records who changed what and when in your Shopware Administration. Once multiple people have access to your shop, this plugin answers the question "Who did that?" — completely, GDPR-compliant, and without any configuration overhead.

![Activity Log listing with filters, user avatars, and action badges](/files/NAeOlEv7z77r9JVjz80e)

## What the Plugin Logs

* **CRUD operations** — every creation, update, and deletion on configured entities (default: products, orders, customers, categories, media)
* **Field-level before/after values** — for every change, the concrete field values before and after the modification are stored
* **State machine transitions** — order, delivery, and payment status changes are captured automatically and attributed to the parent order
* **Login events** — successful logins and failed attempts, including username and timestamp
* **API integrations** — writes via OAuth integrations (e.g. ERP or PIM connections) are attributed with the integration name

## Key Benefits

* **Complete audit trail** — traceable and audit-proof per Art. 5(2) GDPR
* **Team accountability** — see exactly which user made which change
* **Debugging** — track down unexpected changes to their root cause quickly
* **Zero effort** — the plugin logs automatically with no hooks or rules to configure

## Technical Details

| Property               | Value                                         |
| ---------------------- | --------------------------------------------- |
| Shopware compatibility | 6.6.x (version 1.x.x) · 6.7.x (version 2.x.x) |
| PHP                    | 8.2+                                          |
| External services      | none — fully self-contained                   |
| Storefront impact      | none — Administration only                    |


# 2. Installation

## Installing the Plugin

### Via the Shopware Store

1. Log in to your Shopware Administration
2. Navigate to **Extensions → Store**
3. Search for "Admin Activity Log"
4. Click **Buy** or **Install**
5. Activate the plugin under **Extensions → My Extensions**

### Manual Installation (ZIP)

1. Download the plugin ZIP file
2. Navigate to **Extensions → My Extensions**
3. Click **Upload Plugin** and select the ZIP file
4. Activate the plugin in the list

The cache is cleared automatically after activation.

## Getting Started

### Accessing the Activity Log

The activity log is available immediately after activation. You can find it under **Settings → Extensions → Activity Log**. New entries are created automatically with every change made in the Administration from that point on.

The plugin only captures changes made **after** activation. Historical data from before installation is not available.

### Reviewing the Configuration

Open the plugin configuration under **Extensions → My Extensions → Admin Activity Log → Configure** and check whether the default settings meet your requirements:

* **Tracked Entities**: Products, orders, customers, categories, and media are enabled by default
* **Retention Period**: 90 days (default)
* **Log System Actions**: enabled (default)

For details on each option, see the [Configuration](/en/shopware-6/admin-activity-log/3.-configuration) section.

## Notes

* Use **version 1.x.x** for Shopware 6.6 and **version 2.x.x** for Shopware 6.7
* The plugin has **no impact on the storefront** — it operates exclusively in the Administration
* Passwords and other credentials are never stored or processed at any point
* On uninstall, you can choose whether to keep the collected log data (**Keep user data**)


# 3. Configuration

The plugin configuration is located under **Extensions → My Extensions → Admin Activity Log → Configure**.

![Plugin configuration page with entity scope, retention period, and system actions toggle](/files/Q7dJyB1mkmaKH10ueXcq)

## Tracked Entities

| Setting    | Value                                          |
| ---------- | ---------------------------------------------- |
| Config key | `trackedEntities`                              |
| Default    | Products, Orders, Customers, Categories, Media |
| Type       | Multi-select                                   |

Choose which entity types should be tracked in the activity log. Changes to unselected entities are not logged.

Available entity types:

* Products
* Orders
* Customers
* Categories
* Media
* Manufacturers
* Properties
* Shipping Methods
* Payment Methods
* Sales Channels
* CMS Pages

**Note:** Changes take effect immediately for new log entries — no cache flush or restart required. Existing log entries for deselected entities are preserved.

**Note:** Order, delivery, and payment status transitions are captured automatically regardless of whether "Orders" is selected. Third-party plugins can register additional entities — see [Developer Extension API](/en/shopware-6/admin-activity-log/5.-extension).

## Retention Period

| Setting    | Value           |
| ---------- | --------------- |
| Config key | `retentionDays` |
| Default    | 90 days         |
| Type       | Single-select   |

Configure how long log entries are retained before automatic deletion.

| Option      | Description                                                |
| ----------- | ---------------------------------------------------------- |
| 30 days     | Entries older than 30 days are deleted daily               |
| 60 days     | Entries older than 60 days are deleted daily               |
| **90 days** | **Default** — entries older than 90 days are deleted daily |
| 180 days    | Entries older than 180 days are deleted daily              |
| 365 days    | Entries older than 365 days are deleted daily              |
| Unlimited   | No automatic deletion                                      |

Cleanup runs daily via a scheduled task. Expired entries are removed together with all associated field change records.

## Log System Actions

| Setting    | Value              |
| ---------- | ------------------ |
| Config key | `logSystemActions` |
| Default    | enabled            |
| Type       | Boolean (yes/no)   |

Controls whether writes triggered by the following sources are logged:

* CLI commands (`bin/console`)
* Scheduled tasks
* API integrations without a logged-in admin user

**Enabled (default):** All writes are logged regardless of their source. API integrations appear with the integration name and an "Integration" badge.

**Disabled:** Only changes directly triggered by a logged-in admin user appear in the log.

**Note:** Login events are always logged regardless of this setting.


# 4. Usage

## Activity Log

The activity log is accessible under **Settings → Extensions → Activity Log**.

![Activity Log listing with filters and user avatars](/files/NAeOlEv7z77r9JVjz80e)

### Understanding Log Entries

Each log entry contains:

| Column               | Description                                                                                                                        |
| -------------------- | ---------------------------------------------------------------------------------------------------------------------------------- |
| **Date/Time**        | Timestamp of the change                                                                                                            |
| **User**             | User avatar and name of the admin user who made the change; API integrations show the integration name with an "Integration" badge |
| **Entity Type**      | Type of the changed entity (e.g. product, order)                                                                                   |
| **Entity ID / Name** | Human-readable entity name (e.g. product title, order number) with a direct link to the detail page                                |
| **Action**           | Type of change: `created`, `updated`, `deleted`, `login_success`, `login_failed`                                                   |

### Filtering and Searching

Use the filter bar above the list to narrow down entries:

* **Entity Type** — filter by a specific entity type
* **Action** — filter by the type of change
* **User** — filter by a specific admin user or integration
* **Date range** — restrict the time period

The full-text search covers entity name, entity ID, and user name.

### Viewing Field Changes

Click the context menu (three dots) on any row and select **View details** to open a modal showing the field-level before/after values.

![Change detail modal with before/after values for a product update](/files/5eClbHNcrW5oGLSrlS8v)

The modal shows for each changed value:

* **Field** — name of the changed field
* **Old Value** — value before the change
* **New Value** — value after the change

For newly created entities, old values are empty; for deleted entities, new values are empty.

### CSV Export

Click **Export CSV** to download the currently filtered entries as a CSV file. The export respects all active filter criteria and contains one row per changed field.

The export format uses UTF-8 with BOM and semicolon as delimiter — compatible with Microsoft Excel. A maximum of 50,000 entries are exported per request.

***

## History on Entity Detail Pages

After activating the plugin, a **"History" button** appears in the toolbar of product, order, customer, and other entity detail pages.

![History modal on a product detail page](/files/1vimDEuMUE6otUf3hWKD)

Click it to view the complete change history for that entity without leaving the current page.

The modal displays all log entries for the entity in an accordion, sorted newest first. Each entry can be expanded to reveal the field-level changes.

The History button is available on the following detail pages:

* Products
* Orders
* Customers
* Categories
* Manufacturers
* Properties
* Shipping Methods
* Payment Methods
* Sales Channels
* CMS Pages

**Note:** The button is only visible when the entity already exists (it does not appear on the create page).

***

## Dashboard Widget

The **"Recent Activity"** widget appears automatically on the admin dashboard and shows the 10 most recent log entries at a glance.

![Admin dashboard with the Recent Activity widget](/files/5N9GaffVybdiVvklioZq)

Each widget entry shows:

* User avatar and name
* Action badge (e.g. "updated", "created")
* Entity type and name with a direct link to the detail page
* Relative timestamp (e.g. "5 minutes ago")

Click **View all** to navigate directly to the full activity log listing.

The widget is only visible to admin users with the `momo_admin_activity_log:read` permission.


# 5. Developer Extension API

The Admin Activity Log provides a public PHP extension API that allows developers to register custom entities for activity logging. Registered entities appear automatically in the plugin configuration and are fully captured in the activity log.

## Implementing the Interface

Create a class that implements `TrackableEntityProviderInterface`:

```php
use Momocode\MomoAdminActivityLog\Extension\TrackableEntityProviderInterface;
use Shopware\Core\Framework\Context;
use Shopware\Core\Framework\DataAbstractionLayer\EntityWriteResult;

class MyCustomEntityProvider implements TrackableEntityProviderInterface
{
    public function getEntityName(): string
    {
        // DAL entity name (matches the table name)
        return 'my_custom_entity';
    }

    public function getLabel(): string
    {
        // Human-readable label shown in the plugin configuration
        return 'My Custom Entity';
    }

    public function resolveDisplayName(string $entityId, EntityWriteResult $writeResult, Context $context): ?string
    {
        // Optional: return a human-readable display name for a log entry.
        // Called when a log entry is created.
        // Return null if no name can be resolved (falls back to the entity ID).
        return null;
    }

    public function getAdminRoute(): ?string
    {
        // Optional: Vue Router route to the entity's detail page.
        // Used for deep-links in the activity log listing.
        // Format: 'sw.my.custom.entity.detail'
        // Return null if no detail page exists.
        return null;
    }
}
```

## Registering the Service

Register the provider in your `services.xml` with the `momo.activity_log.entity_provider` tag:

```xml
<service id="MyVendor\MyPlugin\ActivityLog\MyCustomEntityProvider">
    <tag name="momo.activity_log.entity_provider" entity="my_custom_entity"/>
</service>
```

That's all — the plugin's compiler pass registers the provider automatically. On the next container build, the entity is included in the activity log.

## Result

After registration:

* The entity appears in the plugin configuration under **Tracked Entities** and can be enabled or disabled there
* All writes to this entity are automatically logged when it is selected in the configuration
* Display names (if `resolveDisplayName()` is implemented) are shown in the listing view
* Deep-links (if `getAdminRoute()` is implemented) are rendered as clickable links in the listing view

## Notes

* The `resolveDisplayName()` and `getAdminRoute()` methods are optional. Returning `null` causes the plugin to display the entity ID as plain text.
* The interface is located in the namespace `Momocode\MomoAdminActivityLog\Extension`.
* The service tag `momo.activity_log.entity_provider` must be spelled exactly — otherwise the compiler pass will not pick up the provider.


# Advanced Wishlists


# 1. Description

The **Advanced Wishlists** plugin replaces Shopware's native wishlist with a fully-featured wishlist solution. Customers can create multiple named wishlists, share them publicly via link, add items directly to the cart, and receive email notifications when prices drop.

![Admin overview of all customer wishlists](/files/q7rlF9zCTFT80EyQ3ATz)

## What the Plugin Does

* **Multiple named wishlists** — Customers create as many lists as they need with custom names (e.g. "Birthday", "Christmas", "Home Office") and manage them from their account.
* **Public sharing via link** — A wishlist can be set to "Public". The generated share link can be shared via WhatsApp, email, or a copy-link button. Visitors can browse the list and save it as their own.
* **Guest wishlist** — Logged-out visitors can save products to a local wishlist stored in localStorage. When they register or log in, their guest items are automatically merged into their first wishlist. Whether consent is required at all, and where it is read from, is determined by the configurable **Consent source**: Shopware's cookie banner, a foreign cookie written by your consent management tool, your own integration via the JavaScript API, or **No consent check** (see [Consent & Consent Tools](/en/shopware-6/advanced-wishlists/4.-consent)).
* **Heart icon toggle** — An icon (default: heart) appears on product cards, product detail pages, and cart line items. Clicking it opens a dropdown for selecting a target wishlist. Clicking an already-selected list removes the product.
* **Configurable icon and terminology** — Merchants choose in the plugin settings which icon (heart, star, bookmark, etc.) appears in the storefront and which terminology is used throughout (Wishlist, Notepad, Order list or Favourites). Each preset provides grammatically correct strings in German and English. Configurable per sales channel.
* **Per-item quantity** — Each wishlist item has its own quantity field. When adding to the cart, the wishlist quantity is used.
* **Save cart as wishlist** — A single click saves all cart items (excluding promotions) to a new or existing wishlist.
* **CSV export and import** — Customers and merchants can export wishlists as CSV and import products by product number.
* **Add by product number** — On the wishlist detail page, customers can add products directly by entering a product number (SKU).
* **Price-drop notifications** — Customers can opt in to email notifications per wishlist. When a product's price drops below its price at the time it was added (minus a configurable threshold), a notification is sent via Shopware's Flow Builder.
* **Global wishlists** — Merchants create curated wishlists in the admin (e.g. "Staff Picks"), which appear below customers' own lists on the wishlist overview page.
* **Admin analytics** — Under **Customers → Wishlists → Analytics** you'll find the most-wishlisted products, activity trends, and conversion rates.
* **Automatic "Last ordered" wishlist** — A background task automatically creates and maintains a read-only wishlist for each registered customer, populated with their recently purchased products. The list is labelled with an "Auto-generated" badge and cannot be edited or deleted by the customer.
* **Unavailable products** — Inactive or channel-removed products are displayed in a dedicated section on the detail page. Alternative products can be assigned in the admin.

## Relationship to Shopware's Native Wishlist

The plugin operates **independently alongside** Shopware's native wishlist. It does not disable it automatically. To use only the plugin, disable the native wishlist under **Settings → Shop → Cart → Enable wishlist**. Existing native wishlists can be migrated using the console command `momo:wishlists:migrate-native` (see [Installation](/en/shopware-6/advanced-wishlists/2.-installation)).

## Technical Requirements

* Shopware 6.6: Version 1.x.x | Shopware 6.7: Version 2.x.x
* PHP 8.2+
* Shopware Scheduled Task Worker must be active (for price-drop notifications and the automatic "Last ordered" wishlist)
* No external services or dependencies


# 2. Installation

## Installing the Plugin

### Via the Shopware Store (recommended)

1. Purchase the plugin from the Shopware Store.
2. Log in to your Shopware admin.
3. Go to **Extensions → My Extensions**.
4. Find **Advanced Wishlists** and click **Install**.
5. Activate the plugin using the toggle in its row.
6. Clear the cache under **Settings → System → Caches & Indexes → Clear cache**.

### Manual installation via ZIP

1. Download the plugin ZIP file.
2. Go to **Extensions → My Extensions**.
3. Click **Upload extension** and select the ZIP file.
4. Install and activate the plugin as described above.
5. Clear the cache.
6. If storefront assets are not built automatically, run **bin/console theme:compile**.

## First Steps After Activation

Core features are available immediately after activation:

* The heart icon appears on product cards and product detail pages.
* Logged-in customers find their wishlist overview under **My Account → My Wishlists**.
* Merchants find the admin overview under **Customers → Wishlists**.

Review and adjust the plugin settings to fit your shop (see [Configuration](/en/shopware-6/advanced-wishlists/3.-configuration)).

## Notes

### Relationship to Shopware's Native Wishlist

The plugin operates independently alongside Shopware's native wishlist and does not disable it automatically. If you want to use only the plugin, disable the native feature under **Settings → Shop → Cart → Enable wishlist**.

### Scheduled Task Worker

For automatic price-drop notifications, the Shopware Scheduled Task Worker must be running:

```bash
bin/console messenger:consume scheduled_task
```

Make sure this process runs continuously (e.g. via a Supervisor daemon or cron job).

### Name of the automatic "Last Ordered" wishlist

The name of the automatically generated wishlist is a multilingual storefront snippet and can be customised per language in the admin without touching any code.

**Snippet key:** `momoAdvancedWishlists.storefront.purchasedWishlist.defaultName`

Edit the snippet under **Settings → Snippets**. The name is resolved for each customer in their account language and reapplied on every task run (every 15 minutes).

## Migrating Existing Native Wishlists

If your shop already has native Shopware wishlists, you can migrate them using the included console command.

> **Note:** This command migrates **native Shopware wishlists** only. Migration from other wishlist plugins is not officially supported. If you are switching from a different plugin and would like to bring your data over, [get in touch](https://momocode.de) — I'm happy to help with the migration personally.

```bash
bin/console momo:wishlists:migrate-native [--name=<name>] [--delete-native] [--dry-run]
```

| Option            | Description                                                         |
| ----------------- | ------------------------------------------------------------------- |
| `--name`          | Name for the migrated wishlists (interactive prompt if omitted)     |
| `--delete-native` | Automatically deletes native wishlists after a successful migration |
| `--dry-run`       | Previews the migration without writing any data                     |

**Recommended approach:**

1. Run with `--dry-run` first and review the output.
2. Run the actual migration without `--dry-run`.
3. Verify that all wishlists have been migrated correctly.
4. Optionally use `--delete-native` or remove native wishlists manually.

> **Note:** The command is not idempotent. Run it only once to avoid duplicate entries.


# 3. Configuration

Plugin settings are found at **Extensions → My Extensions → Advanced Wishlists → ··· → Configure**.

![Plugin configuration](/files/DcXjhgx4IFrYc4pw004b)

Settings can be overridden per sales channel. The four **Consent source** fields in the **Guest Wishlist** section are the exception — they apply shop-wide (see [Consent & Consent Tools](/en/shopware-6/advanced-wishlists/4.-consent)).

***

## Guest Wishlist

### Enable guest wishlist

**Default:** enabled

Allows logged-out visitors to save products to a local wishlist (localStorage). Whether consent is required for this is determined by the **Consent source** setting: with **Shopware cookie banner** (default, category "Functional"), **Foreign cookie** and **Custom** nothing is stored until consent has been granted; with **No consent check** the feature is active without any check. Where that consent is read from, and what happens without it, is up to you (see [Consent & Consent Tools](/en/shopware-6/advanced-wishlists/4.-consent)).

When the guest registers or logs in, their saved items are automatically merged into their first wishlist.

### Maximum guest wishlist items

**Default:** 50

Limits the number of products a guest can save to their local wishlist. Further additions are ignored once the limit is reached.

### Guest wishlist TTL (days)

**Default:** 30

How long guest wishlist data is stored in the browser before expiring. After this period, the data is automatically removed from localStorage.

### Consent source

**Default:** Shopware cookie banner | **Options:** Shopware cookie banner, Foreign cookie (consent management tool), Custom (JavaScript API), No consent check

Determines where the plugin reads the consent state for the guest wishlist from. By default, the plugin declares its cookie in Shopware's cookie banner under "Functional". If you use an external consent management tool instead, select the matching source here.

> **This setting applies shop-wide** and cannot be overridden per sales channel.

A detailed description of every source, including recipes for Cookiebot, Borlabs Cookie, CCM19 and Usercentrics, is available under [Consent & Consent Tools](/en/shopware-6/advanced-wishlists/4.-consent).

### Consent cookie name

Only relevant for the **Foreign cookie** consent source. The name of the cookie your consent tool sets (e.g. `CookieConsent`).

### Consent cookie match strategy

**Default:** Exact match | **Options:** Exact match, Contains, JSON path

Only relevant for the **Foreign cookie** consent source. Determines how the cookie value is compared against the comparison value.

### Consent cookie comparison value or JSON path

Only relevant for the **Foreign cookie** consent source. Depending on the match strategy, either the expected value (for **Exact match** and **Contains**) or a dot-separated path into the cookie's JSON content (for **JSON path**, e.g. `consents.comfort`).

***

## Wishlist Display

### Items per page

**Default:** 24 | **Options:** 12, 24, 48

Determines how many wishlist items are shown per page on the wishlist detail page and the publicly shared wishlist. A page navigation appears when there are more items.

***

## Unavailable Products

### Show unavailable products section on wishlist detail page

**Default:** enabled

When enabled, customers see a dedicated "Unavailable Products" section (above the regular items) on their wishlist detail page. Products that are inactive or removed from the sales channel are listed there.

If you have assigned alternative products in the admin, they appear below the unavailable product as replacement suggestions. Customers can remove unavailable items directly from this section or add a suggested alternative to their wishlist.

Disable this option if you do not want to highlight unavailable products on the storefront.

***

## CSV Import/Export

### Maximum CSV import items

**Default:** 200

Limits the number of products processed in a single CSV import. Rows beyond this limit are ignored.

***

## Price Drop Notifications

### Enable price drop notifications

**Default:** enabled

Enables the feature globally for the entire shop. When disabled, the opt-in section on the wishlist detail page is hidden and no notifications are sent.

To actually send emails, you also need to set up a flow in the Flow Builder (see [Price-Drop Notifications](/en/shopware-6/advanced-wishlists/7.-price-notifications)).

### Threshold type

**Default:** Percentage | **Options:** Percentage, Absolute value

Determines how the minimum price difference is measured:

* **Percentage** — A notification is triggered when the price drops by at least X % below the original price.
* **Absolute value** — A notification is triggered when the price drops by at least X (in the shop currency) below the original price.

### Minimum price drop threshold

**Default:** 5

The minimum amount by which a price must fall to trigger a notification. The interpretation depends on the selected **Threshold type** (e.g. 5 % or €5).

***

## "Last Ordered" Wishlist

### Enable automatic "Last ordered" wishlist

**Default:** disabled

When enabled, a background task (every 15 minutes) automatically creates a private, read-only wishlist for each registered customer containing their recently purchased products — or updates an existing one. Guest orders are excluded. Cancelled orders are ignored.

The wishlist is **read-only** for customers (no renaming, deleting, or editing) and displays an "Auto-generated" badge in the storefront. It appears alongside the customer's own wishlists on the wishlist overview page.

> The Shopware Scheduled Task Worker must be active for this feature to run.

### Wishlist name (snippet)

The name of the automatically generated wishlist is **not a plugin configuration field** — it is a multilingual storefront snippet, so it can be customised per language without touching any code.

**Snippet key:** `momoAdvancedWishlists.storefront.purchasedWishlist.defaultName`

**Default:** "Recently ordered" (EN) / "Zuletzt bestellt" (DE)

Edit the snippet under **Settings → Snippets**, search for the key, and adapt the text per language (e.g. "My order history" or "Already purchased"). The name is resolved for each customer in their account language and reapplied on every task run — changes to the snippet take effect on all existing automatic wishlists within the next run (at most 15 minutes).

### Consider orders from the last N months

**Default:** 0 (no limit)

When set to a value greater than 0, only orders placed within the last N months are included in the automatic wishlist. Older orders are ignored. A value of 0 considers all orders regardless of date.

**Recommendation:** 12 months for a timeframe-relevant list.

### Maximum products in the wishlist

**Default:** 0 (no limit)

Limits the number of products stored in the automatic wishlist. Products from the **most recent** orders are always preferred. A value of 0 means no product limit.

***

## Storefront Appearance

### Terminology preset

**Default:** Wishlist | **Options:** Wishlist, Notepad, Order list, Favourites

Determines which term is used throughout the storefront in place of "Wishlist". Each preset provides a complete, grammatically correct set of strings in German and English — singular, plural, compound words and case inflections included.

| Preset     | DE                           | EN                       |
| ---------- | ---------------------------- | ------------------------ |
| Wishlist   | Wunschliste / Wunschlisten   | Wishlist / Wishlists     |
| Notepad    | Merkzettel                   | Notepad / Notepads       |
| Order list | Bestellliste / Bestelllisten | Order list / Order lists |
| Favourites | Favoriten                    | Favourites               |

All presets can be configured per sales channel. Without an explicit selection (default), the plugin behaves identically to before. Customer-entered list names are never changed — the preset only affects the plugin's own UI strings.

> **Note:** Individual snippet overrides made via **Settings → Snippets** take precedence over the preset and are never overwritten.

### Storefront icon

**Default:** Heart | **Options:** Heart, Star, Bookmark, Shopping bag (bag-product), Shopping bag (bag), Flag, List, Pencil

Determines which icon is displayed in the storefront for the wishlist feature. The icon appears in the header counter, on product cards, on the product detail page and in list-action buttons. Only valid Shopware icons are available — invalid values fall back to the heart icon automatically.

### Product card button position

**Default:** Icon in corner | **Options:** Icon in corner, Full-width button, No button

Controls how the wishlist action appears on product cards (category listings, search results, CMS product sliders, cross-selling boxes).

* **Icon in corner (default)** — The existing behaviour: a small circular icon button overlaid in the corner of the product image. Existing installations are unaffected without an explicit selection.
* **Full-width button** — A button spanning the full card width appears in the action area of the product card, below the "Details" button. The button displays the configured storefront icon and a text label from the active terminology preset (e.g. "Add to order list" with the Order list preset). When a product is already on a wishlist, the button automatically switches to its active state with a filled icon and a remove label.
* **No button** — No wishlist button is shown on product cards. The wishlist feature remains accessible via the product detail page, the header and the customer account.

This setting can be configured independently per sales channel.

### Wishlist control without guest consent

**Default:** Hide the control | **Options:** Hide the control, Show the control and ask for consent

Determines what a guest visitor sees while no consent for the guest wishlist is present.

* **Hide the control (default)** — The wishlist icon or button is not rendered at all. Existing installations behave exactly as before after an update.
* **Show the control and ask for consent** — The control stays visible but inactive. Clicking it opens Shopware's cookie settings; if that dialog is unavailable, a dismissible hint appears instead. No product is ever saved while consent is missing.

This setting can be configured independently per sales channel. See [Consent & Consent Tools](/en/shopware-6/advanced-wishlists/4.-consent) for details.

***

## Wishlist Analytics

### Conversion attribution window (days)

**Default:** 30

Defines how many days after a product is added to a wishlist a purchase counts as a conversion. If a customer buys a wishlisted product within this period, the conversion is recorded in the analytics.

![Plugin configuration — additional settings](/files/t8C72vTnVcSUfSDm3eLV)


# 4. Consent & Consent Tools

The guest wishlist stores products in the visitor's browser (`localStorage`), which makes it subject to consent. You decide where the plugin reads that consent from — from Shopware's own cookie banner through to an integration with an external consent management platform (CMP).

All settings on this page are found at **Extensions → My Extensions → Advanced Wishlists → ··· → Configure**.

> This page applies to **guest visitors** only. Logged-in customers store their wishlists server-side in their customer account, where no consent check applies.

***

## Choosing the Consent Source

The **Consent source** field in the **Guest Wishlist** section determines where the consent state comes from:

| Consent source                               | Consent comes from                                                         | Plugin cookie in Shopware's banner |
| -------------------------------------------- | -------------------------------------------------------------------------- | ---------------------------------- |
| **Shopware cookie banner** *(default)*       | Shopware's own cookie banner, category "Functional"                        | yes                                |
| **Foreign cookie (consent management tool)** | A cookie set by your consent tool, evaluated via a configurable comparison | no                                 |
| **Custom (JavaScript API)**                  | A small JavaScript snippet in your theme only                              | no                                 |
| **No consent check**                         | Nowhere — the guest wishlist is active without any check                   | no                                 |

Two points that regularly cause questions:

* **The setting applies shop-wide**, not per sales channel. Shopware calls the plugin's cookie provider without a sales channel context, so a per-channel setting could not be honoured there. To make sure the cookie banner and the storefront never disagree, both read the same global value.
* **The "Enable guest wishlist" setting always wins.** If the guest wishlist is disabled, it is off in all four sources. The consent source only decides *how* consent is detected — never *whether* the feature exists at all.

In every source other than **Shopware cookie banner**, the plugin deliberately stops declaring its cookie in Shopware's cookie banner. Otherwise the banner would list a cookie the storefront never uses.

***

## Shopware Cookie Banner (Default)

With no further configuration, the plugin cookie appears in Shopware's cookie banner under **Functional**. When a visitor accepts that category, the guest wishlist is enabled **immediately** — no page reload or navigation required. The wishlist control appears right after the cookie selection is saved.

For most shops this is the right choice and no additional settings are needed.

***

## Foreign Cookie (Consent Management Tool)

If you use a consent management platform instead of Shopware's banner, the plugin can read its cookie directly. Three fields control this:

| Field                                            | Meaning                                                            |
| ------------------------------------------------ | ------------------------------------------------------------------ |
| **Consent cookie name**                          | The cookie to read, e.g. `CookieConsent`                           |
| **Consent cookie match strategy**                | Exact match, Contains, or JSON path                                |
| **Consent cookie comparison value or JSON path** | The comparison value — or, for JSON path, the path into the cookie |

The three match strategies:

* **Exact match** — The cookie value equals the comparison value exactly (case-sensitive).
* **Contains** — The comparison value appears somewhere in the cookie value. This is the right strategy for tools whose cookie is readable text rather than valid JSON.
* **JSON path** — The cookie value is parsed as JSON and the comparison value is followed as a dot-separated path (e.g. `consents.comfort`). Only `true`, `1`, `"1"` or `"true"` count as granted.

### Recipes for Common Consent Tools

Cookie names and structures are defined by the vendors of the consent tools and can change with any release. The values below are **starting points, not guarantees** — verify them against your own installation using your browser's developer tools.

| Tool           | Consent source | Cookie                          | Match strategy | Value                                                 |
| -------------- | -------------- | ------------------------------- | -------------- | ----------------------------------------------------- |
| Cookiebot      | Foreign cookie | `CookieConsent`                 | Contains       | `preferences:true`                                    |
| Borlabs Cookie | Foreign cookie | `borlabs-cookie`                | JSON path      | e.g. `consents.comfort`                               |
| CCM19          | Foreign cookie | Your shop's embedding ID cookie | Contains       | Identifier of the accepted group                      |
| Usercentrics   | Custom         | —                               | —              | see [Custom (JavaScript API)](#custom-javascript-api) |

Notes:

* **Cookiebot** writes a value that *looks* like JSON but is not. Use **Contains**, not the JSON path.
* **Borlabs Cookie** places the group identifier in the path, and it depends on the naming in your shop. Open the cookie in your browser once and read off the actual path.
* **Usercentrics** keeps consent in its JavaScript API rather than in a reliably readable cookie. Here the **Custom** source is the only dependable route.

### When Nothing Appears

The comparison deliberately fails **silently** — there is no message in the browser console. Any misconfiguration (empty cookie name, empty comparison value, unparsable JSON, a path that leads nowhere) results in "not granted". The symptom is unambiguous: the guest wishlist does not appear. In that case, check the cookie name, strategy and comparison value against the actual cookie content in your browser.

If the configured cookie does not exist at all, the plugin does **not** treat that as a refusal — a consent tool that is still loading simply has not written its cookie yet.

***

## Custom (JavaScript API)

If your consent tool cannot be read from a cookie, connect it through a small JavaScript interface. The plugin deliberately ships **no** tool-specific adapters — it only provides the connection point; the few lines of glue code live in your theme.

> This section is aimed at developers or your agency. A custom theme or plugin is required for the integration.

### The Bridge Block

The plugin provides an empty, overridable Twig block. Create an extension of `storefront/base.html.twig` in your theme:

```twig
{% sw_extends '@Storefront/storefront/base.html.twig' %}

{% block momo_guest_wishlist_consent_bridge %}
    <script>
        (function () {
            // Register the resolver first: it works regardless of whether
            // your consent tool has loaded by this point.
            window.MomoWishlistConsent.registerResolver(function () {
                if (!window.myCmp || !window.myCmp.isReady()) {
                    return null; // no statement possible yet
                }

                return window.myCmp.hasConsent('comfort');
            });

            // Event binding, as soon as the consent tool is available.
            // Safe to call repeatedly — it binds at most once.
            let bound = false;

            function bindMyCmp() {
                if (bound || !window.myCmp || typeof window.myCmp.onConsentChange !== 'function') {
                    return bound;
                }

                bound = true;

                window.myCmp.onConsentChange(function (consents) {
                    window.MomoWishlistConsent.set(consents.comfort === true);
                });

                // The tool is ready now — re-evaluate the state once
                window.MomoWishlistConsent.refresh();

                return true;
            }

            // If your consent tool loads asynchronously it is not here yet.
            // Bind on its own readiness signal — replace "myCmpReady" with the
            // event or callback your tool actually provides. The load event is
            // only a fallback: a tool that initialises after "load" would never
            // be caught by it.
            if (!bindMyCmp()) {
                document.addEventListener('myCmpReady', bindMyCmp);
                window.addEventListener('load', bindMyCmp);
            }
        }());
    </script>
{% endblock %}
```

Example for Usercentrics:

```twig
{% block momo_guest_wishlist_consent_bridge %}
    <script>
        window.addEventListener('ucEvent', function (event) {
            if (!event.detail || typeof event.detail !== 'object') {
                return;
            }

            // Use the service name from your Usercentrics admin
            window.MomoWishlistConsent.set(event.detail['Momo Advanced Wishlists'] === true);
        });
    </script>
{% endblock %}
```

Ready-made blocks for Cookiebot and Borlabs Cookie are available in the plugin's `README.md`.

### The `window.MomoWishlistConsent` Interface

| Method                 | Behaviour                                                                                                                                                                                                      |
| ---------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `set(granted)`         | Grants or withdraws consent. No change is announced when the state is already the one you set. `set(false)` still deletes the cookie and the stored wishlist on every call, so it remains a reliable hard cut. |
| `isGranted()`          | Returns the currently resolved consent state.                                                                                                                                                                  |
| `onChange(callback)`   | Registers a listener and returns an unsubscribe function.                                                                                                                                                      |
| `registerResolver(fn)` | Registers a resolver that may return `true`, `false` or `null` (no opinion).                                                                                                                                   |
| `refresh()`            | Forces an immediate re-evaluation of all resolvers.                                                                                                                                                            |

The interface is available from the very first moment in the `<head>` — even very early calls from a consent tool are not lost; they are queued and applied once the theme has loaded.

**Evaluation order:** if *any* resolver returns `true`, consent counts as granted. Otherwise, if *any* resolver returns `false`, it counts as refused. If all abstain, the plugin's own consent cookie decides. A `true` deliberately beats every `false` — a resolver returning `true` has positively observed consent, whereas `false` often only means it could not confirm any yet. This implies a rule for your glue code: after a withdrawal, no resolver may keep returning `true`. The consequence depends on how the withdrawal reaches the plugin:

* **Through `set(false)`** — the consent cookie and the stored guest wishlist are deleted first, but the re-evaluation that follows sees the stale `true` and immediately grants consent again. The withdrawal does not stick: no change is announced, and the visitor can save new items right away.
* **Through a re-evaluation only** (Shopware's cookie banner, a returning browser tab) — the stale `true` means no change is detected at all, so no cleanup runs and the stored data stays.

Return `false` for an explicit refusal — or when the consent state you read is present but does not say yes. Return `null` when you have no opinion: your consent tool has not finished loading, or the value you would read has not been written yet. This is the same contract the built-in cookie evaluation of the **Foreign cookie** source follows, and the reason a missing cookie is an abstention rather than a refusal.

The cookie name, lifetime and active consent source are exposed to your glue code as data attributes on the `[data-momo-guest-wishlist-storage]` element. Read the values from there instead of hard-coding them.

***

## No Consent Check

With this source, the guest wishlist is active without any check. This makes sense if your consent handling happens entirely outside Shopware and you control the feature elsewhere.

Note that **no check means "no gate", not "consent granted"**. There is no consent state that could be withdrawn — `set(false)` has no effect in this source. Never test your glue code with this setting; test it with the source you intend to run in production.

***

## Behaviour Without Consent

When no consent is present, the **Wishlist control without guest consent** field in the **Storefront Appearance** section determines what the visitor sees. Unlike the consent source, this setting is configurable **per sales channel**.

* **Hide the control** *(default)* — The wishlist icon or button is not rendered at all. Existing installations behave exactly as before after an update.
* **Show the control and ask for consent** — The control stays visible but inactive. When the visitor clicks it, Shopware's cookie settings dialog opens. If that dialog is unavailable (for example because you use an external consent tool), a dismissible hint appears instead, explaining that consent is required for the wishlist.

**No product is ever saved while consent is missing.** The control never reports a successful save that did not happen. Items clicked before consent was granted are not added retroactively either — the visitor simply clicks again.

The hint text follows your selected [terminology preset](https://github.com/momocode-de/plugin-gitbook/tree/en/shopware-6/advanced-wishlists/configuration.md#terminology-preset) and can be customised under **Settings → Snippets** via the key `momoAdvancedWishlists.storefront.consent.requiredHint`.

The setting has no effect when the guest wishlist is disabled, when the consent source is set to **No consent check**, or when the product card button position is set to **No button**.

***

## Withdrawing Consent

When a visitor withdraws consent, the plugin immediately deletes:

* the plugin's own consent cookie
* the guest wishlist stored in the browser (`localStorage`)

The guest wishlist is empty afterwards and the header counter updates without a page reload. This applies equally to a withdrawal made through Shopware's cookie banner and one made through the JavaScript interface.

**Changing the consent source, by contrast, never deletes data.** If you switch from **Shopware cookie banner** to **Foreign cookie**, for example, visitors holding a still-valid plugin cookie remain enabled — that cookie continues to serve as a fallback. If you want a hard cut, call `window.MomoWishlistConsent.set(false)` once in the bridge block.

***

## When Consent Is Evaluated

The plugin does **not** poll for the consent state. It is evaluated:

* on page load
* when Shopware's cookie banner saves a changed selection
* when the visitor returns to the browser tab
* on an explicit `refresh()` from your glue code

As a result, changes take effect immediately and without a page reload — the wishlist control appears or disappears right away.


# 5. Storefront Usage

## Wishlist Overview

Customers access their wishlists via **My Account → My Wishlists** or via the heart icon in the storefront header. The overview page shows:

* All personal wishlists with name, item count, and visibility (public/private)
* Action buttons for renaming and deleting a list
* A **Create new wishlist** button
* Below (if configured): the merchant's global wishlists as "Shop recommendations"

![My Wishlists overview page](/files/urVwV7rmxTEWwqqJgJpB)

## Creating a New Wishlist

1. On the overview page, click **Create new wishlist**.
2. Enter a name and confirm.

Alternatively, when adding a product via the heart icon dropdown, select **Create new list** — the wishlist is created on the fly.

## Adding Products to a Wishlist

> The displayed icon and the label "Wishlist" can be customised in the [Configuration](/en/shopware-6/advanced-wishlists/3.-configuration) — for example, a star instead of a heart, or "Order list" instead of "Wishlist".

The icon appears on:

* Product cards in listings and search results
* The product detail page
* Cart line items (cart page, checkout, order confirmation)

Clicking the heart icon opens a dropdown listing all available wishlists. Products already on a list are marked with a checkmark. Clicking a checked list **removes** the product (toggle behavior). At the bottom of the dropdown is the **Create new list** option.

### Guest Visitors

If the guest wishlist is enabled in the plugin settings, products can be saved without logging in. The data is stored in the browser's localStorage. When the guest logs in or registers, their items are automatically merged into their first wishlist.

Whether consent is required for this is determined by the **Consent source** setting:

* **Shopware cookie banner** (default), **Foreign cookie (consent-management tool)** and **Custom (JavaScript API)** — nothing is stored until consent has been granted. With the default, that consent comes from Shopware's cookie banner, category "Functional".
* **No consent check** — no consent gate applies: the guest wishlist is active without any check and the control is usable immediately. There is also no consent state in this mode, so there is nothing that could be granted or withdrawn — the two paragraphs below do not apply.

When a consent check is active, the wishlist icon appears in the header and on product cards **immediately** once the visitor grants consent — no reload or navigation required. If they withdraw consent, the consent cookie and the stored guest wishlist are deleted right away and the header counter resets to zero.

> **Note:** While a consent check is active and no consent is present, the wishlist control is hidden by default. You can instead configure it to stay visible and ask for consent when clicked. With **No consent check** this setting has no effect, since the control is always usable anyway. For which of the four sources applies and how to connect an external consent management tool, see [Consent & Consent Tools](/en/shopware-6/advanced-wishlists/4.-consent).

## Wishlist Detail Page

The wishlist detail page provides the following features:

### Managing Items

* **Change quantity** — Each item has +/− buttons and a quantity field. Changes are saved automatically via AJAX.
* **Add to cart** — Per-item button; the off-canvas cart opens automatically.
* **Add all to cart** — Adds all items (with their individual quantities) to the cart in one action.
* **Multi-select** — Select items via checkboxes and add them to the cart together.
* **Remove item** — Removes the item from the wishlist (no cart action).

### Add by Product Number

Below the item list is a collapsible **Add by product number** section. Enter a product number (SKU) and optionally a quantity. The product is immediately added to the wishlist if found.

### Unavailable Products

If the corresponding option is enabled in the configuration, a dedicated section for inactive or channel-removed products appears above the regular item list. Customers can:

* Remove the unavailable item directly from the wishlist.
* Add a merchant-assigned alternative product to the wishlist with a single click.

![Wishlist detail page with items and quantities](/files/gMhm7tuAhMhtoc0PKO8L)

### CSV Export and Import

* **Export as CSV** — Downloads the current wishlist as a CSV file (columns: product number, name, quantity, date added).
* **Import from CSV** — Opens a file selection dialog. The CSV file must contain at least a column with product numbers. Items not found and duplicates are skipped and listed in a summary.

### Price-Drop Notifications

The detail page includes (when globally enabled) a **Price-drop notifications** toggle. Customers can turn this on or off per wishlist independently. When active, they receive an email when any item on this wishlist drops in price.

## Sharing a Wishlist

1. On the detail page, click **Make public**. The visibility changes to "Public".
2. A share link section appears with buttons for WhatsApp, Email, and **Copy link**.
3. Share the link. Recipients can browse the wishlist without logging in.

Click **Make private** to block access immediately (the link becomes invalid, but the token is preserved in case the list is made public again later).

### Public Wishlist for Recipients

Share link recipients see:

* The wishlist name and owner's name
* All items as standard Shopware product cards (with image, name, variants, price, add-to-cart button)
* Share buttons (WhatsApp, Email, Copy link)
* A **Save as my wishlist** button (for logged-in customers)

![Public wishlist — recipient view](/files/Befpi1adNpNyypbl1kNr)

When saving as their own list, a new private wishlist is created with the same name, containing all items from the shared list.

## Saving the Cart as a Wishlist

On the cart page, a **Save as wishlist** button is available. A dropdown lets customers:

* Save all cart items to a new wishlist (default name: "Cart – {date}")
* Add all cart items to an existing wishlist (duplicates are skipped)

The cart is **not** cleared.


# 6. Admin Area

The plugin's admin area is accessible at **Customers → Wishlists**. It contains four tabs:

* **Customer Wishlists** — All wishlists from all customers
* **Global Wishlists** — Merchant-curated wishlists
* **Unavailable Products** — Inactive or channel-removed products on wishlists
* **Analytics** — Statistics and conversion rates

![Admin overview of all customer wishlists](/files/q7rlF9zCTFT80EyQ3ATz)

***

## Customer Wishlists

### Overview

The table shows all customer wishlists with:

* Wishlist name
* Customer name (clickable — opens the customer detail page)
* Item count
* Visibility (public/private)
* Date created

Use the search bar to filter by wishlist name or customer name. Columns are sortable.

### Wishlist Detail View

Click a row to open the detail view with:

* Basic information (name, customer, visibility, item count, creation date)
* Table of all products (name with variant properties, product number, price, quantity, date added)

![Wishlist detail view in the admin](/files/APy5yx0lMz1k6L7EBzAZ)

### Wishlists in the Customer Profile

On the customer detail page (**Customers → \[Customer Name]**), the **Wishlists** tab lists all wishlists for that customer with direct links to each detail view.

![Wishlists tab in the customer profile](/files/jmuDFfWOlYjh9JebD1qg)

***

## Global Wishlists

Merchants can create curated wishlists that are visible to all customers in the storefront (or only to customers of a specific sales channel). These lists appear on the customer wishlist overview page under "Shop recommendations".

![Global wishlists in the admin](/files/mBvFRrYB9WqCDwJTKfYh)

### Creating a Global Wishlist

1. Open the **Global Wishlists** tab.
2. Click **Create global wishlist**.
3. Enter a name, optionally assign a sales channel (no sales channel = visible in all channels), and set a position.
4. Add products via the product search field.
5. Save.

### Editing a Global Wishlist

Click a row in the Global Wishlists table to edit the name, sales channel, position, and products.

![Global wishlist detail — edit products and settings](/files/lfn0UFxOirGsW3oKJO0L)

### Deleting a Global Wishlist

Use the context menu (three dots) in the table or the detail view. A delete confirmation is shown.

***

## Unavailable Products

The **Unavailable Products** tab lists all products that:

* Appear on at least one customer wishlist **and**
* Are inactive or removed from the associated sales channel

| Column       | Description                                          |
| ------------ | ---------------------------------------------------- |
| Product      | Name and product number (clickable → product detail) |
| Reason       | Inactive or not in sales channel                     |
| Wishlists    | Number of wishlists the product appears on           |
| Alternatives | Number of assigned active alternative products       |
| Global       | Present on a global wishlist                         |

![Unavailable products — overview](/files/9tFsUq0it6ygQHTTMQo2)

### Assigning Alternative Products

1. Click a row to open the detail view.
2. In the **Alternative products** section, add products via the product search.
3. Save.

![Assigning alternative products — detail view](/files/TyhXJnJUEHbAQNKa9xFf)

The assigned alternatives are shown to customers on the storefront wishlist detail page as replacement suggestions.

***

## Analytics

The analytics page provides an overview of wishlist activity in your shop:

![Analytics dashboard](/files/OuPB6VWDQJoTsvQOVaeb)

### Date Filter

Filter all analytics by any time period using the **From** / **To** date fields.

### Key Metrics

* **Total wishlists** — Number of all customer wishlists in the selected period
* **Total items** — Number of all wishlist items in the selected period
* **Conversion rate** — Share of wishlisted items that were subsequently purchased (within the configured conversion window)

### Most-Wishlisted Products

Table of products that appear most often on wishlists, sorted by number of unique customers. Rows are clickable to the product detail page.

### Activity Trends

Chart of wishlist items added per day/week/month (granularity selectable via a dropdown).

### ACL Permission

The analytics page is protected by the ACL privilege `momo_wishlist_analytics.viewer`. Admin users without this privilege cannot see the analytics section.


# 7. Price-Drop Notifications

The plugin can automatically send customers email notifications when products on their wishlists drop in price. Two things are required:

1. The feature is **globally enabled** in the plugin settings (active by default).
2. A **Flow Builder** flow is set up to send the email.

## How Price Tracking Works

When a customer adds a product to a wishlist, the plugin automatically saves the current gross unit price and currency ID. This stored price serves as the reference for future comparisons.

A **scheduled background task** periodically checks all wishlist items for price changes. When the current price drops below the stored reference price (minus the configured threshold), a Flow Builder event is dispatched.

> **Note:** The Scheduled Task Worker must be running. Without it, no checks are performed and no notifications are sent.

## Configuring the Threshold

In the [plugin settings](/en/shopware-6/advanced-wishlists/3.-configuration) under **Price Drop Notifications**, you can configure:

* **Threshold type** — `Percentage` or `Absolute value`
* **Minimum price drop threshold** — e.g. `5` for 5 % or €5

Only price drops that exceed the threshold trigger a notification. This filters out micro-fluctuations (e.g. from rounded currency conversions).

## Setting Up the Flow Builder

The plugin provides the **"Wishlist Price Drop"** event (technically: `momo_advanced_wishlists.price_drop`) for the Flow Builder.

### Step 1: Create a flow

1. Go to **Marketing → Flow Builder**.
2. Click **Create flow**.
3. Give the flow a descriptive name (e.g. "Price drop notification").

### Step 2: Select the trigger

1. Click **Add trigger**.
2. Search for **Wishlist Price Drop** or scroll to the Wishlist category.
3. Select the event.

### Step 3: Add an action

1. Click **Add action**.
2. Select **Send email**.
3. Choose a recipient — for customer notifications: **Customer (Wishlist)**.
4. Select an email template or create a new one. The plugin automatically creates the **"Wishlist Price Drop Notification"** template during installation — you can select and use it right away.

### Step 4: Design the email template

The following variables from the price-drop event are available in the email template:

| Variable                | Content                                          |
| ----------------------- | ------------------------------------------------ |
| `{{ customer }}`        | Customer object (firstName, lastName, email, id) |
| `{{ priceDropItems }}`  | Array of affected items (see below)              |
| `{{ currencyIsoCode }}` | Currency code (e.g. `EUR`)                       |

Each element in `priceDropItems` contains:

| Key                 | Content                              |
| ------------------- | ------------------------------------ |
| `productName`       | Product name                         |
| `productId`         | Product ID                           |
| `oldPrice`          | Original price (float)               |
| `newPrice`          | Current price (float)                |
| `savingsAmount`     | Savings amount (absolute, float)     |
| `savingsPercentage` | Savings percentage (float)           |
| `productUrl`        | URL to the product in the storefront |

**Example Twig for the email template:**

```twig
Hello {{ customer.firstName }},

the following products on your wishlists have dropped in price:

{% for item in priceDropItems %}
- {{ item.productName }}
  Was:  {{ item.oldPrice }} {{ currencyIsoCode }}
  Now:  {{ item.newPrice }} {{ currencyIsoCode }}
  You save: {{ item.savingsAmount }} {{ currencyIsoCode }} ({{ item.savingsPercentage }}%)
  View product: {{ item.productUrl }}
{% endfor %}

Best regards,
Your shop team
```

### Step 5: Activate the flow

Make sure the flow is set to **Active** before saving.

## Customer Opt-In

For a customer to receive notifications, they must **enable the feature per wishlist**:

1. Open the wishlist detail page in the storefront.
2. In the **Price-drop notifications** section, activate the toggle.

Customers can deactivate the toggle at any time. If the feature is globally disabled in the plugin settings, the toggle is hidden in the storefront.

## Frequently Asked Questions

**Are notifications sent for all price drops?** No. Only price drops that exceed the configured threshold trigger a notification.

**Is a notification sent each time the price drops further?** Yes — each check where the price is below the stored reference price dispatches an event. The reference price is not automatically updated.

**What happens if a product is removed from the catalogue?** Items for which no price can be resolved are skipped during the check. No notification and no error message is triggered.


# Plugins & Apps


# Bestätigungsmail für Formulare


# 1. Beschreibung

Wenn ein Besucher ein Formular abschickt, bekommt standardmäßig nur der Shopbetreiber eine E-Mail mit der Zusammenfassung. Mit diesem Plugin bekommen Sie die Möglichkeit, automatische Bestätigungsmails an den Absender zu schicken, wenn dieser ein Formular ausgefüllt und abgeschickt hat.

Sie können über das Shopware Backend-Modul für E-Mail-Vorlagen beliebige Vorlagen erstellen und diese über ein Freitextfeld mit Ihren Formularen verknüpfen. In den E-Mail-Vorlagen können Sie sowohl auf die Felder und dessen Namen, als auch auf die vom Absender ausgefüllten Werte zugreifen, falls Sie in der E-Mail darauf Bezug nehmen wollen. Wichtig ist nur, dass Ihr Formular ein Feld vom Typ "email" enthält, denn an die dort eingetragene E-Mail-Adresse wird die Bestätigungsmail verschickt. Ohne ein E-Mail-Feld, kann das Plugin nicht wissen, wohin es die Bestätigungsmail schicken soll.

Wenn ein Formular mehrere E-Mail-Felder besitzt, wird die Bestätigungsmail an die Adresse geschickt, die in das erste E-Mail-Feld eingetragen wurde. Positionieren Sie Ihre Felder also dementsprechend richtig.

Sie können selbst bestimmen, welche Formulare mit welchen E-Mail-Vorlagen verknüpft werden. Bei Formularen, die mit keiner E-Mail-Vorlage verknüpft sind, wird auch keine E-Mail an den Absender geschickt.

Das Plugin ist auch mit Sub- und Sprachshops kompatibel. Sofern für die E-Mail-Vorlage die entsprechende Übersetzung vorhanden ist, bekommt der Absender die Bestätigungsmail in der Sprache, die für den Shop konfiguriert ist, in dem er sich gerade befindet.

Das Plugin setzt mindesten PHP 5.6 voraus. Entwickelt und getestet wurde es für Shopware 5.3.0 bis 5.6.x. Sollten Sie einen Fehler feststellen, würde ich mich freuen, wenn Sie mich über das Shopware Support-Tool darüber informieren. Sollten Sie einen Verbesserungsvorschlag oder individuelle Anpassungswünsche haben, können Sie mich über <moritz@momocode.de> kontaktieren.

### Kompatibilität zu anderen Plugins

#### BogxEmbeddedForm (Formulare Widget)

Mit dem BogxEmbeddedForm Plugin können Formulare z.B. in Einkaufswelten eingefügt werden. Für dieses Plugin wurde eine Kompatibilität geschaffen, sodass auch bei diesen Formularen eine Bestätigungsmail an den Absender geschickt werden kann. Beachten Sie aber, dass eine Kompatibilität zu anderen Plugins nicht für jede Version des Plugins gewährleistet werden kann, da man keinen Einfluss darauf hat, was andere Entwickler mit ihren Plugins machen. Das BogxEmbeddedForm Plugin wurde in der Version 3.3.2 getestet. Sollten Sie eine Version haben, die nicht mehr mit diesem Plugin kompatibel ist, können Sie mich gerne unter <moritz@momocode.de> kontaktieren.

### Sie wollen auch dem Empfänger eines Formulars eine Mail mit einer HTML-Vorlage schicken?

Mit meinem Plugin "HTML E-Mail für Formulare" ist dies möglich. Das Plugin schickt auch dem Empfänger eine Mail mit einer ausgewählten E-Mail-Vorlage. Nutzen Sie die Gelegenheit und erwerben Sie direkt beide Plugins in einem Bundle!


# 2. Installationsanleitung

1. Plugin herunterladen und die ZIP-Datei im Plugin-Manager des Shopware Backends hochladen
2. Plugin mit Klick auf das Installieren-Icon installieren und danach aktivieren
3. Durch die Plugin-Installation wurde ein neues Freitextfeld für Formulare angelegt. Öffnen Sie im Backend unter "Inhalte -> Formulare" ein Formular und prüfen Sie, ob das neue Freitextfeld im Bereich "Freitextfelder" vorhanden ist.


# 3. Konfiguration

Sie können jetzt unter "Einstellungen -> E-Mail-Vorlagen" bzw. ab Shopware 5.6 unter "Einstellungen -> E-Mail-Management -> E-Mail-Vorlagen" im Ordner "Benutzer-E-Mails" beliebige E-Mail-Vorlagen für Ihre Formulare anlegen. In diesen E-Mail-Vorlagen haben Sie Zugriff auf verschiedene Variablen, u.A. auf die Namen der Felder des Formulars und auf die vom Absender abgeschickten Werte. Sollten Sie zum Beispiel eine Vorlage mit dem Standard Formular "Kontaktformular" verknüpfen, stehen Ihnen folgende Variablen zur Verfügung:

{$sShop}: Shopware Demo\
{$sShopURL}: <http://example.com\\>
{$momoFormData.anrede.label}: Anrede\
{$momoFormData.anrede.value}: Herr\
{$momoFormData.vorname.label}: Vorname\
{$momoFormData.vorname.value}: Moritz\
{$momoFormData.nachname.label}: Nachname\
{$momoFormData.nachname.value}: Müller\
{$momoFormData.email.label}: eMail-Adresse\
{$momoFormData.email.value}: <moritz@momocode.de>\
{$momoFormData.telefon.label}: Telefon\
{$momoFormData.telefon.value}:\
{$momoFormData.betreff.label}: Betreff\
{$momoFormData.betreff.value}: Kontaktanfrage\
{$momoFormData.kommentar.label}: Kommentar\
{$momoFormData.kommentar.value}: Sehr geehrte Damen und Herren...

Sie sehen also, dass Sie pro Feld auf das Label und auf den vom Absender abgeschickten Wert zugreifen können. Ab Version 1.1.0 des Plugins werden auch Felder vom Typ "text2" unterstützt. Wenn das Feld beispielsweise den Namen "plz;ort" mit dem Label "PLZ;Ort" hat, stehen in der E-Mail-Vorlage folgende Variablen getrennt zur Verfügung:

{$momoFormData.plz.label}: PLZ\
{$momoFormData.plz.value}: ...\
{$momoFormData.ort.label}: Ort\
{$momoFormData.ort.value}: ...

Sollten Ihre Feld-Namen Sonderzeichen oder Umlaute enthalten, müssen die Variablen wie folgt in die Vorlage eingebaut werden:

{$momoFormData\['straße'].label}: Straße\
{$momoFormData\['straße'].value}: Hauptstraße\
{$momoFormData\['nationalität'].label}: Nationalität\
{$momoFormData\['nationalität'].value}: Deutsch

Wenn die E-Mail-Vorlage angelegt ist, können Sie diese mit dem Formular verknüpfen, indem Sie sie in dem Freitextfeld des Formulars auswählen. Bei Formularen, wo nichts in dem Freitextfeld ausgewählt wird, wird auch keine E-Mail an den Absender geschickt.

Wichtig ist nur, dass Ihr Formular ein Feld vom Typ "email" enthält, denn an die dort eingetragene E-Mail-Adresse wird die Bestätigungsmail verschickt. Ohne ein E-Mail-Feld, kann das Plugin nicht wissen, wohin es die Bestätigungsmail schicken soll. Wenn ein Formular mehrere E-Mail-Felder besitzt, wird die Bestätigungsmail an die Adresse geschickt, die in das erste E-Mail-Feld eingetragen wurde. Positionieren Sie Ihre Felder also dementsprechend richtig.


# HTML E-Mail für Formulare


# 1. Beschreibung

Standardmäßig kann bei einem Formular nur eine Plain-Text E-Mail gepflegt werden. Die E-Mail, die dann beim Formular-Empfänger ankommt, sieht dann ungestyled und unübersichtlich aus. Mit diesem Plugin bekommen Sie die Möglichkeit, Formularen eine E-Mail-Vorlage zuzuweisen. Somit kann eine schöne und übersichtliche HTML-E-Mail an den Empfänger geschickt werden.

Sie können über das Shopware Backend-Modul für E-Mail-Vorlagen beliebige Vorlagen erstellen und diese über ein Freitextfeld mit Ihren Formularen verknüpfen. In den E-Mail-Vorlagen können Sie sowohl auf die Felder und dessen Namen, als auch auf die vom Absender ausgefüllten Werte zugreifen, damit der Formular-Empfänger die Daten bewerten kann.

Sie können selbst bestimmen, welche Formulare mit welchen E-Mail-Vorlagen verknüpft werden. Bei Formularen, die mit keiner E-Mail-Vorlage verknüpft sind, wird weiterhin die Plain-Text E-Mail verschickt. Bei Formularen, denen eine E-Mail-Vorlage zugewiesen ist, wird die Plain-Text E-Mail ersetzt, das heißt es werden nicht beide Mails verschickt, sondern dann nur die HTML-E-Mail. Als Empfänger wird in beiden Fällen die E-Mail-Adresse genommen, die beim Formular hinterlegt ist. Es gibt für HTML-E-Mails also kein extra Feld für den Empfänger, sondern es wird der Empfänger aus dem Standard-Feld genommen.

Das Plugin setzt mindesten PHP 5.6 voraus. Entwickelt und getestet wurde es für Shopware 5.3.0 bis 5.6.x. Sollten Sie einen Fehler feststellen, würde ich mich freuen, wenn Sie mich über das Shopware Support-Tool darüber informieren. Sollten Sie einen Verbesserungsvorschlag oder individuelle Anpassungswünsche haben, können Sie mich über <moritz@momocode.de> kontaktieren.

### Sie wollen auch dem Absender eines Formulars eine Bestätigungsmail schicken?

Mit meinem Plugin "Bestätigungsmails für Formulare" ist dies möglich. Das Plugin schickt auch dem Absender eine Mail mit einer ausgewählten E-Mail-Vorlage. Nutzen Sie die Gelegenheit und erwerben Sie direkt beide Plugins in einem Bundle!


# 2. Installationsanleitung

1. Plugin herunterladen und die ZIP-Datei im Plugin-Manager des Shopware Backends hochladen
2. Plugin mit Klick auf das Installieren-Icon installieren und danach aktivieren
3. Durch die Plugin-Installation wurde ein neues Freitextfeld für Formulare angelegt. Öffnen Sie im Backend unter "Inhalte -> Formulare" ein Formular und prüfen Sie, ob das neue Freitextfeld im Bereich "Freitextfelder" vorhanden ist.


# 3. Konfiguration

Sie können jetzt unter "Einstellungen -> E-Mail-Vorlagen" bzw. ab Shopware 5.6 unter "Einstellungen -> E-Mail-Management -> E-Mail-Vorlagen" im Ordner "Benutzer-E-Mails" beliebige E-Mail-Vorlagen für Ihre Formulare anlegen. In diesen E-Mail-Vorlagen haben Sie Zugriff auf verschiedene Variablen, u.A. auf die Namen der Felder des Formulars und auf die vom Absender abgeschickten Werte. Sollten Sie zum Beispiel eine Vorlage mit dem Standard Formular "Kontaktformular" verknüpfen, stehen Ihnen folgende Variablen zur Verfügung:

{$sShop}: Shopware Demo\
{$sShopURL}: <http://example.com\\>
{$momoFormData.anrede.label}: Anrede\
{$momoFormData.anrede.value}: Herr\
{$momoFormData.vorname.label}: Vorname\
{$momoFormData.vorname.value}: Moritz\
{$momoFormData.nachname.label}: Nachname\
{$momoFormData.nachname.value}: Müller\
{$momoFormData.email.label}: eMail-Adresse\
{$momoFormData.email.value}: <moritz@momocode.de>\
{$momoFormData.telefon.label}: Telefon\
{$momoFormData.telefon.value}:\
{$momoFormData.betreff.label}: Betreff\
{$momoFormData.betreff.value}: Kontaktanfrage\
{$momoFormData.kommentar.label}: Kommentar\
{$momoFormData.kommentar.value}: Sehr geehrte Damen und Herren...

Sie sehen also, dass Sie pro Feld auf das Label und auf den vom Absender abgeschickten Wert zugreifen können. Ab Version 1.1.0 des Plugins werden auch Felder vom Typ "text2" unterstützt. Wenn das Feld beispielsweise den Namen "plz;ort" mit dem Label "PLZ;Ort" hat, stehen in der E-Mail-Vorlage folgende Variablen getrennt zur Verfügung:

{$momoFormData.plz.label}: PLZ\
{$momoFormData.plz.value}: ...\
{$momoFormData.ort.label}: Ort\
{$momoFormData.ort.value}: ...

Sollten Ihre Feld-Namen Sonderzeichen oder Umlaute enthalten, müssen die Variablen wie folgt in die Vorlage eingebaut werden:

{$momoFormData\['straße'].label}: Straße\
{$momoFormData\['straße'].value}: Hauptstraße\
{$momoFormData\['nationalität'].label}: Nationalität\
{$momoFormData\['nationalität'].value}: Deutsch

Wenn die E-Mail-Vorlage angelegt ist, können Sie diese mit dem Formular verknüpfen, indem Sie sie in dem Freitextfeld des Formulars auswählen. Bei Formularen, wo nichts in dem Freitextfeld ausgewählt wird, wird weiterhin die normale Plain-Text E-Mail, die beim Formular gepflegt ist, verschickt.

Wie es auch bei der Plain-Text E-Mail der Fall ist, wird die E-Mail dann an die E-Mail-Adresse geschickt, die beim Formular hinterlegt ist.


# Bestätigungsmail für Formulare


# 1. Beschreibung

Da es in der aktuellen Shopware 6 Version noch keine individuellen Formulare gibt, sondern nur das Kontakt- und Newsletter-Formular, ist dieses Plugin im Gegensatz zur Shopware 5 Version nur auf das Kontakt-Formular beschränkt. Für das Newsletter-Formular gibt es ja standardmäßig schon eine Mail an den Absender des Formulars. Sobald auch individuelle Formulare in Shopware 6 möglich sind, wird das Plugin erweitert und die Beschränkung auf das Kontakt-Formular wird aufgehoben.

Wenn ein Besucher das Kontakt-Formular abschickt, bekommt standardmäßig nur der Shopbetreiber eine E-Mail mit der Zusammenfassung. Mit diesem Plugin bekommen Sie die Möglichkeit, automatische Bestätigungsmails an den Absender zu schicken, wenn dieser das Kontakt-Formular ausgefüllt und abgeschickt hat.

Sie können über die Shopware Administration beliebige E-Mail-Vorlagen erstellen und diese über die Formular-Konfiguration mit Ihrem Kontakt-Formular verknüpfen. In den E-Mail-Vorlagen können Sie auf die vom Absender ausgefüllten Werte zugreifen, falls Sie in der E-Mail darauf Bezug nehmen wollen. Im Gegensatz zur Shopware 5 Version der App stehen in dieser Version leider nicht die Beschriftungen der Formular-Felder in der E-Mail als Variablen zur Verfügung, sondern nur die ausgefüllten Werte. Die E-Mail an den Absender wird an die Adresse verschickt, die er in das E-Mail Feld des Kontakt-Formulars eingetragen hat.

Sollten Sie für Ihr Kontakt-Formular keine E-Mail-Vorlage auswählen, wird auch keine E-Mail an den Absender geschickt.

Die App ist auch mit Sub- und Sprachshops kompatibel. Sofern für die E-Mail-Vorlage die entsprechende Übersetzung vorhanden ist, bekommt der Absender die Bestätigungsmail in der Sprache, die für den Shop konfiguriert ist, in dem er sich gerade befindet.


# 2. Installationsanleitung

1. App herunterladen und die ZIP-Datei im Plugin-Manager der Shopware Administration hochladen
2. App über die Schaltflächen installieren und danach aktivieren


# 3. Konfiguration

Durch die App-Installation wurde ein neuer Typ für E-Mail-Vorlagen angelegt. Sie können jetzt in der Administration unter "Einstellungen -> E-Mail-Vorlagen" beliebige E-Mail-Vorlagen für Ihr Kontakt-Formular anlegen. Wichtig ist, dass als "Typ" der neue Typ "Formular Bestätigung an Kunden" ausgewählt wird. Die restlichen Einstellungen können Sie nach Belieben vornehmen. Ein Verkaufskanal muss für die E-Mail-Vorlage nicht ausgewählt werden. Im Mail-Text haben Sie Zugriff auf die vom Absender abgeschickten Werte. Für das Kontakt-Formular sind das folgende Variablen:

`{{ contactFormData.firstName }}`: Moritz\
`{{ contactFormData.lastName }}`: Müller\
`{{ contactFormData.email }}`: <moritz@momocode.de>\
`{{ contactFormData.phone }}`: 123456789\
`{{ contactFormData.subject }}`: Frage zum Artikel "XY"\
`{{ contactFormData.comment }}`: Hallo! Ich habe eine Frage zum Artikel "XY" ...\
`{{ contactFormData.salutation.salutationKey }}`: mr\
`{{ contactFormData.salutation.displayName }}`: Herr\
`{{ contactFormData.salutation.letterName }}`: Sehr geehrter Herr

Sie sehen also, dass Sie pro Feld auf den vom Absender abgeschickten Wert zugreifen können.

Um die E-Mail-Vorlage jetzt mit Ihrem Kontakt-Formular verknüpfen zu können und somit die Bestätigungsmail an den Kunden zu aktivieren, müssen Sie wie folgt vorgehen:

Gehen Sie in der Shopware Administration auf "Inhalte -> Erlebniswelten". Nun haben Sie zwei Möglichkeiten, um ein neues Layout mit einem Kontakt-Formular anzulegen. Entweder Sie duplizieren die gesperrte Standard Vorlage "Standard Shopseiten-Layout mit Kontaktformular" und bearbeiten die neu angelegte Vorlage, oder Sie gehen auf "Neues Layout anlegen", wählen dann "Shopseite" und geben die weiteren abgefragten Konfigurationen an. Wenn Sie die Standard Vorlage dupliziert haben, existiert bereits das Kontakt-Formular als Block. Wenn Sie ein neues Layout angelegt haben, müssen Sie in der rechten Spalte auf das + klicken, dann unter "Block-Kategorie" "Formular" auswählen und das Formular-Element nach links in den Vorschau-Bereich ziehen. Wenn Sie nun auf das Element klicken und mit der Maus über das Element fahren, erscheint in der rechten oberen Ecke des Elements ein Zahnrad-Symbol. Wenn Sie auf das Symbol klicken, erscheint ein Popup mit den Einstellungen des Formulars. Wenn im Tab "Inhalt" unter "Formulartyp" das Formular "Kontakt" ausgewählt ist, existiert gleichzeitig der durch die App hinzugefügte Tab "Bestätigungsmail". Wenn Sie in diesen Tab wechseln, können Sie dort die zuvor angelegte E-Mail-Vorlage auswählen. In dem Auswahl-Feld wird der Betreff der E-Mail-Vorlage angezeigt, da dies das aussagekräftigste Pflichtfeld für E-Mail-Vorlagen ist. Beachten Sie, dass in dem Auswahlfeld nur die E-Mail-Vorlagen zur Auswahl stehen, die vom Typ "Formular Bestätigung an Kunden" sind. Wählen Sie nun Ihre E-Mail-Vorlage aus und klicken Sie auf "Fertig" und speichern Sie dann das Layout. Zur weiteren Verwendung des Layouts folgen Sie bitte der Shopware Dokumentation.


# Bestätigungsmail für Formulare der CMS-Erweiterung


# 1. Beschreibung

Wenn ein Besucher ein Formular (der CMS-Erweiterung) abschickt, bekommt standardmäßig nur der Shopbetreiber eine E-Mail mit der Zusammenfassung. Mit dieser App bekommen Sie die Möglichkeit, automatische Bestätigungsmails an den Absender zu schicken, wenn dieser das Formular ausgefüllt und abgeschickt hat.

Die Konfiguration für die Bestätigungsmails findet über den Flow Builder statt. Die App stellt für jedes eigene Formular einen Trigger für den Flow-Builder zur Verfügung. Sie können also für jedes Formular einen eigenen Flow erstellen, als Auslöser dann einen der von der App bereitgestellten Trigger wählen und als Aktion dann den E-Mail-Versand konfigurieren. Beim E-Mail-Versand haben Sie verschiedene Möglichkeiten, u.A. die Bestätigungsmail an den Absender. Die E-Mail wird dann an die Adresse verschickt, die der Absender in das E-Mail Feld des Formulars eingetragen hat.

Sie können über die Shopware Administration beliebige E-Mail-Vorlagen erstellen und diese für den E-Mail-Versand in der Flow Konfiguration auswählen. In den E-Mail-Vorlagen können Sie auf die vom Absender ausgefüllten Werte zugreifen, falls Sie in der E-Mail darauf Bezug nehmen wollen.


# 2. Installationsanleitung

1. App herunterladen und die ZIP-Datei im Erweiterungs-Manager der Shopware Administration hochladen
2. App über die Schaltflächen installieren und danach aktivieren

**Hinweis:**

Bevor Sie die App installieren können, muss die CMS-Erweiterung installiert und aktiviert sein.


# 3. Konfiguration

Sobald Sie ein neues Formular der CMS-Erweiterung erstellt haben, wird automatisch ein neuer Trigger im Flow Builder bereitgestellt. Um die Bestätigungsmail zu aktivieren, müssen Sie also zuerst ein neuen Flow im Flow Builder anlegen. Als Auslöser für den Flow können Sie dann den Trigger des Formulars wählen und als Aktion können Sie dann "E-Mail verschicken" auswählen. In den Einstellungen der Aktion können Sie dann bei "Empfänger" die Option "Formular-Bestätigung" auswählen. Dadurch wird die E-Mail an die Adresse geschickt, die vom Absender im Formular angegeben wurde. Wichtig ist, dass es im Formular ein Feld mit dem internen Namen "email" gibt, denn an die in diesem Feld eingetragene Adresse wird dann die Bestätigungsmail geschickt.

Als E-Mail-Template können Sie jede beliebige Vorlage wählen. Wenn Sie in der Vorlage auf die vom Absender abgeschickten Daten Bezug nehmen wollen, können Sie die gleichen Variablen verwenden, die auch in der Vorlage für die E-Mail an den Shopbetreiber verfügbar sind. Diese können Sie sich in der E-Mail-Vorlage mit dem Typ "Custom Form" abgucken, die von der CMS-Erweiterung angelegt wurde.

**Achtung:**

Wenn Sie bei einem Formular, für das bereits ein Flow konfiguriert wurde, den internen Namen ändern, müssen Sie danach den Flow neu konfigurieren, da die Auslöser auf den internen Namen der Formulare basieren und im Flow dann noch der alte Name als Auslöser hinterlegt ist. Solche Flows werden dann automatisch deaktiviert, solange sie nicht aktualisiert wurden.


# Shop the Look


# 1. Beschreibung

Diese App bietet Ihnen die Möglichkeit, ein "Shop the Look" Element auf Produktseiten zu platzieren. Mit diesem Element können Sie dem Kunden direkt auf der Produktseite eines entsprechenden Produkts eine Auswahl von Looks präsentieren, die zu dem besuchten Produkt passen. Somit wird der Kunde zum Kauf von weiteren Produkten angeregt.

Es wurde versucht, die Pflege der Looks so komfortabel wie möglich zu gestalten. Es gibt verschiedene Wege und Automatismen, um Looks anzulegen. Somit ist es zum Beispiel möglich, einen Look bei einer Variante anzulegen und ihn dann automatisch auch bei allen anderen Varianten, die z.B. die gleiche Farbe aber eine andere Größe haben, anzulegen. Alternativ ist es auch möglich, Looks immer nur bei dem Haupt-Produkt anzulegen und automatisch bei allen Varianten des Produkts anzuzeigen. Mehr zu den verschiedenen Möglichkeiten finden Sie im Konfigurations-Teil dieser Dokumentation.

Neben den Möglichkeiten zur automatischen Übernahme von Looks innerhalb eines Produkts gibt es noch zwei verschiedene Arten von Looks, die je nach gewünschtem Anwendungsfall genutzt werden können. Bei der ersten Art handelt es sich um "Globale Looks". Globale Looks können sowohl in einem neuen Tab für die Produkt-Konfiguration als auch über ein extra Modul angelegt werden. Man kann für den Look einen internen Namen und die zu dem Look gehörenden Produkte festlegen. Der Look wird dann automatisch auf den Produktseiten aller im Look enthaltenen Produkte angezeigt.

Bei dem zweiten Vorgehen können Looks individuell für ein Produkt angelegt werden. Dies geht dann ebenfalls über den neuen Tab für die Produkt-Konfiguration. Hier können jetzt auch Looks mit internem Namen und verknüpften Produkten angelegt werden. Der Unterschied zum ersten Vorgehen ist, dass dieser Look dann nur für das eine Produkt angelegt wird und nicht für die anderen im Look enthaltenen Produkte. Dies kann zum Beispiel verwendet werden, wenn man bei einem Produkt genau die Produkte aus dem Produktbild als Look anlegen möchte und die verknüpften Produkte andererseits aber nicht diese Produkte in den Produktbildern haben und für die dieser Look somit nicht existieren soll.

Für das "Shop the Look" Element auf Produktseiten können dann noch verschiedene Einstellungen vorgenommen werden, wie zum Beispiel die Position oder das Produkt-Layout innerhalb des Elements. Diese Einstellungen können über ein weiteres neues Modul in der Administration gepflegt werden. Zusätzlich zu der globalen Konfiguration können diese Einstellungen aber auch über den neuen Tab in der Produkt-Konfiguration individuell für ein Produkt angepasst werden.

Über das "Shop the Look" Element auf der Produktseite hat man als Kunde die Möglichkeit, per Button auf eine extra Seite zu gelangen, auf der nochmal alle Produkte des Looks dargestellt werden. Diese Seite existiert als Erlebniswelt, weshalb Sie die Seite über die Administration individuell gestalten können.

Der Aufbau und das Aussehen des "Shop the Look" Elements auf den Produktseiten wurde auf Basis des Standard Themes von Shopware entiwckelt. Es sind alle Voraussetzungen erfüllt worden, damit das Element nach Ihren Wünschen in Ihrem eigenen Theme ohne Probleme erweitert und umgestyled werden kann. Gerne können Sie die App mit dem Erwerb einer Testversion testen und die Umsetzbarkeit Ihrer Änderungswünsche prüfen.


# 2. Installationsanleitung

1. App herunterladen und die ZIP-Datei im App-Manager der Shopware Administration hochladen
2. App über die Schaltflächen installieren und danach aktivieren




---

[Next Page](/llms-full.txt/1)

