Skip to content

Commit 84e13d4

Browse files
committed
Add GA4 compatibility
1 parent 14e488f commit 84e13d4

18 files changed

+810
-57
lines changed

Config/config.xml

+16-3
Original file line numberDiff line numberDiff line change
@@ -7,12 +7,25 @@
77
<form name="googletagmanager.configuration.form" class="GoogleTagManager\Form\Configuration" />
88
</forms>
99

10+
<services>
11+
<service id="googletamanager.service" class="GoogleTagManager\Service\GoogleTagService">
12+
<argument type="service" id="request_stack"/>
13+
</service>
14+
15+
<service id="googletamanager.tag.listener" class="GoogleTagManager\Listener\GoogleTagListener">
16+
<argument type="service" id="googletamanager.service"/>
17+
<argument type="service" id="request_stack"/>
18+
<tag name="kernel.event_subscriber"/>
19+
</service>
20+
</services>
21+
1022
<hooks>
11-
<hook id="googletagmanager.head.hook" class="GoogleTagManager\Hook\FrontHook" scope="request">
23+
<hook id="googletagmanager.front.hook" class="GoogleTagManager\Hook\FrontHook" scope="request">
1224
<tag name="hook.event_listener" event="main.head-top" method="onMainHeadTop"/>
13-
</hook>
14-
<hook id="googletagmanager.body.hook" class="GoogleTagManager\Hook\FrontHook" scope="request">
1525
<tag name="hook.event_listener" event="main.body-top" method="onMainBodyTop"/>
26+
<tag name="hook.event_listener" event="main.javascript-initialization" method="onMainJsInit"/>
27+
<tag name="hook.event_listener" event="product.bottom" method="onProductBottom"/>
28+
<argument type="service" id="googletamanager.service"/>
1629
</hook>
1730
<hook id="googletagmanager.configuration.hook" class="GoogleTagManager\Hook\BackHook" scope="request">
1831
<tag name="hook.event_listener" event="module.configuration" type="back" method="onModuleConfiguration"/>

Config/module.xml

+5-2
Original file line numberDiff line numberDiff line change
@@ -13,14 +13,17 @@
1313
<language>en_US</language>
1414
<language>fr_FR</language>
1515
</languages>
16-
<version>2.0.1</version>
16+
<version>2.2.0</version>
1717
<authors>
1818
<author>
1919
<name>Tom Pradat</name>
2020
<email>tpradat@openstudio.fr</email>
2121
</author>
2222
</authors>
2323
<type>classic</type>
24-
<thelia>2.1.0</thelia>
24+
<required>
25+
<module version=">=1.0.1">ShortCode</module>
26+
</required>
27+
<thelia>2.4.0</thelia>
2528
<stability>prod</stability>
2629
</module>

Config/routing.xml

+8
Original file line numberDiff line numberDiff line change
@@ -7,4 +7,12 @@
77
<route id="googletagmanager.configuration" path="/admin/module/googletagmanager/save" methods="post">
88
<default key="_controller">GoogleTagManager\Controller\Configuration::saveAction</default>
99
</route>
10+
11+
<route id="googletagmanager.item" path="/googletagmanager/getItem" methods="post">
12+
<default key="_controller">GoogleTagManager\Controller\ProductDataController::getProductDataWithUrl</default>
13+
</route>
14+
15+
<route id="googletagmanager.cart.item" path="/googletagmanager/getCartItem" methods="post">
16+
<default key="_controller">GoogleTagManager\Controller\ProductDataController::getCartItem</default>
17+
</route>
1018
</routes>

Controller/Configuration.php

+8-6
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,10 @@
1515

1616
use GoogleTagManager\GoogleTagManager;
1717
use Thelia\Controller\Admin\BaseAdminController;
18+
use Thelia\Core\HttpFoundation\Session\Session;
1819
use Thelia\Core\Security\AccessManager;
1920
use Thelia\Core\Security\Resource\AdminResources;
21+
use Thelia\Core\Translation\Translator;
2022

