> For the complete documentation index, see [llms.txt](https://l-shop-en.gitbook.io/documentation/llms.txt). Markdown versions of documentation pages are available by appending `.md` to page URLs; this page is available as [Markdown](https://l-shop-en.gitbook.io/documentation/software-api/purchasing/change-in-the-method-of-delivery-of-products.md).

# Change in the method of delivery of products

## Introduction

For the delivery of products to the player in the L-Shop are responsible, so-called, Distributor. In fact, a distributor is a class that encapsulates the delivery product logic. Each such class must implement the `App\Services\Purchasing\Distributors\Distributor` interface.

## Steps

In order to implement a mechanism that is different from the standard, you need:

* Create a class and implements and interface `App\Services\Purchasing\Distributors\Distributor`.
* Write implementation for method `distribute()`. This method receives object of type`App\Entity\Distribution` which represents distribute entity.

{% code title="/app/Services/Purchasing/Distributors/CustomDistributor.php" %}

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

namespace App\Services\Purchasing\Distributors;

use App\Entity\Distribution;

class CustomDistributor implements Distributor
{
    /**
     * {@inheritdoc}
     */
    public function distribute(Distribution $distribution): void
    {
        // Логика выдачи товаров.
    }
}
```

{% endcode %}

* If your distributor implementation implies the possibility of manual delivery (an example of this is the built-in `App\Services\Purchasing\Distributors\RconDistributor`), the distributor class must also implement the `App\Services\Purchasing\Distributors\Attempting` interface, which does not have methods. The interface is a kind of marker.
* Register new distributor for activate it.
  * Go to file `/config/purchasing.php` .
  * Add fully qualified class name of the new distributor to the array element `distribution.distributors`.

{% code title="/config/purchasing.php" %}

```php
'distributors' => [
    // Builtin distributors...
    \App\Services\Purchasing\Distributors\ShoppingCartDistributor::class,
    \App\Services\Purchasing\Distributors\RconDistributor::class,
    
    // Custom distributors...
    \App\Services\Purchasing\Distributors\CustomDistributor::class
],
```

{% endcode %}

* Reset application cache to apply new configuration.

## Specification

{% hint style="info" %}
The key words "MUST", "MUST NOT", "REQUIRED", "SHALL", "NOT SHALL", "RECOMMENDED", "MAY" must be interpreted in the same way as described in [RFC 2119](http://www.ietf.org/rfc/rfc2119.txt).
{% endhint %}

* Distributor class *MUST* implements interface `App\Services\Purchasing\Distributors\Distributor`.
* Distributor class *MAY* implements interface `App\Services\Purchasing\Distributors\Attempting` in case if implementation of the distributor implies the possibility of manual delivery of products to the player.
* It is RECOMMENDED to add the suffix Distributor to the class name, so that the class of the distributor can be identified by name.
* It is RECOMMENDED to place distributors in the namespace `App\Services\Purchasing\Distributors`.
* The implementation of the `distribute()` method *MUST* contain the logic for delivering products to the player.
* In the event of an error that the distributor is unable to handle on its own, it is necessary to throw an exception of the type`App\Exceptions\Distributor\DistributionException`.
