<?php
declare(strict_types=1);
namespace App\EventSubscriber\Shop\OrderExtension\Bonus;
use App\Entity\Shop\Payment;
use App\Event\Shop\OrderFormCreateAfterEvent;
use App\Event\Shop\OrderPlaceAfterEvent;
use App\Event\Shop\PaymentStatusChangeAfterEvent;
use App\Exception\RuntimeException;
use App\Service\UkSlaveApi;
use Doctrine\ORM\EntityManagerInterface;
use Exception;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\Form\Extension\Core\Type\ChoiceType;
use Symfony\Component\Serializer\Encoder\JsonEncoder;
use Symfony\Component\Serializer\Normalizer\ObjectNormalizer;
use Symfony\Component\Serializer\Serializer;
class WybieramyDomBonusSubscriber implements EventSubscriberInterface
{
protected const UK_SLAVE_ID = 'b1afc8b37b4ca097a3df2c445e4fc6ea';
protected UkSlaveApi $api;
protected EntityManagerInterface $em;
public function __construct(UkSlaveApi $api, EntityManagerInterface $em)
{
$this->api = $api;
$this->em = $em;
}
public function addBonusField(OrderFormCreateAfterEvent $event): void
{
$form = $event->getForm();
$form->add('bonus', ChoiceType::class, [
'choices' => [
'Wersja Elektroniczna (BEZPŁATNIE)' => 1,
'Wersja Drukowana (BEZPŁATNIE)' => 2,
'Nie, dziękuje' => 0,
],
'expanded' => true,
'multiple' => false,
]);
}
public function addBonusInfoToOrder(OrderPlaceAfterEvent $event): void
{
if (null !== $bonus = $event->getExtraFormData()['bonus'] ?? null) {
// Add a bonus info to an order
$order = $event->getOrder();
$order->setParam('bonus', $bonus);
$order->setParam('bonus_sent', false);
try {
$this->em->persist($order);
$this->em->flush();
} catch (Exception $e) {
// TODO: Log
}
}
}
public function processBonus(PaymentStatusChangeAfterEvent $event): void
{
// Process only when a payment was successfull
if ($event->getStatus() !== Payment::STATUS_SUCCESS)
return;
$order = $event->getPayment()->getShopOrder();
$bonusId = $order->getParam('bonus');
if (in_array($bonusId, [1, 2], true)) {
try {
$serializer = new Serializer([new ObjectNormalizer()], [new JsonEncoder()]);
$data = [
'json' => $serializer->serialize([
'order' => [
'id' => $order->getId(),
'addressDelivery' => $order->getAddressDelivery(),
'addressInvoice' => $order->getAddressInvoice(),
'comment' => $order->getComment(),
'acceptance' => $order->getAcceptance(),
'acceptanceMarketing' => $order->getAcceptanceMarketing(),
]
], 'json'),
];
$response = $this->api->request(self::UK_SLAVE_ID, $data);
// Validate a response
if (array_key_exists('error', $response) || (array_key_exists('data', $response) && empty($response['data'])))
throw new RuntimeException('UK Slave Error: ' . ($response['error'] ?? 'empty body'));
// Mark a bonus as sent
$order->setParam('bonus_sent', true);
$this->em->persist($order);
$this->em->flush();
} catch (Exception $e) {
dump($e);
// TODO: log
}
}
}
public static function getSubscribedEvents(): array
{
return [
OrderFormCreateAfterEvent::NAME => [
['addBonusField', 1000],
],
OrderPlaceAfterEvent::NAME => [
['addBonusInfoToOrder', 1000],
],
PaymentStatusChangeAfterEvent::NAME => [
['processBonus', 1000],
],
];
}
}