<?php
namespace App\EventSubscriber;
use App\Event\CartItemAdded;
use App\Service\Klaviyo\KlaviyoEmail;
use App\Service\Klaviyo\KlaviyoEventService;
use Exception;
use Symfony\Component\EventDispatcher\EventSubscriberInterface;
use Symfony\Component\HttpFoundation\RequestStack;
use App\Event\EmailEntered;
use App\Service\Klaviyo\KlaviyoProfileService;
use App\Event\OrderMakedEvent;
use App\Repository\ProdRepository;
use App\Env;
use App\Event\OrderStartedEvent;
use App\Event\ProdViewedEvent;
class Klaviyo implements EventSubscriberInterface
{
public function __construct(
private KlaviyoEventService $klaviyoEventService,
private RequestStack $requestStack,
private KlaviyoEmail $klaviyoEmail,
private ProdRepository $prodRepository,
)
{
}
public function onCartItemAdded(CartItemAdded $event): void
{
try {
$this->klaviyoEventService->track(
'Added to Cart',
$this->klaviyoEmail->getEmail(),
[
'product_id' => $event->getProd()->getId(),
'product_name' => $event->getProd()->getName(),
'price' => $event->getProd()->getPrice(),
'quantity' => $event->getNum(),
'cart_value' => $event->getCartAmount(),
'url' => $this->requestStack->getCurrentRequest()->getUri(),
]
);
} catch (Exception $e) {
echo $e->getMessage();die();
}
}
public function onEmailEntered(EmailEntered $event): void
{
try {
$this->klaviyoEmail->setEmail($event->getEmail());
$this->klaviyoProfileService->identify($event->getEmail());
} catch (Exception $e) {
}
}
public function onOrderStarted(OrderStartedEvent $event): void
{
try {
$items = [];
foreach ($event->getCartItems() as $item) {
if (empty($item['id'])) {
continue;
}
$product = $this->prodRepository->find($item['id']);
if (!$product) {
continue;
}
$items[] = [
'product_id' => $product->getId(),
'name' => $product->getName(),
'price' => $item['price'],
'quantity' => $item['num'],
];
}
$this->klaviyoEventService->track(
'Started Checkout',
$this->klaviyoEmail->getEmail(),
[
'total' => $event->getAmount(),
'currency' => Env::currency_code(),
'items' => $items,
]
);
} catch (Exception $e) {
dd($e);
}
}
public function onOrderMaked(OrderMakedEvent $event): void
{
try {
$this->klaviyoEventService->track(
'Order Placed',
$event->getOrder()->getEmail(),
[
'order_id' => $event->getOrder()->getId(),
'total' => $event->getOrder()->getAmount(),
'currency' => Env::currency_code(),
'items' => array_values(array_map(fn($item) => [
'product_id' => $item['id'],
'name' => $this->prodRepository->find($item['id'])->getName(),
'price' => $item['price'],
'quantity' => $item['num'],
], $event->getCartItems())),
]
);
} catch (Exception $e) {
dd($e);
}
}
public function onProdViewed(ProdViewedEvent $event): void
{
try {
$product = $event->getProd();
$this->klaviyoEventService->track(
'Viewed Product',
$this->klaviyoEmail->getEmail(),
[
'product_id' => $product->getId(),
'name' => $product->getName(),
'price' => $product->getPrice(),
'url' => $this->requestStack->getCurrentRequest()?->getUri() ?? '',
]
);
} catch (Exception $e) {
dd($e);
}
}
public static function getSubscribedEvents(): array
{
return [
CartItemAdded::NAME => 'onCartItemAdded',
EmailEntered::NAME => 'onEmailEntered',
OrderMakedEvent::NAME => 'onOrderMakedEvent',
OrderStartedEvent::NAME => 'onOrderStarted',
ProdViewedEvent::NAME => 'onProdViewed',
];
}
}