Skip to content

Use Plugin Configuration

Use Plugin Configuration

In our guide on how to add a plugin configuration, you can learn how to provide this possibility to use configuration options in your plugins. This guide will aid you on how to then use this configuration in your plugin.

Prerequisites

In order to add a plugin configuration, you sure need to provide your plugin first. However, you won't learn to create a plugin in this guide. Head over to our plugin base guide to create your plugin first. It is also recommended to know how to setup a plugin configuration in the first instance. In this example, the configurations will be read inside of a subscriber, so knowing the Listening to events guide will also be helpful.

Overview

The plugin in this example already knows a subscriber, which listens to the product.loaded event and therefore will be called every time a product is loaded.

php
// <plugin root>/src/Subscriber/MySubscriber.php
<?php declare(strict_types=1);

namespace Swag\BasicExample\Subscriber;

use Shopware\Core\Framework\DataAbstractionLayer\Event\EntityLoadedEvent;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Shopware\Core\Content\Product\ProductEvents;

class MySubscriber implements EventSubscriberInterface
{
    public static function getSubscribedEvents(): array
    {
        return [
            ProductEvents::PRODUCT_LOADED_EVENT => 'onProductsLoaded'
        ];
    }

    public function onProductsLoaded(EntityLoadedEvent $event): void
    {
        // Do stuff with the product
    }
}

For this guide, a very small plugin configuration file is available as well:

xml
// <plugin root>/src/Resources/config/config.xml
<?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>Minimal configuration</title>
        <input-field>
            <name>example</name>
        </input-field>
    </card>
</config>

Just a simple input field with the technical name example. This will be necessary in the next step.

Reading the configuration

Let's get to the important part. Reading the plugin configuration is based on the Shopware\Core\System\SystemConfig\SystemConfigService. This service is responsible for reading all configs from Shopware 6, such as the plugin configurations.

Inject this service into your subscriber using the DI container.

xml
// <plugin root>/src/Resources/config/services.xml
<?xml version="1.0" ?>

<container xmlns="http://symfony.com/schema/dic/services"
           xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
           xsi:schemaLocation="http://symfony.com/schema/dic/services http://symfony.com/schema/dic/services/services-1.0.xsd">

    <services>
        <service id="Swag\BasicExample\Subscriber\MySubscriber">
            <argument type="service" id="Shopware\Core\System\SystemConfig\SystemConfigService" />
            <tag name="kernel.event_subscriber"/>
        </service>
    </services>
</container>

Note the new argument being provided to your subscriber. Now create a new field in your subscriber and pass in the SystemConfigService:

php
// <plugin root>/src/Subscriber/MySubscriber.php
<?php declare(strict_types=1);

namespace Swag\BasicExample\Subscriber;

...
use Shopware\Core\System\SystemConfig\SystemConfigService;

class MySubscriber implements EventSubscriberInterface
{
    private SystemConfigService $systemConfigService;

    public function __construct(SystemConfigService $systemConfigService)
    {
        $this->systemConfigService = $systemConfigService;
    }

    public static function getSubscribedEvents(): array
    {
        ...
    }
    ...
}

So far, so good. The SystemConfigService is now available in your subscriber.

This service comes with a get method to read the configurations. The first idea would be to simply call $this->systemConfigService->get('example') now, wouldn't it? Simply using the technical name you've previously set for the configuration.

But what would happen, if there were more plugins providing the same technical name for their very own configuration field? How would you access the proper field, how would you prevent plugin conflicts?

That's why the plugin configurations are always prefixed. By default, the pattern is the following: <BundleName>.config.<configName>. Thus, it would be SwagBasicExample.config.example here.

php
// <plugin root>/src/Subscriber/MySubscriber.php
<?php declare(strict_types=1);

namespace Swag\BasicExample\Subscriber;

...

class MySubscriber implements EventSubscriberInterface
{
    ...
    public function onProductsLoaded(EntityLoadedEvent $event): void
    {
        $exampleConfig = $this->systemConfigService->get('SwagBasicExample.config.example', $salesChannelId);
    }
}

INFO

Set the saleschannelId to null for the plugin configuration to be used by all Sales Channels else set to the corresponding Sales Channel ID.

Reading configuration in JavaScript

While the above examples show how to read plugin configuration in PHP, you might also need to access these values in JavaScript for Administration extensions or Storefront functionality.

Administration API access

To access your plugin's configuration from JavaScript in the Administration, you should use the systemConfigApiService which wraps the system-config endpoints.

Using injection in Vue components

javascript
// Example: Reading plugin configuration in Administration Vue component
export default Shopware.Component.wrapComponentConfig({
    inject: ['systemConfigApiService'],
    
    async created() {
        await this.loadPluginConfig();
    },
    
    methods: {
        async loadPluginConfig() {
            try {
                const config = await this.systemConfigApiService.getValues('SwagBasicExample.config');
                const exampleValue = config['SwagBasicExample.config.example'];
                
                console.log('Plugin configuration value:', exampleValue);
                return exampleValue;
            } catch (error) {
                console.error('Error fetching plugin configuration:', error);
            }
        }
    }
});

Using direct service access

javascript
// Example: Reading plugin configuration using direct service access
async function getPluginConfig() {
    try {
        const systemConfigApiService = Shopware.ApiService.getByName('systemConfigApiService');
        const config = await systemConfigApiService.getValues('SwagBasicExample.config');
        const exampleValue = config['SwagBasicExample.config.example'];
        
        console.log('Plugin configuration value:', exampleValue);
        return exampleValue;
    } catch (error) {
        console.error('Error fetching plugin configuration:', error);
    }
}

WARNING

Your plugin needs the system_config:read permission to access this API endpoint.

Storefront template access

In Storefront templates, you can use the config() twig function to access plugin configuration values directly without making API calls:

twig
{# Example: Reading plugin configuration in Storefront templates #}
{% set exampleValue = config('SwagBasicExample.config.example') %}

{% if exampleValue %}
    <div class="plugin-config-value">{{ exampleValue }}</div>
{% endif %}

Storefront JavaScript access

For Storefront JavaScript plugins, you can pass configuration values from Twig templates to your JavaScript code:

twig
{# In your Storefront template #}
<script>
    window.pluginConfig = {
        example: {{ config('SwagBasicExample.config.example')|json_encode|raw }}
    };
</script>
javascript
// In your Storefront JavaScript plugin
const { PluginBaseClass } = window;

export default class ExamplePlugin extends PluginBaseClass {
    init() {
        // Access the configuration value passed from Twig
        const exampleConfig = window.pluginConfig?.example;
        
        if (exampleConfig) {
            console.log('Plugin configuration:', exampleConfig);
            // Use the configuration value in your plugin logic
        }
    }
}