Skip to content

Commit

Permalink
feat: plugin basis
Browse files Browse the repository at this point in the history
  • Loading branch information
lanfisis committed Jun 21, 2023
1 parent ae8b8be commit f778735
Show file tree
Hide file tree
Showing 2 changed files with 157 additions and 106 deletions.
115 changes: 9 additions & 106 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -16,13 +16,13 @@
[![Tests Status](https://img.shields.io/github/actions/workflow/status/monsieurbiz/SyliusOrderHistoryPlugin/tests.yml?branch=master&logo=github)](https://github.com/monsieurbiz/SyliusOrderHistoryPlugin/actions?query=workflow%3ATests)
[![Security Status](https://img.shields.io/github/actions/workflow/status/monsieurbiz/SyliusOrderHistoryPlugin/security.yml?branch=master&label=security&logo=github)](https://github.com/monsieurbiz/SyliusOrderHistoryPlugin/actions?query=workflow%3ASecurity)

This plugin saves order events and allows you to display them in the order history as a timeline.
This plugin saves order events and allows you to display them in the order history as a timeline. It based on state
machine events.

![Demo of the Order History](docs/images/demo.png)

## Installation


Install the plugin via composer:

```bash
Expand Down Expand Up @@ -50,113 +50,16 @@ Copy the plugin configuration files in your `config` folder:
cp -Rv vendor/monsieurbiz/sylius-order-history-plugin/recipes/1.0/config/ config
```

## Add custom events in code

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

namespace MonsieurBiz\SyliusOrderHistoryPlugin\EventListener;

use MonsieurBiz\SyliusOrderHistoryPlugin\Notifier\OrderHistoryNotifierInterface;
use Sylius\Bundle\ResourceBundle\Event\ResourceControllerEvent;
use App\Erp\ErpClient;

final class OrderEventListener
{
public function __construct(
private OrderHistoryNotifierInterface $notifier,
private ErpClient $erpClient,
){
}

public function onOrderItemAdded(ResourceControllerEvent $event): void
{
$order = $event->getSubject();
$erpOrderNumber = $this->erpClient->sendOrder($order);

# Use the event notifier with your own information
$this->notifier->notifyEvent($order, 'erp', 'send_order', [
'erp_order_number' => $erpOrderNumber,
]);
}
}
```

## Add custom event in state machine

There is two ways to add custom events in state machine.

### Use basic notifier with "on-the-fly" details

This is the easiest way to add custom events in state machine. You can use basic [expression language](https://symfony.com/doc/current/reference/formats/expression_language.html)
and have acces to two vars: `object` and `event`.

```yaml
winzou_state_machine:
sylius_order_checkout:
callbacks:
after:
app_order_history_notify_custom:
on: 'address'
do: [ '@MonsieurBiz\SyliusOrderHistoryPlugin\Notifier\OrderHistoryNotifier', 'notifyEvent' ]
args:
- 'object'
- '"my_type"'
- '"my_custom_event"'
- |
{
email: object.getCustomer().getEmail(),
amount: object.getTotal(),
}
```

### Using your own notifier

It would be useful to use your own notifier for more complex events and/or if you want to inject some services in your notifier.
Your notifier had to implements `OrderHistoryNotifierInterface`. Extends `AbstractOrderHistoryNotifier` is recommended to avoid boilerplate.

```php
<?php

declare(strict_types=1);

namespace App\Notifier;

use Sylius\Component\Core\Model\OrderInterface;

final class MyCustomNotifier extends AbstractOrderHistoryNotifier implements OrderHistoryNotifierInterface
{
public function notifyEvent(OrderInterface $order, string $type, string $label, array $details = []): void
{
$details['email'] = $order->getCustomer()?->getEmail();
$details['amount'] = $order->getCustomer()?->getEmail();
parent::notifyEvent($order, $type, $label, $details);
}
}
```

You can now use your own notifier in state machine.

```yaml
winzou_state_machine:
sylius_order_checkout:
callbacks:
after:
app_order_history_notify_custom:
on: 'address'
do: [ '@App\Notifier\MyCustomNotifier', 'notifyEvent' ]
args: [ 'object', '"my_type"', '"my_custom_event"' ]
```
## Getting started

### Add custom type and label display in history timeline
Show any order on the Sylius backend and click on the top right `History` button.

You could add dedicated label and title display in history timeline for your custom event type and event label. There's native builded
templates for common label `new`, `completed` or `cancelled` and default ones for unkwnon types and labels. But if you want to add your
own, you can do it by adding a new templates in the following paths:
## How to

* `templates/bundles/MonsieurBizSyliusOrderHistoryPlugin/Event/Type/{type}.html.twig`
* `templates/bundles/MonsieurBizSyliusOrderHistoryPlugin/Event/Label/{label}.html.twig`
* [Add more details on existing events](https://github.com/monsieurbiz/SyliusOrderHistoryPlugin/blob/master/docs/HOW-TO.md#add-more-details-on-existing-events)
* [Add custom events in code](https://github.com/monsieurbiz/SyliusOrderHistoryPlugin/blob/master/docs/HOW-TO.md#add-more-details-on-existing-events)
* [Add custom event in state machine](https://github.com/monsieurbiz/SyliusOrderHistoryPlugin/blob/master/docs/HOW-TO.md#add-more-details-on-existing-events)
* [Add custom type and label display in history timeline](https://github.com/monsieurbiz/SyliusOrderHistoryPlugin/blob/master/docs/HOW-TO.md#add-more-details-on-existing-events)

## Contributing

Expand Down
148 changes: 148 additions & 0 deletions docs/HOW-TO.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,148 @@
## Add more details on existing events

If you want to add more details on existing events, you can decorate native notifiers.

```yaml
# config/services.yaml
services:
App\Notifier\OrderHistoryWithAddressesDataNotifierDecorator:
decorates: MonsieurBiz\SyliusOrderHistoryPlugin\Notifier\OrderHistoryWithAddressesDataNotifier
arguments: [ '@.inner' ]
```

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

namespace App\Notifier;

use MonsieurBiz\SyliusOrderHistoryPlugin\Notifier\OrderHistoryWithAddressesDataNotifier;
use Sylius\Component\Core\Model\OrderInterface;

final class OrderHistoryWithAddressesDataNotifierDecorator
{
public function __construct(private OrderHistoryWithAddressesDataNotifier $decorated)
{
}

public function notifyEvent(OrderInterface $order, string $type, string $label, array $details = []): void
{
$details['my_custom_label'] = 'my_custom_value';
$this->decorated->notifyEvent($order, $type, $label, $details);
}
}
```

## Add custom events in code

It could be usefull to fired your own order timeline event. For example, you could notify when an order is sent to your
ERP or when an email is sent to your customer.

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

namespace App\EventListener;

use MonsieurBiz\SyliusOrderHistoryPlugin\Notifier\OrderHistoryNotifierInterface;
use Sylius\Bundle\ResourceBundle\Event\ResourceControllerEvent;
use App\Erp\ErpClient;

final class OrderEventListener
{
public function __construct(
private OrderHistoryNotifierInterface $notifier,
private ErpClient $erpClient,
){
}

public function onOrderItemAdded(ResourceControllerEvent $event): void
{
$order = $event->getSubject();
$erpOrderNumber = $this->erpClient->sendOrder($order);

# Use the event notifier with your own information
$this->notifier->notifyEvent($order, 'erp', 'send_order', [
'erp_order_number' => $erpOrderNumber,
]);
}
}
```

## Add custom event in state machine

There is two ways to add custom events in state machine.

### Use basic notifier with "on-the-fly" details

This is the easiest way to add custom events in state machine. You can use
basic [expression language](https://symfony.com/doc/current/reference/formats/expression_language.html)
and have acces to two vars: `object` and `event`.

```yaml
winzou_state_machine:
sylius_order_checkout:
callbacks:
after:
app_order_history_notify_custom:
on: 'address'
do: [ '@MonsieurBiz\SyliusOrderHistoryPlugin\Notifier\OrderHistoryNotifier', 'notifyEvent' ]
args:
- 'object'
- '"my_type"'
- '"my_custom_event"'
- |
{
email: object.getCustomer().getEmail(),
amount: object.getTotal(),
}
```

### Using your own notifier

It would be useful to use your own notifier for more complex events and/or if you want to inject some services into your
notifier. Your notifier should implement the `OrderHistoryNotifierInterface`. Extending `AbstractOrderHistoryNotifier`
is recommended to avoid boilerplate.

```php
<?php

declare(strict_types=1);

namespace App\Notifier;

use Sylius\Component\Core\Model\OrderInterface;

final class MyCustomNotifier extends AbstractOrderHistoryNotifier implements OrderHistoryNotifierInterface
{
public function notifyEvent(OrderInterface $order, string $type, string $label, array $details = []): void
{
$details['email'] = $order->getCustomer()?->getEmail();
$details['amount'] = $order->getCustomer()?->getEmail();
parent::notifyEvent($order, $type, $label, $details);
}
}
```

You can now use your own notifier in state machine.

```yaml
winzou_state_machine:
sylius_order_checkout:
callbacks:
after:
app_order_history_notify_custom:
on: 'address'
do: [ '@App\Notifier\MyCustomNotifier', 'notifyEvent' ]
args: [ 'object', '"my_type"', '"my_custom_event"' ]
```

## Add custom type and label display in history timeline

You could add a dedicated label and title display in the history timeline for your custom event type and event label.
There are native built-in templates for common labels like `new`, `completed` or `cancelled` as well as default ones
for unknown types and labels. However, if you want to add your own, you can do so by adding new templates in the
following paths:

* `templates/bundles/MonsieurBizSyliusOrderHistoryPlugin/Event/Type/{type}.html.twig`
* `templates/bundles/MonsieurBizSyliusOrderHistoryPlugin/Event/Label/{label}.html.twig`

0 comments on commit f778735

Please sign in to comment.