Diese mächtigen Werkzeuge verwandeln deine Shopware 6 static plugins in flexible Lösungen, die sich an jeden Shop anpassen lassen. Gleichzeitig sparst du dir unzählige Stunden Entwicklungszeit und machst deine Plugins für eine breitere Zielgruppe interessant.
Stell dir vor, du entwickelst ein Newsletter-Plugin für Shopware. Ohne Konfigurationsmöglichkeiten müsstest du bei jeder Anpassung den Code ändern – API-Schlüssel anpassen, Versandzeiten modifizieren oder Design-Elemente austauschen. Das bedeutet bei jedem Kundenwunsch neuen Aufwand, Updates werden kompliziert und die Wartung zum Alptraum.
Mit durchdachten Plugin-Konfigurationen löst du all diese Probleme auf einen Schlag. Shop-Betreiber können ihre Einstellungen selbstständig über die Administration anpassen, ohne dass du als Entwickler eingreifen musst. Das Ergebnis: Zufriedenere Kunden und weniger Support-Anfragen für dich.
Plugin-Konfigurationen bieten dir als Entwickler mehrere entscheidende Vorteile. Erstens reduzieren sie den Wartungsaufwand erheblich, da Shop-Betreiber ihre Einstellungen selbst verwalten können. Zweitens machst du deine Plugins flexibler und damit für einen größeren Markt interessant. Drittens sparst du Zeit bei der Entwicklung kundenspezifischer Lösungen.
Für Shop-Betreiber bedeuten gut strukturierte Konfigurationen mehr Kontrolle über ihr System. Sie können Features aktivieren oder deaktivieren, Texte anpassen und technische Parameter einstellen – alles über die vertraute Shopware-Administration.
Die Basis jeder Plugin-Konfiguration ist eine XML-Datei namens `config.xml`, die du im Verzeichnis `src/Resources/config/` deines Plugins platzierst. Diese Shopware 6 config file definiert alle verfügbaren Einstellungsoptionen und wird automatisch von Shopware in der Administration gerendert.
Eine minimale Shopware config xml sieht folgendermaßen aus:
<?xml version="1.0" encoding="UTF-8"?>
<config xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:noNamespaceSchemaLocation="https://raw.githubusercontent.com/shopware/shopware/trunk/src/Core/System/SystemConfig/Schema/config.xsd">
<card>
<title>Grundeinstellungen</title>
<input-field>
<name>apiKey</name>
<label>API-Schlüssel</label>
<helpText>Trage hier deinen API-Schlüssel ein</helpText>
</input-field>
</card>
</config>
Das `card`-Element gruppiert zusammengehörige Einstellungen visuell. Innerhalb einer Karte definierst du verschiedene `input-field`-Elemente für deine Konfigurationsoptionen. Jedes Feld benötigt mindestens einen eindeutigen `name`, der später als technischer Bezeichner dient.
Shopware bietet dir eine Vielzahl von Feldtypen für verschiedene Anwendungszwecke:
Textfelder eignen sich für einfache Texteingaben wie API-URLs oder Benutzernamen. Du kannst sie mit zusätzlichen Attributen wie `copyable="true"` ausstatten, um eine Kopieren-Schaltfläche hinzuzufügen.
Passwort-Felder maskieren sensible Daten wie API-Schlüssel. Mit `minLength` und `maxLength` definierst du Längenbeschränkungen:
<input-field type="password">
<name>secretToken</name>
<label>Geheimer Token</label>
<minLength>8</minLength>
<maxLength>64</maxLength>
</input-field>
Auswahlfelder ermöglichen die Auswahl aus vordefinierten Optionen. Bei `single-select` kann nur eine Option gewählt werden, während `multi-select` mehrere Auswahlmöglichkeiten zulässt:
<input-field type="single-select">
<name>mailMethod</name>
<label>Versandmethode</label>
<options>
<option>
<id>smtp</id>
<name>SMTP-Versand</name>
</option>
<option>
<id>sendmail</id>
<name>Sendmail</name>
</option>
</options>
<defaultValue>smtp</defaultValue>
</input-field>
Für komplexere Konfigurationen kannst du spezielle Admin-Komponenten einbinden. Die `sw-entity-single-select`-Komponente ermöglicht beispielsweise die Auswahl von Shopware-Entitäten wie Produkten oder Kategorien:
<component name="sw-entity-single-select">
<name>defaultProduct</name>
<entity>product</entity>
<label>Standardprodukt auswählen</label>
</component>
Mit `sw-media-field` integrierst du eine Medienauswahl, während `sw-text-editor` einen WYSIWYG-Editor für formatierten Text bereitstellt.
| Komponente | Verwendungszweck | Besonderheiten |
|---|---|---|
| sw-entity-single-select | Auswahl einer Shopware-Entität | Vollständige Integration in DAL |
| sw-entity-multi-id-select | Auswahl mehrerer Entitäts-IDs | Speichert Array von IDs |
| sw-media-field | Medienauswahl oder -upload | Direkte Anbindung an Media Manager |
| sw-text-editor | Formatierte Texteingabe | WYSIWYG-Editor mit Rich-Text |
Nachdem du deine Konfigurationsmöglichkeiten definiert hast, möchtest du diese Werte natürlich in deinem Plugin-Code verwenden. Shopware stellt dir dafür den `SystemConfigService` zur Verfügung, der alle Konfigurationswerte verwaltet.
Zunächst musst du den Service in deiner `services.xml` als Abhängigkeit definieren:
<services>
<service id="MeinPlugin\Service\ConfigService">
<argument type="service" id="Shopware\Core\System\SystemConfig\SystemConfigService"/>
</service>
</services>
In deiner Service-Klasse injizierst du dann den `SystemConfigService`:
<?php declare(strict_types=1);
namespace MeinPlugin\Service;
use Shopware\Core\System\SystemConfig\SystemConfigService;
class ConfigService
{
private SystemConfigService $systemConfigService;
public function __construct(SystemConfigService $systemConfigService)
{
$this->systemConfigService = $systemConfigService;
}
public function getApiKey(?string $salesChannelId = null): ?string
{
return $this->systemConfigService->get('MeinPlugin.config.apiKey', $salesChannelId);
}
}
Besonders wichtig ist das korrekte Namensschema beim Abrufen der Konfigurationswerte. Shopware verwendet das Format `PluginName.config.feldname`. Das verhindert Konflikte zwischen verschiedenen Plugins und stellt sicher, dass du immer die richtigen Werte erhältst.
Wenn du beispielsweise in deiner Shopware plugin xml ein Feld mit dem Namen `apiKey` definiert hast und dein Plugin `MeinPlugin` heißt, rufst du den Wert mit `MeinPlugin.config.apiKey` ab.
Ein besonders mächtiges Feature sind Sales Channel-spezifische Konfigurationen. Du kannst für jeden Verkaufskanal unterschiedliche Einstellungen vornehmen, indem du die Sales Channel-ID als zweiten Parameter übergibst:
// Globale Konfiguration (für alle Sales Channels)
$globalApiKey = $this->systemConfigService->get('MeinPlugin.config.apiKey');
// Sales Channel-spezifische Konfiguration
$channelSpecificKey = $this->systemConfigService->get('MeinPlugin.config.apiKey', $salesChannelId);
Falls für einen Sales Channel keine spezifische Konfiguration existiert, wird automatisch auf die globale Einstellung zurückgegriffen.
Je nach Anwendungsfall benötigst du deine Plugin-Konfigurationen in unterschiedlichen Bereichen deines Plugins. Hier erfährst du, wie du sie in den wichtigsten Kontexten verwendest. In Shopware plugin config in controller-Szenarien ist die korrekte Implementation besonders wichtig.
Event Subscriber sind ideal, um auf bestimmte Shop-Ereignisse zu reagieren und dabei deine Shopware config-Einstellungen zu berücksichtigen:
<?php declare(strict_types=1);
namespace MeinPlugin\Subscriber;
use Shopware\Core\Checkout\Cart\Event\BeforeLineItemAddedEvent;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
class CartSubscriber implements EventSubscriberInterface
{
private SystemConfigService $configService;
public function __construct(SystemConfigService $configService)
{
$this->configService = $configService;
}
public static function getSubscribedEvents(): array
{
return [
BeforeLineItemAddedEvent::class => 'onBeforeLineItemAdded'
];
}
public function onBeforeLineItemAdded(BeforeLineItemAddedEvent $event): void
{
$maxQuantity = $this->configService->get(
'MeinPlugin.config.maxQuantity',
$event->getCart()->getToken()
);
if ($maxQuantity && $event->getLineItem()->getQuantity() > $maxQuantity) {
// Implementiere deine Logik hier
}
}
}
In Storefront- oder API-Controllern kannst du mit Shopware get plugin config-Funktionalitäten das Verhalten deiner Endpunkte anpassen:
<?php declare(strict_types=1);
namespace MeinPlugin\Storefront\Controller;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Shopware\Storefront\Controller\StorefrontController;
use Symfony\Component\HttpFoundation\Response;
use Symfony\Component\Routing\Annotation\Route;
/**
* @Route(defaults={"_routeScope"={"storefront"}})
*/
class CustomController extends StorefrontController
{
private SystemConfigService $configService;
public function __construct(SystemConfigService $configService)
{
$this->configService = $configService;
}
/**
* @Route("/custom-endpoint", name="frontend.custom.endpoint", methods={"GET"})
*/
public function customEndpoint(): Response
{
$isFeatureEnabled = $this->configService->get('MeinPlugin.config.enableFeature');
if (!$isFeatureEnabled) {
throw $this->createNotFoundException();
}
return $this->renderStorefront('@MeinPlugin/storefront/custom.html.twig');
}
}
Auch im Frontend kannst du auf deine Plugin-Konfigurationen zugreifen. In Twig-Templates verwendest du die `config()`-Funktion:
Für JavaScript-Anwendungen kannst du Konfigurationswerte über Twig in deinen Code einbetten:
<script>
window.pluginConfig = {
apiUrl: '',
timeout:
};
</script>
Robuste Plugin-Konfigurationen benötigen durchdachte Validierung und Fehlerbehandlung. Shopware bietet dir mehrere Mechanismen, um die Eingaben der Nutzer zu überprüfen.
Die erste Verteidigungslinie bildet die XML-Konfiguration selbst. Mit Attributen wie `required`, `minLength`, `maxLength`, `min` und `max` definierst du grundlegende Validierungsregeln:
<input-field type="url">
<name>webhookUrl</name>
<label>Webhook-URL</label>
<required>true</required>
<helpText>Diese URL muss mit https:// beginnen</helpText>
</input-field>
<input-field type="int">
<name>retryCount</name>
<label>Anzahl Wiederholungen</label>
<min>1</min>
<max>10</max>
<defaultValue>3</defaultValue>
</input-field>
Für komplexere Validierungslogik erstellst du eigene Validierungsmethoden in deinen Service-Klassen:
<?php declare(strict_types=1);
namespace MeinPlugin\Service;
use Shopware\Core\System\SystemConfig\SystemConfigService;
class ValidationService
{
private SystemConfigService $configService;
public function validateApiCredentials(?string $salesChannelId = null): array
{
$errors = [];
$apiKey = $this->configService->get('MeinPlugin.config.apiKey', $salesChannelId);
$apiSecret = $this->configService->get('MeinPlugin.config.apiSecret', $salesChannelId);
if (empty($apiKey)) {
$errors[] = 'API-Schlüssel ist erforderlich';
} elseif (strlen($apiKey) < 32) {
$errors[] = 'API-Schlüssel muss mindestens 32 Zeichen lang sein';
}
if (empty($apiSecret)) {
$errors[] = 'API-Secret ist erforderlich';
}
// Teste die Verbindung zur API
if (empty($errors) && !$this->testApiConnection($apiKey, $apiSecret)) {
$errors[] = 'Verbindung zur API fehlgeschlagen. Überprüfe deine Zugangsdaten.';
}
return $errors;
}
private function testApiConnection(string $apiKey, string $apiSecret): bool
{
// Implementiere hier deinen API-Test
return true;
}
}
Sorge immer für sinnvolle Fallback-Werte, falls Konfigurationsoptionen leer oder ungültig sind:
public function getConfigWithFallback(string $key, $default, ?string $salesChannelId = null)
{
$value = $this->configService->get("MeinPlugin.config.{$key}", $salesChannelId);
return $value ?? $default;
}
public function getTimeout(?string $salesChannelId = null): int
{
$timeout = $this->getConfigWithFallback('timeout', 30, $salesChannelId);
// Stelle sicher, dass der Timeout in vernünftigen Grenzen liegt
return max(5, min(300, (int)$timeout));
}
Professionelle Plugins unterstützen mehrere Sprachen – das gilt auch für die Konfigurationsoberfläche. Shopware macht es dir einfach, mehrsprachige Plugin-Konfigurationen zu erstellen.
In deiner Shopware 6 config kannst du für jedes Element mehrsprachige Labels definieren:
<input-field>
<name>emailTemplate</name>
<label>E-Mail Template</label>
<label lang="de-DE">E-Mail-Vorlage</label>
<label lang="fr-FR">Modèle d'e-mail</label>
<helpText>Select the email template for notifications</helpText>
<helpText lang="de-DE">Wähle die E-Mail-Vorlage für Benachrichtigungen</helpText>
<helpText lang="fr-FR">Sélectionnez le modèle d'e-mail pour les notifications</helpText>
</input-field>
Das `lang`-Attribut verwendet die standard Shopware-Locale-Codes. Ohne Angabe wird automatisch `en-GB` als Standardsprache verwendet.
Auch die Optionen in Select-Feldern lassen sich mehrsprachig gestalten:
<input-field type="single-select">
<name>orderStatus</name>
<label>Order Status</label>
<label lang="de-DE">Bestellstatus</label>
<options>
<option>
<id>pending</id>
<name>Pending</name>
<name lang="de-DE">Ausstehend</name>
<name lang="fr-FR">En attente</name>
</option>
<option>
<id>completed</id>
<name>Completed</name>
<name lang="de-DE">Abgeschlossen</name>
<name lang="fr-FR">Terminé</name>
</option>
</options>
</input-field>
Strukturiere deine Übersetzungen konsistent und verwende präzise, verständliche Begriffe. Halte Labels kurz und aussagekräftig, während Hilfstexte ausführlichere Erklärungen bieten können.
Berücksichtige auch kulturelle Unterschiede: Datums- und Uhrzeitformate, Währungen oder regionale Besonderheiten sollten in deinen Konfigurationsoptionen Beachtung finden.
Plugin-Konfigurationen werden häufig abgerufen, daher ist Performance ein wichtiger Aspekt. Shopware bietet dir verschiedene Möglichkeiten zur Optimierung.
Erstelle einen Service, der häufig verwendete Konfigurationswerte zwischenspeichert:
<?php declare(strict_types=1);
namespace MeinPlugin\Service;
use Shopware\Core\System\SystemConfig\SystemConfigService;
use Psr\Cache\CacheItemPoolInterface;
class CachedConfigService
{
private SystemConfigService $configService;
private CacheItemPoolInterface $cache;
private array $runtimeCache = [];
public function __construct(
SystemConfigService $configService,
CacheItemPoolInterface $cache
) {
$this->configService = $configService;
$this->cache = $cache;
}
public function get(string $key, ?string $salesChannelId = null): mixed
{
$cacheKey = "plugin_config_{$key}_{$salesChannelId}";
// Runtime-Cache prüfen
if (isset($this->runtimeCache[$cacheKey])) {
return $this->runtimeCache[$cacheKey];
}
// Persistenten Cache prüfen
$cacheItem = $this->cache->getItem($cacheKey);
if ($cacheItem->isHit()) {
$this->runtimeCache[$cacheKey] = $cacheItem->get();
return $this->runtimeCache[$cacheKey];
}
// Wert aus SystemConfig laden
$value = $this->configService->get($key, $salesChannelId);
// In beiden Caches speichern
$cacheItem->set($value);
$cacheItem->expiresAfter(3600); // 1 Stunde
$this->cache->save($cacheItem);
$this->runtimeCache[$cacheKey] = $value;
return $value;
}
}
Wenn du mehrere Konfigurationswerte gleichzeitig benötigst, lade sie in einer Operation:
public function getMultipleConfigs(array $keys, ?string $salesChannelId = null): array
{
$configs = [];
$pluginPrefix = 'MeinPlugin.config.';
foreach ($keys as $key) {
$configs[$key] = $this->configService->get($pluginPrefix . $key, $salesChannelId);
}
return $configs;
}
Lade Konfigurationswerte erst dann, wenn sie tatsächlich benötigt werden:
class LazyConfigService
{
private ?array $configCache = null;
private function loadConfigs(?string $salesChannelId = null): void
{
if ($this->configCache !== null) {
return;
}
$this->configCache = [
'apiKey' => $this->configService->get('MeinPlugin.config.apiKey', $salesChannelId),
'timeout' => $this->configService->get('MeinPlugin.config.timeout', $salesChannelId),
// Weitere Konfigurationen...
];
}
public function getApiKey(?string $salesChannelId = null): ?string
{
$this->loadConfigs($salesChannelId);
return $this->configCache['apiKey'];
}
}
Auch bei sorgfältiger Entwicklung können bei Plugin-Konfigurationen Probleme auftreten. Die Shopware plugin structure und die korrekte Einrichtung des Shopware plugin folder sind dabei essentiell. Hier sind die häufigsten Fehlerquellen und ihre Lösungen.
Problem: Konfigurationswerte werden nicht gespeichert
Lösung: Überprüfe die XML-Struktur und stelle sicher, dass alle `name`-Elemente eindeutig und valide sind. Der Name darf nur Buchstaben und Zahlen enthalten und muss mindestens 4 Zeichen lang sein.
Problem: Plugin-Konfiguration wird nicht in der Administration angezeigt
Lösung: Kontrolliere den Shopware get plugin path zur `config.xml` (muss in `src/Resources/config/` liegen) und validiere die XML-Syntax. Lösche den Cache und installiere das Plugin neu.
Problem: Konfigurationswerte sind immer `null`
Lösung: Verwende das korrekte Namensschema `PluginName.config.feldname` und stelle sicher, dass der Plugin-Name exakt dem Ordnernamen entspricht.
Erstelle einen Debug-Service, der dir beim Troubleshooting hilft:
<?php declare(strict_types=1);
namespace MeinPlugin\Service;
use Shopware\Core\System\SystemConfig\SystemConfigService;
class ConfigDebugService
{
private SystemConfigService $configService;
public function __construct(SystemConfigService $configService)
{
$this->configService = $configService;
}
public function debugConfig(?string $salesChannelId = null): array
{
$pluginPrefix = 'MeinPlugin.config.';
$allConfigs = [];
// Alle verfügbaren Konfigurationen laden
$configs = $this->configService->all($salesChannelId);
foreach ($configs as $key => $value) {
if (str_starts_with($key, $pluginPrefix)) {
$allConfigs[$key] = [
'value' => $value,
'type' => gettype($value),
'isEmpty' => empty($value)
];
}
}
return $allConfigs;
}
}
Für anspruchsvolle Anwendungsfälle bietet Shopware erweiterte Konfigurationsmöglichkeiten, die über einfache Eingabefelder hinausgehen.
Manchmal sollen bestimmte Konfigurationsfelder nur dann angezeigt werden, wenn andere Optionen aktiviert sind. Dies erreichst du durch geschickte Verwendung mehrerer Konfigurationskarten:
<card>
<title>E-Mail Einstellungen</title>
<input-field type="bool">
<name>enableEmailNotifications</name>
<label>E-Mail-Benachrichtigungen aktivieren</label>
</input-field>
</card>
<card>
<title>E-Mail Konfiguration</title>
<input-field>
<name>senderEmail</name>
<label>Absender E-Mail</label>
<helpText>Wird nur verwendet, wenn E-Mail-Benachrichtigungen aktiv sind</helpText>
</input-field>
<input-field>
<name>emailTemplate</name>
<label>E-Mail Template</label>
</input-field>
</card>
Für komplexe Konfigurationen kannst du JSON-Strukturen in Textfeldern verwenden und diese in deinem Service verarbeiten. Eine alternative Lösung für erweiterte Funktionalitäten kann auch die Verwendung der Shopware database config und Shopware 6 database config file sein:
public function getAdvancedConfig(?string $salesChannelId = null): array
{
$jsonConfig = $this->configService->get('MeinPlugin.config.advancedSettings', $salesChannelId);
if (empty($jsonConfig)) {
return $this->getDefaultAdvancedConfig();
}
$config = json_decode($jsonConfig, true);
if (json_last_error() !== JSON_ERROR_NONE) {
// Fallback bei JSON-Fehlern
return $this->getDefaultAdvancedConfig();
}
return array_merge($this->getDefaultAdvancedConfig(), $config);
}
private function getDefaultAdvancedConfig(): array
{
return [
'retrySettings' => [
'maxRetries' => 3,
'backoffMultiplier' => 2,
'maxBackoffSeconds' => 300
],
'features' => [
'enableLogging' => true,
'enableMetrics' => false
]
];
}
Bei der Arbeit mit komplexeren Konfigurationen ist es wichtig, die Shopware 6 database config-Konzepte zu verstehen und auch Legacy-Kompatibilität zu Shopware 5 plugin config-Systemen zu berücksichtigen, falls du Migrationen unterstützen musst.
Mit durchdachten Plugin-Konfigurationen schaffst du die Basis für skalierbare, wartbare und benutzerfreundliche Shopware-Erweiterungen. Du sparst dir Zeit bei Support-Anfragen, machst deine Plugins für einen breiteren Markt interessant und bietest Shop-Betreibern die Flexibilität, die sie benötigen.
Die Kombination aus XML-Konfiguration, PHP-Services und Frontend-Integration ermöglicht es dir, auch komplexe Anforderungen elegant zu lösen. Mit den gezeigten Techniken für Validierung, Caching und Debugging bist du für alle Herausforderungen gewappnet.
Deine Plugin-Konfigurationen werden zu einem mächtigen Werkzeug, das deine Entwicklungsarbeit professionalisiert und gleichzeitig die Anwenderfreundlichkeit deiner Shopware-Plugins auf ein neues Level hebt. Der Aufwand für die initiale Einrichtung zahlt sich schnell durch reduzierte Wartungskosten und zufriedenere Kunden aus.