You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
Class hierarchy: Plugin → Shopware\Bundle → Symfony\Bundle
32
+
Class hierarchy: `Plugin` → `Shopware\Bundle` → `Symfony\Bundle`
33
33
34
34
## When to use a bundle
35
35
@@ -79,7 +79,7 @@ project-root/
79
79
└── .shopware-project.yaml
80
80
```
81
81
82
-
The Bundle is typically placed in a project's `src/` folder, which is the standard location for custom code. You still will need to register the Bundle in the project's `config/bundles.php` file.
82
+
The Bundle is typically placed in a project's `src/` folder, which is the standard location for custom code. You will still need to register the Bundle in the project's `config/bundles.php` file.
83
83
84
84
## Choosing the right bundle class
85
85
@@ -144,7 +144,7 @@ if (Feature::isActive('YOUR_FEATURE_FLAG') && InstalledVersions::isInstalled('ve
144
144
You can add services, Twig templates, routes, etc., to your Bundle just as you would to a plugin. Create `Resources/config/services.php` and `Resources/config/routes.php` files, or `Resources/views` for Twig templates. The Bundle will be automatically detected, and the files will be loaded.
145
145
146
146
To mark your Bundle as a theme, you only need to implement the `Shopware\Core\Framework\ThemeInterface` interface in your bundle class.
147
-
This will automatically register your Bundle as a theme and make it available in the Shopware administration.
147
+
This will automatically register your Bundle as a theme and make it available in the Administration.
148
148
You can also add a `theme.json` file to define the theme configuration like [described here](../themes/configuration/theme-configuration.md).
149
149
150
150
## Adding migrations
@@ -170,7 +170,7 @@ class YourBundleName extends Bundle
170
170
}
171
171
```
172
172
173
-
Since Bundles don't have a lifecycle, migrations aren't automatically executed. Execute them manually via the console command:
173
+
Since bundles don't have a lifecycle, migrations aren't automatically executed. Execute them manually via the console command:
174
174
175
175
```bash
176
176
bin/console database:migrate <BundleName> --all
@@ -193,11 +193,11 @@ The Shopware CLI cannot automatically detect bundles. Therefore, bundle assets a
193
193
{
194
194
"extra": {
195
195
"shopware-bundles": {
196
-
"src/<BundleName>": {
197
-
"name": "<BundleName>",
198
-
}
199
-
}
200
-
}
196
+
"src/<BundleName>": {
197
+
"name": "<BundleName>"
198
+
}
199
+
}
200
+
}
201
201
}
202
202
```
203
203
@@ -207,8 +207,8 @@ This will tell Shopware CLI where the Bundle is located and its name.
207
207
208
208
Now that you know about the differences between a Symfony bundle and a Shopware plugin, review the following guides:
Copy file name to clipboardExpand all lines: guides/plugins/plugins/creating-plugins.md
+7-17Lines changed: 7 additions & 17 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -5,14 +5,10 @@ nav:
5
5
6
6
---
7
7
8
-
##Creating Plugins
8
+
# Creating Plugins
9
9
10
10
This guide walks you through creating and scaffolding a basic Shopware plugin so it can be installed locally on your Shopware 6 instance.
11
11
12
-
::: info
13
-
Refer to this video on [Creating a plugin](https://www.youtube.com/watch?v=_Tkoq5W7woI) that shows how to bootstrap a plugin. Also available on our free online training ["Shopware 6 Backend Development"](https://academy.shopware.com/courses/shopware-6-backend-development-with-jisse-reitsma).
14
-
:::
15
-
16
12
## Prerequisites
17
13
18
14
You'll need:
@@ -21,8 +17,6 @@ You'll need:
21
17
* A running Shopware 6 instance; refer to our [Install Shopware 6](../../installation/index.md) guide
22
18
* full file system and command line access
23
19
24
-
`<shopware project root>/custom/plugins` contains all plugins from the Shopware store. You install and manage these plugins via the Shopware Administration.
25
-
26
20
## 1. Choose a name
27
21
28
22
Use **UpperCamelCase**, which means that your plugin name must begin with a capital letter too. Whenever possible, begin it with a company prefix to avoid duplicate names (e.g., `SwagBasicExample`). Choose a name that describes your plugin as succinctly and clearly as possible.
@@ -33,6 +27,8 @@ A vendor prefix is required if you plan to publish your plugin in the [Shopware
33
27
34
28
## 2. Generate the plugin structure
35
29
30
+
Plugins are located in `<shopware project root>/custom/plugins` and managed via the Shopware Administration.
31
+
36
32
From your Shopware project's root directory, run:
37
33
38
34
```bash
@@ -93,7 +89,7 @@ This file contains basic metadata that Shopware needs to know about your plugin,
93
89
* The technical name
94
90
* The description
95
91
* The author
96
-
* The used license
92
+
* The license
97
93
* The current plugin version
98
94
* The required dependencies
99
95
* and other configuration details.
@@ -157,7 +153,7 @@ Here's an example `composer.json` you can refer to:
157
153
If you change the `autoload.psr-4` path (for example, not using `src/`), adjust your directory structure accordingly.
158
154
:::
159
155
160
-
::: Info
156
+
::: info
161
157
Set up [CI](../../development/testing/ci.md) early. Run static analysis, tests, and `shopware-cli extension build` in CI so your plugin ZIP is reproducible and safe to promote across environments.
Authentication via API token is required. Refer to ["Using Composer for plugin installation in Shopware"](https://www.shopware.com/en/news/using-composer-for-plugin-installation-in-shopware/) for detailed information.
173
169
174
-
###Manual creation (optional)
170
+
## Manual creation (optional)
175
171
176
172
In most cases, you should use `bin/console plugin:create`. Manual creation is only useful if you need full control over the structure or are working in a custom setup.
177
173
@@ -190,7 +186,7 @@ SwagBasicExample/
190
186
└── SwagBasicExample.php
191
187
```
192
188
193
-
***namespace**: here, it's `Swag\BasicExample`. We recommend using a combination of your manufacturer prefix and the technical name to name it.
189
+
***Namespace**: here, it's `Swag\BasicExample`. We recommend using a combination of your manufacturer prefix and the technical name to name it.
194
190
***`src/` directory**: recommended but not strictly required.
195
191
***PHP class**: `SwagBasicExample.php`, which you name after your plugin.
196
192
@@ -209,12 +205,6 @@ class SwagBasicExample extends Plugin
209
205
}
210
206
```
211
207
212
-
::: warning
213
-
If you change the `autoload.psr-4` path (for example, not using `src/`), your directory structure must match that configuration.
214
-
:::
215
-
216
-
And that's it. The basic structure and all necessary files for your plugin to be installable are done.
217
-
218
208
## Next steps
219
209
220
210
[Install and activate](./install-activate-plugin.md) your plugin.
Copy file name to clipboardExpand all lines: guides/plugins/plugins/database/custom-fields-of-type-media.md
+5-7Lines changed: 5 additions & 7 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -6,11 +6,9 @@ nav:
6
6
7
7
# Using Custom Fields of Type Media
8
8
9
-
## Overview
10
-
11
9
After adding a custom field of type media in the Administration or via a plugin, you can assign media objects to different entities.
12
10
This is often used on products to add additional images to the product detail page.
13
-
If you want to learn more about custom fields, take a look at[Adding custom fields](../framework/custom-field/add-custom-field.md).
11
+
For more on custom fields, see[Adding custom fields](../framework/custom-field/add-custom-field.md).
14
12
15
13
## Resolve media custom fields in Twig
16
14
@@ -21,10 +19,10 @@ In the product detail page template, `page.product.translated.customFields.xxx`
21
19
public function searchMedia(array $ids, Context $context): MediaCollection { ... }
22
20
```
23
21
24
-
This function resolves the corresponding media entities for the given IDs. Here is an example with a custom field \(`custom_sports_media_id`\) on the product detail page:
22
+
This function resolves the corresponding media entities for the given IDs. Here is an example with a custom field (`custom_sports_media_id`) on the product detail page:
Copy file name to clipboardExpand all lines: guides/plugins/plugins/database/database-migrations.md
+8-12Lines changed: 8 additions & 12 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -7,10 +7,6 @@ nav:
7
7
8
8
# Database Migrations
9
9
10
-
## Overview
11
-
12
-
This guide covers what migrations are and how to use them.
13
-
14
10
Migrations are PHP classes used to manage incremental and reversible database schema changes. Shopware comes with a pre-built Migration System, to take away most of the work for you. Throughout this guide, you will find the `$` symbol representing your command line.
15
11
16
12
## Prerequisites
@@ -34,7 +30,7 @@ By default, Shopware 6 is looking for migration files in a directory called `Mig
34
30
└── SwagBasicExample.php
35
31
```
36
32
37
-
As you can see there is one file in the `<plugin root>/src/Migration` directory. Below you find a break down of what each part of its name means.
33
+
As you can see there is one file in the `<plugin root>/src/Migration` directory. Below you'll find a breakdown of what each part of its name means.
@@ -106,11 +102,11 @@ class Migration1611740369ExampleDescription extends MigrationStep
106
102
107
103
As you can see, your migration contains three methods:
108
104
109
-
* getCreationTimestamp\(\)
110
-
* update\(\)
111
-
* updateDestructive\(\)
105
+
*`getCreationTimestamp()`
106
+
*`update()`
107
+
*`updateDestructive()`
112
108
113
-
There is no need to change `getCreationTimestamp()`, it returns the timestamp that's also part of the file name. In the `update()` method you implement non-destructive changes which should always be **reversible**. The `updateDestructive()` method is the follow up step, that is run after `update()` and used for **destructive none reversible changes**, like dropping columns or tables. Destructive migrations are only executed explicitly.
109
+
There is no need to change `getCreationTimestamp()`, it returns the timestamp that's also part of the file name. In the `update()` method you implement non-destructive changes which should always be **reversible**. The `updateDestructive()` method is the follow up step, that is run after `update()` and used for **destructive non-reversible changes**, like dropping columns or tables. Destructive migrations are only executed explicitly.
114
110
115
111
::: info
116
112
You do not add instructions to revert your migrations within the migration class itself. `updateDestructive` is not meant to revert instructions in `update`. Reverting changes in the database is done explicitly in plugin lifecycle method `uninstall`, as explained in the [Plugin Lifecycle guide](../plugin-fundamentals/plugin-lifecycle.md#uninstall).
@@ -169,7 +165,7 @@ This command will generate a new migration file including the `CREATE TABLE` or
Once you have become familiar with the migration process and the development flow, you may want to have finer control over the migrations performed during the installation and update. In this case the `MigrationCollection` which is only filled with your specific migrations, can be accessed via the `InstallContext` and all its subclasses \(UpdateContext, ActivateContext, ...\). A plugin must reject the automatic execution of migrations in order to have control over the migrations that are executed.
193
+
Once you have become familiar with the migration process and the development flow, you may want to have finer control over the migrations performed during the installation and update. In this case the `MigrationCollection` which is only filled with your specific migrations, can be accessed via the `InstallContext` and all its subclasses (UpdateContext, ActivateContext, ...). A plugin must reject the automatic execution of migrations in order to have control over the migrations that are executed.
198
194
199
195
Therefore, a typical update method might look more like this:
200
196
@@ -213,4 +209,4 @@ Therefore, a typical update method might look more like this:
213
209
}
214
210
```
215
211
216
-
If you don't use the Shopware migration system, an empty collection \(NullObject\) will be in the context.
212
+
If you don't use the Shopware migration system, an empty collection (`NullObject`) will be in the context.
Copy file name to clipboardExpand all lines: guides/plugins/plugins/in-app-purchases.md
+8-6Lines changed: 8 additions & 6 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -8,7 +8,7 @@ nav:
8
8
# In-App Purchases
9
9
10
10
::: info
11
-
In-App Purchase is available since Shopware version 6.6.9.0
11
+
In-App Purchases are available since Shopware version 6.6.9.0
12
12
:::
13
13
14
14
In-App Purchases are a way to lock certain features behind a paywall within the same extension.
@@ -20,9 +20,9 @@ and then offer a paid version with more features.
20
20
21
21
## Allow users to buy an In-App Purchase
22
22
23
-
In order to enable others to purchase your In-App Purchase, you must request a checkout for it via the `inAppPurchaseCheckout` store in the administration.
23
+
In order to enable others to purchase your In-App Purchase, you must request a checkout for it via the `inAppPurchaseCheckout` store in the Administration.
24
24
The checkout process itself is provided by Shopware.
25
-
As this is purely functional, it is your responsibility to provide a button and hide it if the IAP cannot be purchased more than once.
25
+
It is your responsibility to provide a button and hide it if the IAP cannot be purchased more than once.
26
26
27
27
```ts
28
28
{
@@ -69,13 +69,15 @@ class Example
69
69
If you want to check an in-app purchase in the administration:
70
70
71
71
```js
72
-
if (Shopware.InAppPurchase.isActive('MyExtensionName', 'my-iap-identifier')) {};
72
+
if (Shopware.InAppPurchase.isActive('MyExtensionName', 'my-iap-identifier')) {
73
+
// ...
74
+
}
73
75
```
74
76
75
-
## Event
77
+
## Listen to In-App Purchase events
76
78
77
79
Apps are also able to manipulate the available In-App Purchases as described in
Copy file name to clipboardExpand all lines: guides/plugins/plugins/index.md
+3-3Lines changed: 3 additions & 3 deletions
Display the source diff
Display the rich diff
Original file line number
Diff line number
Diff line change
@@ -20,7 +20,7 @@ Plugins run directly inside the Shopware environment and provide full access to:
20
20
21
21
Technically, plugins are extensions of [Symfony bundles](./bundle.md). They follow a defined directory structure and, when used as managed extensions, provide a lifecycle (install, update, deactivate, uninstall).
22
22
23
-
Plugins can ship their own assets, controllers, services, and tests, enabling deep platform and full extensibility across core and custom functionality.
23
+
Plugins can ship their own assets, controllers, services, and tests, enabling deep extensibility across core and custom functionality.
24
24
25
25
## When to create and use a plugin
26
26
@@ -99,7 +99,7 @@ Managed plugins are commonly used for marketplace-distributed extensions. They a
99
99
100
100
### Bundles
101
101
102
-
Symfony-based [bundles](../plugins/bundle.md) are installed via Composer. They do not have a Shopware plugin lifecycle and are not managed via the Administration.
102
+
Symfony-based [bundles](./bundle.md) are installed via Composer. They do not have a Shopware plugin lifecycle and are not managed via the Administration.
103
103
104
104
Bundles are useful when you want:
105
105
@@ -119,7 +119,7 @@ For custom projects, it is often preferable to:
119
119
* Share one CI pipeline and one set of static analysis rules
120
120
* Organize functionality through clean internal directory structure
121
121
122
-
It does not matter whether static plugins or Symfony bundles internally are used, as much as having:
122
+
It does not matter whether static plugins or Symfony bundles are used internally, as much as having:
0 commit comments