When writing object oriented code, you will usually need small, reusable services that encapsulate certain parts of your business logic. This tutorial will cover the creation of services and how to use them together with Shopware's DI container.
Ideally a service is just a simple PHP class with only one responsibility:
<?php
namespace SwagServicePlugin\Components;
class TaxCalculator
{
public function calculate($netPrice, $tax)
{
return $netPrice * $tax;
}
}
Instead of creating the TaxCalculator
class everywhere you need it, you can make it available with the DI container.
This way the same instance of this class can be accessed everywhere in Shopware - even by other plugins.
To register a service, you can add it to your plugins services.xml
like this:
<?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_service_plugin.tax_calculator" class="SwagServicePlugin\Components\TaxCalculator" />
</services>
</container>
The new TaxCalculator
can now be requested from e.g. a controller using the Shopware DI container:
$this->container->get('swag_service_plugin.tax_calculator');
Keep in mind that any subsequent calls will return the same instance of the object - the container will keep a reference to the object you returned the first time and will not call your event callback another time. If you need to return new instances every time the service is requested, a factory pattern might be helpful.
In many cases, your services might depend on other services. Usually you will inject those using constructor injection:
<?php
namespace SwagServicePlugin\Components;
use Shopware\Components\Logger;
class TaxCalculator
{
/**
* @var $logger Logger
*/
private $logger;
/**
* @param $logger Logger
*/
public function __construct(Logger $logger)
{
$this->logger = $logger;
}
/**
* @param $netPrice float
* @param $tax float
* @return float
*/
public function calculate($netPrice, $tax)
{
$this->logger->debug('Calculating price for tax: ' . $tax);
return $netPrice * $tax;
}
}
<?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_service_plugin.tax_calculator" class="SwagServicePlugin\Components\TaxCalculator">
<argument type="service" id="corelogger"/>
</service>
</services>
</container>
A simple example plugin can be found here