2123
/**
2224
* Class Configuration
@@ -25,24 +27,24 @@
2527
*/
2628
class Configuration extends BaseAdminController
2729
{
28-
public function saveAction(){
30+
public function saveAction(Session $session){
2931

3032
if (null !== $response = $this->checkAuth(array(AdminResources::MODULE), array('googletagmanager'), AccessManager::UPDATE)) {
3133
return $response;
3234
}
3335

34-
$form = new \GoogleTagManager\Form\Configuration($this->getRequest());
36+
$form = $this->createForm("googletagmanager.configuration.form");
3537
$response=null;
3638

3739
try {
3840
$vform = $this->validateForm($form);
3941
$data = $vform->getData();
40-
$lang = $this->getRequest()->getSession()->get('thelia.admin.edition.lang');
42+
$lang = $session->get('thelia.admin.edition.lang');
4143

42-
GoogleTagManager::setConfigValue('googletagmanager_gtmId', $data['gtmId'], $lang->getlocale());
44+
GoogleTagManager::setConfigValue('googletagmanager_gtmId', $data['gtmId']);
4345
} catch (\Exception $e) {
4446
$this->setupFormErrorContext(
45-
$this->getTranslator()->trans("Syntax error"),
47+
Translator::getInstance()->trans("Syntax error"),
4648
$e->getMessage(),
4749
$form,
4850
$e
@@ -51,4 +53,4 @@ public function saveAction(){
5153

5254
return $this->generateSuccessRedirect($form);
5355
}
54-
}
56+
}

Controller/ProductDataController.php

+85
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,85 @@
1+
<?php
2+
3+
namespace GoogleTagManager\Controller;
4+
5+
use GoogleTagManager\Service\GoogleTagService;
6+
use Thelia\Controller\Front\BaseFrontController;
7+
use Thelia\Core\HttpFoundation\JsonResponse;
8+
use Thelia\Model\Base\RewritingUrlQuery;
9+
use Thelia\Model\Currency;
10+
use Thelia\Model\Lang;
11+
use Thelia\Model\ProductQuery;
12+
use Thelia\Model\ProductSaleElementsQuery;
13+
14+
class ProductDataController extends BaseFrontController
15+
{
16+
public function getProductDataWithUrl()
17+
{
18+
$request = $this->getRequest();
19+
20+
/** @var GoogleTagService $googleTagService */
21+
$googleTagService = $this->getContainer()->get('googletamanager.service');
22+
23+
$requestContent = json_decode($request->getContent(), true);
24+
$productUrl = parse_url($requestContent['productUrl']);
25+
$result = [];
26+
27+
if (!isset($productUrl['path'])) {
28+
return new JsonResponse(json_encode($result));
29+
}
30+
31+
$rewriteUrl = RewritingUrlQuery::create()
32+
->filterByView('product')
33+
->filterByUrl(substr($productUrl['path'], 1))
34+
->findOne();
35+
36+
$session = $request->getSession();
37+
38+
/** @var Lang $lang */
39+
$lang = $session->get('thelia.current.lang');
40+
41+
/** @var Currency $currency */
42+
$currency = $session->get('thelia.current.currency');
43+
44+
45+
if (null !== $rewriteUrl) {
46+
$product = ProductQuery::create()->findPk($rewriteUrl->getViewId());
47+
$result = $googleTagService->getProductItem($product, $lang, $currency);
48+
}
49+
50+
return new JsonResponse(json_encode([$result]));
51+
}
52+
53+
public function getCartItem()
54+
{
55+
$request = $this->getRequest();
56+
57+
/** @var GoogleTagService $googleTagService */
58+
$googleTagService = $this->getContainer()->get('googletamanager.service');
59+
60+
$requestContent = json_decode($request->getContent(), true);
61+
$result = [];
62+
63+
if (!isset($requestContent['pseId']) || !isset($requestContent['quantity'])) {
64+
return new JsonResponse(json_encode($result));
65+
}
66+
67+
$pseId = $requestContent['pseId'];
68+
$quantity = $requestContent['quantity'];
69+
70+
$pse = ProductSaleElementsQuery::create()->findPk($pseId);
71+
$product = $pse->getProduct();
72+
73+
$session = $request->getSession();
74+
75+
/** @var Lang $lang */
76+
$lang = $session->get('thelia.current.lang');
77+
78+
/** @var Currency $currency */
79+
$currency = $session->get('thelia.current.currency');
80+
81+
$result = $googleTagService->getProductItem($product, $lang, $currency, $pse, $quantity);
82+
83+
return new JsonResponse(json_encode([$result]));
84+
}
85+
}

Form/Configuration.php

+4-7
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414

1515

1616
use GoogleTagManager\GoogleTagManager;
17+
use Symfony\Component\Form\Extension\Core\Type\TextType;
1718
use Thelia\Core\Translation\Translator;
1819
use Thelia\Form\BaseForm;
1920

@@ -29,10 +30,10 @@ protected function buildForm()
2930
$form = $this->formBuilder;
3031

3132
$lang = $this->getRequest()->getSession()->get('thelia.admin.edition.lang');
32-
$value = GoogleTagManager::getConfigValue('googletagmanager_gtmId', null, $lang->getLocale());
33+
$value = GoogleTagManager::getConfigValue('googletagmanager_gtmId');
3334
$form->add(
3435
"gtmId",
35-
"text",
36+
TextType::class,
3637
array(
3738
'data' => $value,
3839
'label' => Translator::getInstance()->trans("Google Tag Manager Id",[] ,GoogleTagManager::DOMAIN_NAME),
@@ -42,8 +43,4 @@ protected function buildForm()
4243
)
4344
);
4445
}
45-
46-
public function getName(){
47-
return 'googletagmanager';
48-
}
49-
}
46+
}

