├── registration.php
├── etc
├── module.xml
├── frontend
│ └── routes.xml
├── config.xml
└── adminhtml
│ └── system.xml
├── view
└── frontend
│ ├── templates
│ ├── noscript.phtml
│ └── gtm.phtml
│ └── layout
│ └── default.xml
├── composer.json
├── Controller
└── Index
│ └── Index.php
├── Helper
└── Data.php
├── README.md
└── Block
└── Gtm.php
/registration.php:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
--------------------------------------------------------------------------------
/etc/frontend/routes.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
--------------------------------------------------------------------------------
/etc/config.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 | 1
7 |
8 |
9 |
10 |
11 |
--------------------------------------------------------------------------------
/view/frontend/templates/noscript.phtml:
--------------------------------------------------------------------------------
1 | getContainerId();
3 | if ($block->getIsEnable()): // if module is enabled
4 | ?>
5 |
6 |
7 |
9 |
10 |
11 |
12 |
--------------------------------------------------------------------------------
/composer.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "chapagain/googletagmanager2",
3 | "description": "Google Tag Manager module for Magento 2",
4 | "type": "magento2-module",
5 | "version": "1.0.1",
6 | "license": [
7 | "OSL-3.0",
8 | "AFL-3.0"
9 | ],
10 | "require": {
11 | "php": "~5.5.0|~5.6.0|~7.0.0"
12 | },
13 | "autoload": {
14 | "files": [
15 | "registration.php"
16 | ],
17 | "psr-4": {
18 | "Chapagain\\GoogleTagManager\\": ""
19 | }
20 | }
21 | }
22 |
--------------------------------------------------------------------------------
/view/frontend/templates/gtm.phtml:
--------------------------------------------------------------------------------
1 | getContainerId();
3 |
4 | if ($block->getIsEnable()): // if module is enabled
5 | ?>
6 |
7 |
8 |
9 | getIsEnableDataLayer()):
11 | echo $block->getDataLayerProduct(); // Product Detail Page
12 | echo $block->getDataLayerOrder(); // Order Success Page
13 | endif;
14 | ?>
15 |
16 |
21 |
22 |
23 |
24 |
25 |
--------------------------------------------------------------------------------
/view/frontend/layout/default.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 |
15 |
16 |
17 |
18 |
--------------------------------------------------------------------------------
/Controller/Index/Index.php:
--------------------------------------------------------------------------------
1 | resultPageFactory = $resultPageFactory;
21 | parent::__construct($context);
22 | }
23 | /**
24 | * Default customer account page
25 | *
26 | * @return void
27 | */
28 | public function execute()
29 | {
30 | return $this->resultPageFactory->create();
31 | }
32 | }
33 |
--------------------------------------------------------------------------------
/Helper/Data.php:
--------------------------------------------------------------------------------
1 | scopeConfig = $scopeConfig;
20 | }
21 |
22 | /**
23 | * Check if the module is enabled
24 | *
25 | * @return boolean 0 or 1
26 | */
27 | public function getIsEnable()
28 | {
29 | $storeScope = \Magento\Store\Model\ScopeInterface::SCOPE_STORE;
30 | return $this->scopeConfig->getValue(self::XML_PATH_GTM_ENABLED, $storeScope);
31 | }
32 |
33 | /**
34 | * Check if data layered is enabled or not
35 | *
36 | * @return boolean 0 or 1
37 | */
38 | public function getIsEnableDataLayer()
39 | {
40 | $storeScope = \Magento\Store\Model\ScopeInterface::SCOPE_STORE;
41 | return $this->scopeConfig->getValue(self::XML_PATH_GTM_ENABLED_DATA_LAYER, $storeScope);
42 | }
43 |
44 | /**
45 | * Get container id
46 | *
47 | * @return string
48 | */
49 | public function getContainerId()
50 | {
51 | $storeScope = \Magento\Store\Model\ScopeInterface::SCOPE_STORE;
52 | $containerId = $this->scopeConfig->getValue(self::XML_PATH_GTM_CONTAINER_ID, $storeScope);
53 | return trim($containerId);
54 | }
55 | }
56 |
--------------------------------------------------------------------------------
/etc/adminhtml/system.xml:
--------------------------------------------------------------------------------
1 |
2 |
3 |
4 |
5 |
6 |
7 |
8 |
9 |
10 | chapagain_tab
11 | Chapagain_GoogleTagManager::config
12 |
13 |
14 |
15 |
16 | Magento\Config\Model\Config\Source\Yesno
17 |
18 |
19 |
20 | Magento\Config\Model\Config\Source\Yesno
21 |
22 |
23 |
24 |
25 |
26 |
27 |
28 |
29 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | # Google Tag Manager - Extension for Magento 2.x
2 |
3 | This extension allows you to integrate Google Tag Manager on your Magento site so that you can track
4 | and gather valuable visitor data from your website and make important decisions to grow your
5 | business. This extension also provides e-commerce transaction tracking feature. You just need to enter
6 | your Tag Manager container id in the extension's configuration settings.
7 |
8 | [Google Tag Manager](https://support.google.com/tagmanager/answer/6102821?hl=en) allows you to quickly and easily update tags and code snippets on your website or
9 | mobile app, such as those intended for traffic analysis and marketing optimization. You can add and
10 | update AdWords, Google Analytics, Floodlight, and 3rd party or custom tags from the Google Tag
11 | Manager user interface instead of editing site code. This reduces errors, frees you from having to
12 | involve a web developer, and allows you to quickly deploy new features or content onto your site.
13 |
14 | Google Tag Manager are FREE of charge services offered by Google. You need to create a separate
15 | Google Tag Manager account from [here](https://tagmanager.google.com/?hl=en#/admin/accounts/create) and link the account with your Magento store by adding the
16 | "Container ID" of your Google Tag Manager account to the current extension's configuration setting.
17 |
18 | ## Features
19 |
20 | - Tracks views of the product
21 | - Tracks categories and price of the product
22 | - Tracks transaction of the product by SKU, name, category, price and quantity
23 | - Tracks the transaction purchase revenue, tax and shipping cost
24 | - Tracks the coupon code
25 |
26 | ## Installation
27 |
28 | 1. The module's files should be placed in folder: `app/code/Chapagain/GoogleTagManager`
29 | 2. Open terminal/command-prompt
30 | 3. Go to your Magento website’s root directory with the following command:
31 | - `cd /path/to/your/magento/root/directory`
32 | 4. Enable the module and clear static content with the following command:
33 | - `php bin/magento module:enable Chapagain_GoogleTagManager –clear-static-content`
34 | 5. Do setup upgrade with the following command:
35 | - `php bin/magento setup:upgrade`
36 | 6. Flush cache with the following command:
37 | - `php bin/magento cache:flush`
38 | 7. That's all. The extension is installed now.
39 |
40 | ## Configuration Settings
41 |
42 | 1. Login to your Magento site's admin
43 | 2. Go to `STORES → Settings → Configuration` page
44 | 3. On left sidebar, click on `CHAPAGAIN EXTENSIONS → Google Tag Manager` menu
45 | 4. Here, you will see the following settings from where you can:
46 | - Enable/Disable module
47 | - Enable/Disable data layer
48 | - Add container ID of your site from Google Tag Manager
49 |
50 | ## Links
51 |
52 | - This extension is also available on Magento Marketplace: [Google Tag Manager on Magento Marketplace](https://marketplace.magento.com/chapagain-googletagmanager2.html)
53 | - BLOG: [http://blog.chapagain.com.np/google-tag-manager-magento-2-extension-free/](http://blog.chapagain.com.np/google-tag-manager-magento-2-extension-free/)
54 |
--------------------------------------------------------------------------------
/Block/Gtm.php:
--------------------------------------------------------------------------------
1 | _helper = $helper;
94 | $this->_logo = $logo;
95 | $this->_request = $request;
96 | $this->_registry = $registry;
97 | $this->_order = $order;
98 | $this->_checkoutSession = $checkoutSession;
99 | $this->_categoryRepository = $categoryRepository;
100 | $this->_currency = $currency;
101 | $this->_locale = $locale;
102 | $this->_tax = $tax;
103 |
104 | parent::__construct($context, $data);
105 | }
106 |
107 | // HELPER FUNCTIONS
108 |
109 | /**
110 | * Check if the module is enabled
111 | *
112 | * @return boolean 0 or 1
113 | */
114 | public function getIsEnable()
115 | {
116 | return $this->_helper->getIsEnable();
117 | }
118 |
119 | /**
120 | * Check if data layered is enabled or not
121 | *
122 | * @return boolean 0 or 1
123 | */
124 | public function getIsEnableDataLayer()
125 | {
126 | return $this->_helper->getIsEnableDataLayer();
127 | }
128 |
129 | /**
130 | * Get container id
131 | *
132 | * @return string
133 | */
134 | public function getContainerId()
135 | {
136 | return $this->_helper->getContainerId();
137 | }
138 |
139 | // END HELPER FUNCTIONS
140 |
141 |
142 | /**
143 | * Check if current page is homepage
144 | *
145 | * @return boolean true or false
146 | */
147 | public function getIsHomePage()
148 | {
149 | return $this->_logo->isHomePage();
150 | }
151 |
152 | /**
153 | * Check if current page is order success page
154 | *
155 | * @return boolean true or false
156 | */
157 | public function getIsOrderSuccessPage()
158 | {
159 | if (strpos($this->_request->getPathInfo(), '/checkout/onepage/success') !== false) {
160 | return true;
161 | }
162 | return false;
163 | }
164 |
165 | /**
166 | * Check if current page is shopping cart page
167 | *
168 | * @return boolean true or false
169 | */
170 | public function getIsCartPage()
171 | {
172 | if (strpos($this->_request->getPathInfo(), '/checkout/cart') !== false) {
173 | return true;
174 | }
175 | return false;
176 | }
177 |
178 | /**
179 | * Check if current page is checkout page
180 | *
181 | * @return boolean true or false
182 | */
183 | public function getIsCheckoutPage()
184 | {
185 | if (strpos($this->_request->getPathInfo(), '/checkout/onepage') !== false) {
186 | return true;
187 | }
188 | return false;
189 | }
190 |
191 | /**
192 | * Get current product
193 | *
194 | * @return \Magento\Catalog\Model\Product\Interceptor
195 | */
196 | public function getCurrentProduct()
197 | {
198 | return $this->_registry->registry('current_product');
199 | }
200 |
201 | /**
202 | * Get current category
203 | *
204 | * @return \Magento\Catalog\Model\Category\Interceptor
205 | */
206 | public function getCurrentCategory()
207 | {
208 | return $this->_registry->registry('current_category');
209 | }
210 |
211 | /**
212 | * Get order
213 | *
214 | * @return mixed \Magento\Sales\Model\Order or false
215 | */
216 | public function getOrder()
217 | {
218 | if ($this->getIsOrderSuccessPage()) {
219 | $orderId = $this->_checkoutSession->getLastOrderId();
220 | $order = $this->_order->load($orderId);
221 | if (!$order) {
222 | return false;
223 | }
224 | return $order;
225 | }
226 | return false;
227 | }
228 |
229 | public function getDataLayerProduct()
230 | {
231 | if ($product = $this->getCurrentProduct()) {
232 |
233 | $categoryCollection = $product->getCategoryCollection();
234 |
235 | $categories = array();
236 | foreach ($categoryCollection as $category) {
237 | $categories[] = $this->_categoryRepository->get($category->getEntityId())->getName();
238 | }
239 |
240 | $objProduct = new stdClass();
241 | $objProduct->name = $product->getName();
242 | $objProduct->id = $product->getSku();
243 |
244 | //$objProduct->price = $this->_currency->formatTxt($product->getFinalPrice(), array('display' => \Magento\Framework\Currency::NO_SYMBOL));
245 | /**
246 | * Fix for price for different locale
247 | *
248 | * For example:
249 | * Price display of Dutch locale is the opposite of English locale
250 | * English locale price = 1,230.55
251 | * Dutch locale price = 1.230,55
252 | */
253 | $objProduct->price = (string) $this->_locale->getNumber($product->getFinalPrice(), array('display' => \Magento\Framework\Currency::NO_SYMBOL));
254 |
255 | $objProduct->category = implode('|', $categories);
256 |
257 | $objEcommerce = new stdClass();
258 | $objEcommerce->ecommerce = new stdClass();
259 | $objEcommerce->ecommerce->detail = new stdClass();
260 | $objEcommerce->ecommerce->detail->actionField = new stdClass();
261 | $objEcommerce->ecommerce->detail->actionField->list = 'Catalog';
262 | $objEcommerce->ecommerce->detail->products = $objProduct;
263 |
264 | /*$objAddToCart = new stdClass();
265 | $objAddToCart->event = 'addToCart';
266 | $objAddToCart->ecommerce = new stdClass();
267 | $objAddToCart->ecommerce->add = new stdClass();
268 | $objAddToCart->ecommerce->add->products = $objProduct;*/
269 |
270 | $pageCategory = json_encode(array('pageCategory' => 'product-detail'), JSON_PRETTY_PRINT);
271 |
272 | $dataScript = PHP_EOL;
273 |
274 | $dataScript .= '';
275 |
276 | $dataScript .= PHP_EOL.PHP_EOL;
277 |
278 | $dataScript .= '';
279 |
280 | //$dataScript .= PHP_EOL.PHP_EOL;
281 |
282 | //$dataScript .= '';
283 |
284 | return $dataScript;
285 | }
286 | }
287 |
288 | public function getDataLayerOrder()
289 | {
290 | if ($order = $this->getOrder()) {
291 |
292 | $aItems = array();
293 | $productItems = array();
294 | foreach ($order->getAllVisibleItems() as $item) {
295 |
296 | $categoryCollection = $item->getProduct()->getCategoryCollection();
297 | $categories = array();
298 | foreach ($categoryCollection as $category) {
299 | $categories[] = $this->_categoryRepository->get($category->getEntityId())->getName();
300 | }
301 |
302 | $productItem = array();
303 | $productItem['name'] = $item->getName();
304 | $productItem['id'] = $item->getSku();
305 |
306 | //$productItem['price'] = $this->_currency->formatTxt($item->getBasePrice(), array('display' => \Magento\Framework\Currency::NO_SYMBOL));
307 | /**
308 | * Fix for price for different locale
309 | *
310 | * For example:
311 | * Price display of Dutch locale is the opposite of English locale
312 | * English locale price = 1,230.55
313 | * Dutch locale price = 1.230,55
314 | */
315 | $productItem['price'] = (string) $this->_locale->getNumber($item->getBasePrice(), array('display' => \Magento\Framework\Currency::NO_SYMBOL));
316 |
317 | $productItem['category'] = implode('|', $categories);
318 | $productItem['quantity'] = intval($item->getQtyOrdered()); // converting qty from decimal to integer
319 | $productItem['coupon'] = '';
320 | $productItems[] = (object) $productItem;
321 |
322 | $objItem = array();
323 | $objItem['sku'] = $item->getSku();
324 | $objItem['name'] = $item->getName();
325 | $objItem['category'] = implode('|', $categories);
326 |
327 | //$objItem['price'] = $this->_currency->formatTxt($item->getBasePrice(), array('display' => \Magento\Framework\Currency::NO_SYMBOL));
328 | /**
329 | * Fix for price for different locale
330 | *
331 | * For example:
332 | * Price display of Dutch locale is the opposite of English locale
333 | * English locale price = 1,230.55
334 | * Dutch locale price = 1.230,55
335 | */
336 | $objItem['price'] = (string) $this->_locale->getNumber($item->getBasePrice(), array('display' => \Magento\Framework\Currency::NO_SYMBOL));
337 |
338 | $objItem['quantity'] = intval($item->getQtyOrdered()); // converting qty from decimal to integer
339 | $aItems[] = (object) $objItem;
340 | }
341 |
342 | $objOrder = new stdClass();
343 |
344 | $objOrder->transactionId = $order->getIncrementId();
345 | $objOrder->transactionAffiliation = $this->_storeManager->getStore()->getFrontendName();
346 |
347 | //$objOrder->transactionTotal = $this->_currency->formatTxt($order->getBaseGrandTotal(), array('display' => \Magento\Framework\Currency::NO_SYMBOL));
348 | //$objOrder->transactionTax = $this->_currency->formatTxt($order->getBaseTaxAmount(), array('display' => \Magento\Framework\Currency::NO_SYMBOL));
349 | //$objOrder->transactionShipping = $this->_currency->formatTxt($order->getBaseShippingAmount(), array('display' => \Magento\Framework\Currency::NO_SYMBOL));
350 | /**
351 | * Fix for price for different locale
352 | */
353 | $objOrder->transactionTotal = (string) $this->_locale->getNumber($order->getBaseGrandTotal(), array('display' => \Magento\Framework\Currency::NO_SYMBOL));
354 | $objOrder->transactionTax = (string) $this->_locale->getNumber($order->getBaseTaxAmount(), array('display' => \Magento\Framework\Currency::NO_SYMBOL));
355 | $objOrder->transactionShipping = (string) $this->_locale->getNumber($order->getBaseShippingAmount(), array('display' => \Magento\Framework\Currency::NO_SYMBOL));
356 |
357 | $objOrder->transactionProducts = $aItems;
358 |
359 | $objOrder->ecommerce = new stdClass();
360 | $objOrder->ecommerce->purchase = new stdClass();
361 | $objOrder->ecommerce->purchase->actionField = new stdClass();
362 | $objOrder->ecommerce->purchase->actionField->id = $order->getIncrementId();
363 | $objOrder->ecommerce->purchase->actionField->affiliation = $this->_storeManager->getStore()->getFrontendName();
364 |
365 | //$objOrder->ecommerce->purchase->actionField->revenue = $this->_currency->formatTxt($order->getBaseGrandTotal(), array('display' => \Magento\Framework\Currency::NO_SYMBOL));
366 | //$objOrder->ecommerce->purchase->actionField->tax = $this->_currency->formatTxt($order->getBaseTaxAmount(), array('display' => \Magento\Framework\Currency::NO_SYMBOL));
367 | //$objOrder->ecommerce->purchase->actionField->shipping = $this->_currency->formatTxt($order->getBaseShippingAmount(), array('display' => \Magento\Framework\Currency::NO_SYMBOL));
368 | /**
369 | * Fix for price for different locale
370 | */
371 | $objOrder->ecommerce->purchase->actionField->revenue = (string) $this->_locale->getNumber($order->getBaseGrandTotal(), array('display' => \Magento\Framework\Currency::NO_SYMBOL));
372 | $objOrder->ecommerce->purchase->actionField->tax = (string) $this->_locale->getNumber($order->getBaseTaxAmount(), array('display' => \Magento\Framework\Currency::NO_SYMBOL));
373 | $objOrder->ecommerce->purchase->actionField->shipping = (string) $this->_locale->getNumber($order->getBaseShippingAmount(), array('display' => \Magento\Framework\Currency::NO_SYMBOL));
374 |
375 | $coupon = $order->getCouponCode();
376 | $objOrder->ecommerce->purchase->actionField->coupon = $coupon == null ? '' : $coupon;
377 |
378 | $objOrder->ecommerce->products = $productItems;
379 |
380 | $pageCategory = json_encode(array('pageCategory' => 'order-success'), JSON_PRETTY_PRINT);
381 |
382 | $dataScript = PHP_EOL;
383 |
384 | $dataScript .= '';
385 |
386 | $dataScript .= PHP_EOL.PHP_EOL;
387 |
388 | $dataScript .= '';
389 |
390 | return $dataScript;
391 | }
392 | }
393 | }
394 |
--------------------------------------------------------------------------------