src/Service/CustomGA4Ecommerce.php line 200

Open in your IDE?
  1. <?php
  2. namespace App\Service;
  3. use CoreShop\Bundle\TrackingBundle\Tracker\AbstractEcommerceTracker;
  4. use Pimcore\Model\DataObject\CoreShopProduct;
  5. use Symfony\Component\HttpFoundation\RequestStack;
  6. use Symfony\Component\HttpFoundation\Session\SessionInterface;
  7. use Symfony\Component\OptionsResolver\OptionsResolver;
  8. use Twig\Environment;
  9. class CustomGA4Ecommerce extends AbstractEcommerceTracker
  10. {
  11.     private ?RequestStack $requestStack;
  12.     public function __construct(Environment $twig, array $options = [], bool $enabled falseRequestStack $requestStack null)
  13.     {
  14.         parent::__construct($twig$options);
  15.         $this->setEnabled($enabled);
  16.         $this->requestStack $requestStack;
  17.     }
  18.     protected function configureOptions(OptionsResolver $resolver): void
  19.     {
  20.         parent::configureOptions($resolver);
  21.         $resolver->setDefaults(['template_prefix' => '@CoreShopFrontend/Tracking/ga4tm']);
  22.         $this->setEnabled(true);
  23.     }
  24.     public function trackProduct($product): void
  25.     {
  26.         $parameters = [];
  27.         $actionData = [
  28.             'items' => [$this->transformProductAction($product)],
  29.         ];
  30.         $parameters['actionData'] = $actionData;
  31.         //unset($parameters['actionData']['quantity']);
  32.         $this->buildCode($this->renderTemplate('product_view'$parameters));
  33.     }
  34.     public function trackProductImpression($product): void
  35.     {
  36.         $parameters = [];
  37.         if (isset($product['itemlist']) && is_iterable($product['itemlist'])) {
  38.             $actionData = [];
  39.             foreach ($product['itemlist'] as $item) {
  40.                 $actionData[] = $this->transformProductAction($this->convertProductToArray($item));
  41.             }
  42.             $parameters['actionData'] = [
  43.                 'item_list_id' => $product['item_list_id'] ?? '',
  44.                 'item_list_name' => $product['item_list_name'] ?? '',
  45.                 'items' => $actionData
  46.             ];
  47.         } else {
  48.             $actionData = [
  49.                 'currency' => $product['currency'] ?? null,
  50.                 'value' => $product['price'] ?? 0,
  51.                 'items' => [$this->transformProductAction($product)],
  52.             ];
  53.             $parameters['actionData'] = $actionData;
  54.         }
  55.         //unset($parameters['actionData']['quantity']);
  56.         $parameters['event'] = $product['event'] ?? 'product_impression';
  57.         $this->buildCode($this->renderTemplate('product_action'$parameters));
  58.     }
  59.     public function trackCartAdd($cart$productfloat $quantity 1.0): void
  60.     {
  61.         $this->trackCartAction($product'add'$quantity);
  62.     }
  63.     public function trackCartRemove($cart$productfloat $quantity 1.0): void
  64.     {
  65.         $this->trackCartAction($product'remove'$quantity);
  66.     }
  67.     public function trackCheckoutStep($cart$stepIdentifier nullbool $isFirstStep false$checkoutOption null): void
  68.     {
  69.         $parameters = [];
  70.         $actionData = [];
  71.         $actionData['items'] = $cart['items'];
  72.         $actionData['currency'] = $cart['currency'];
  73.         $actionData['value'] = $cart['total'];
  74.         if (null !== $stepIdentifier || null !== $checkoutOption) {
  75.             $actionData['checkout_step'] = $stepIdentifier 1;
  76.             if (!empty($cart['voucher'])) {
  77.                 $actionData['coupon'] = $cart['voucher'];
  78.             }
  79.         }
  80.         $parameters['actionData'] = $actionData;
  81.         $parameters['event'] = $isFirstStep === true 'begin_checkout' 'checkout_progress';
  82.         $this->buildCode($this->renderTemplate('checkout'$parameters));
  83.     }
  84.     public function trackCheckoutComplete($order): void
  85.     {
  86.         $orderData $this->transformOrder($order);
  87.         $actionData array_merge($orderData, ['items' => $order['items'] ?? []]);
  88.         $parameters = [];
  89.         $parameters['actionData'] = $actionData;
  90.         $this->buildCode($this->renderTemplate('checkout_complete'$parameters));
  91.     }
  92.     protected function trackCartAction($product$actionfloat $quantity 1.0): void
  93.     {
  94.         $product $this->transformProductAction($product);
  95.         $product['quantity'] = $quantity;
  96.         $parameters = [];
  97.         $actionData = ['currency' => $product['currency'] ?? null'value' => $product['price'] * $quantity'items' => []];
  98.         $actionData['items'][] = $product;
  99.         $parameters['actionData'] = $actionData;
  100.         $parameters['event'] = $action === 'remove' 'remove_from_cart' 'add_to_cart';
  101.         $this->buildCode($this->renderTemplate('product_action'$parameters));
  102.     }
  103.     protected function transformOrder(array $actionData): array
  104.     {
  105.         return [
  106.             'transaction_id' => $actionData['id'],
  107. //            'affiliation' => $actionData['affiliation'] ?: '',
  108.             'value' => $actionData['total'],
  109.             'tax' => $actionData['totalTax'],
  110.             'shipping' => $actionData['shipping'],
  111.             'currency' => $actionData['currency'],
  112.         ];
  113.     }
  114.     protected function transformProductAction(array $item): array
  115.     {
  116.         if (!$item) {
  117.             return [];
  118.         }
  119.         $product CoreShopProduct::getById((int)$item['id']);
  120.         $categoriesArray = [];
  121.         if ($product instanceof CoreShopProduct) {
  122.             $i 2;
  123.             foreach ($product->getCategories() as $category) {
  124.                 if (empty($categoriesArray)) {
  125.                     $categoriesArray['item_category'] = $category->getName();
  126.                 } else {
  127.                     $categoriesArray['item_category' $i++] = $category->getName();
  128.                 }
  129.             }
  130.             $item['brand'] = $product->getBrand();
  131.         }
  132.         return $this->filterNullValues(array_merge([
  133.             'item_id' => $item['id'],
  134.             'item_name' => $item['name'],
  135.             'item_brand' => $item['brand'] ?? null,
  136.             'item_variant' => $item['variant'] ?? null,
  137.             'price' => round($item['price'], 2),
  138.             'quantity' => $item['quantity'] ?? 1,
  139.             'index' => $item['position'] ?? null,
  140.             'currency' => $item['currency'],
  141.             'item_gender' => $item['gender'] ?? null,
  142.             'item_collection' => $item['collection'] ?? null,
  143.             'item_subcollection' => $item['subcollection'] ?? null
  144.         ], $categoriesArray));
  145.     }
  146.     protected function buildCheckoutCalls(array $items): array
  147.     {
  148.         $calls = [];
  149.         foreach ($items as $item) {
  150.             $calls[] = $this->transformProductAction($item);
  151.         }
  152.         return $calls;
  153.     }
  154.     protected function buildCode(string $code): void
  155.     {
  156.         if (!$code) {
  157.             return;
  158.         }
  159.         $session $this->requestStack?->getSession();
  160.         if (!$session instanceof SessionInterface) {
  161.             return;
  162.         }
  163.         if ($session->has('TRACKER_CODE')) {
  164.             $code $session->get('TRACKER_CODE') . "\n\n\n" $code;
  165.         }
  166.         $session->set('TRACKER_CODE'$code);
  167.     }
  168.     private function convertProductToArray(CoreShopProduct $product): array
  169.     {
  170.         return [
  171.             'id' => $product->getId(),
  172.             'name' => $product->getName(),
  173.             'category' => $product->getCategories(),
  174.             'brand' => $product->getBrand(),
  175.             'variant' => null,
  176.             'price' => $product->getWholeSalePrice() / 100,
  177.             'quantity' => 1,
  178.             'index' => null,
  179.             'currency' => 'HUF',
  180.             'collection' => $product->getCollection(),
  181.             'subcollection' => $product->getSubCollection(),
  182.             'gender' => $product->getTypeofwatch()
  183.         ];
  184.     }
  185. }