GoogleTagManager.php

+13
Original file line numberDiff line numberDiff line change
@@ -12,10 +12,23 @@
1212

1313
namespace GoogleTagManager;
1414

15+
use Propel\Runtime\Connection\ConnectionInterface;
16+
use ShortCode\ShortCode;
1517
use Thelia\Module\BaseModule;
1618

1719
class GoogleTagManager extends BaseModule
1820
{
1921
/** @var string */
2022
const DOMAIN_NAME = 'googletagmanager';
23+
24+
const GOOGLE_TAG_VIEW_ITEM = 'google_tag_view_item';
25+
const GOOGLE_TAG_VIEW_LIST_ITEM = 'google_tag_view_list_item';
26+
const GOOGLE_TAG_TRIGGER_LOGIN = 'google_tag_trigger_login';
27+
28+
public function postActivation(ConnectionInterface $con = null): void
29+
{
30+
ShortCode::createNewShortCodeIfNotExist(self::GOOGLE_TAG_VIEW_LIST_ITEM, self::GOOGLE_TAG_VIEW_LIST_ITEM);
31+
ShortCode::createNewShortCodeIfNotExist(self::GOOGLE_TAG_VIEW_ITEM, self::GOOGLE_TAG_VIEW_ITEM);
32+
}
33+
2134
}

Hook/FrontHook.php

+72-20
Original file line numberDiff line numberDiff line change
@@ -14,10 +14,10 @@
1414

1515

1616
use GoogleTagManager\GoogleTagManager;
17+
use GoogleTagManager\Service\GoogleTagService;
1718
use Thelia\Core\Event\Hook\HookRenderEvent;
1819
use Thelia\Core\Hook\BaseHook;
19-
use Thelia\Model\Base\LangQuery;
20-
use Thelia\Model\ConfigQuery;
20+
use Thelia\Model\LangQuery;
2121

2222
/**
2323
* Class FrontHook
@@ -26,37 +26,89 @@
2626
*/
2727
class FrontHook extends BaseHook
2828
{
29-
public function onMainHeadTop(HookRenderEvent $event){
30-
$lang = $this->getLang();
31-
$value = GoogleTagManager::getConfigValue('googletagmanager_gtmId', null, $lang->getLocale());
32-
if ("" != $value){
29+
/**
30+
* @var GoogleTagService
31+
*/
32+
private $googleTagService;
33+
34+
public function __construct(GoogleTagService $googleTagService)
35+
{
36+
$this->googleTagService = $googleTagService;
37+
}
38+
39+
public function onMainHeadTop(HookRenderEvent $event)
40+
{
41+
if ($gtmId = GoogleTagManager::getConfigValue('googletagmanager_gtmId')) {
42+
$view = $this->request->get('_view');
43+
44+
$event->add($this->render('datalayer/thelia-page-view.html', ['data' => $this->googleTagService->getTheliaPageViewParameters()]));
45+
46+
if (in_array($view, ['category', 'brand', 'search'])) {
47+
$event->add($this->render('datalayer/view-item-list.html', ['eventName' => 'view_item_list']));
48+
}
49+
50+
if ($view === 'product') {
51+
$event->add($this->render('datalayer/view-item.html', ['eventName' => 'view_item']));
52+
}
53+
54+
if (null !== $authAction = $this->request->getSession()->get(GoogleTagManager::GOOGLE_TAG_TRIGGER_LOGIN)) {
55+
$event->add($this->render('datalayer/thelia-page-view.html', [
56+
'data' => $this->googleTagService->getLogInData($authAction)
57+
]));
58+
$this->request->getSession()->set(GoogleTagManager::GOOGLE_TAG_TRIGGER_LOGIN, null);
59+
}
60+
61+
if ($view === 'order-placed') {
62+
$event->add($this->render('datalayer/thelia-page-view.html', [
63+
'data' => $this->googleTagService->getPurchaseData($this->request->get('order_id'))
64+
]));
65+
}
66+
3367
$event->add(
34-
"<!-- Google Tag Manager -->".
35-
"<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':".
36-
"new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],".
37-
"j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=".
38-
"'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);".
39-
"})(window,document,'script','dataLayer','".$value."');</script>".
68+
"<!-- Google Tag Manager -->" .
69+
"<script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':" .
70+
"new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0]," .
71+
"j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=" .
72+
"'https://www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);" .
73+
"})(window,document,'script','dataLayer','" . $gtmId . "');</script>" .
4074
"<!-- End Google Tag Manager -->"
4175
);
4276
}
4377
}
44-
public function onMainBodyTop(HookRenderEvent $event){
45-
$lang = $this->getLang();
46-
$value = GoogleTagManager::getConfigValue('googletagmanager_gtmId', null, $lang->getLocale());
47-
if ("" != $value){
48-
$event->add("<!-- Google Tag Manager (noscript) -->".
49-
"<noscript><iframe src='https://www.googletagmanager.com/ns.html?id=".$value."' ".
50-
"height='0' width='0' style='display:none;visibility:hidden'></iframe></noscript>".
78+
79+
public function onMainBodyTop(HookRenderEvent $event)
80+
{
81+
$value = GoogleTagManager::getConfigValue('googletagmanager_gtmId');
82+
83+
if ("" != $value) {
84+
$event->add("<!-- Google Tag Manager (noscript) -->" .
85+
"<noscript><iframe src='https://www.googletagmanager.com/ns.html?id=" . $value . "' " .
86+
"height='0' width='0' style='display:none;visibility:hidden'></iframe></noscript>" .
5187
"<!-- End Google Tag Manager (noscript) -->"
5288
);
5389
}
5490
}
5591

92+
public function onMainJsInit(HookRenderEvent $event)
93+
{
94+
$view = $this->request->get('_view');
95+
96+
if (in_array($view, ['category', 'brand', 'search'])) {
97+
$event->add($this->render('datalayer/select-item.html'));
98+
}
99+
$event->add($this->render('datalayer/add-to-cart.html'));
100+
}
101+
102+
public function onProductBottom(HookRenderEvent $event)
103+
{
104+
$productId = $event->getArgument('product');
105+
$this->request->getSession()->set(GoogleTagManager::GOOGLE_TAG_VIEW_ITEM, $productId);
106+
}
107+
56108
protected function getLang()
57109
{
58110
$lang = $this->getRequest()->getSession()->get("thelia.current.lang");
59-
if (null === $lang){
111+
if (null === $lang) {
60112
$lang = LangQuery::create()->filterByByDefault(1)->findOne();
61113
}
62114
return $lang;

0 commit comments

Comments
 (0)