Version Notes
All basic features included.
- It can handle full page caching.
- Exception handling has been added.
- Removed empty objects and arrays; Removed duplicated subcategories.
- Added product data for products on category and search pages.
- Fixed issue where configurable products have multiple product entries, and incorrect prices, in the cart object.
- Added more data into digitalData object so websites can be debugged.
- Configurable products have each of their configurations listed under 'linkedProduct'.
- Fixed bug that was breaking some styling.
- Added 'pageName' attribute and fixed type of 'returningStatus' object.
- Tweaks to configuration panel and default values.
- List of all installed non-Magento extensions are exposed (for debug purposes)
- Products associated with a Grouped Product have been included.
- Minimum prices of grouped and bundled products can be extracted.
- Output of debug data can now be controlled through admin configuration panel.
Release Info
Developer | Muhammed Miah |
Extension | W3CDigitalDataLayerByTriggeredMessaging |
Version | 0.3.3 |
Comparing to | |
See all releases |
Version 0.3.3
- app/code/community/TriggeredMessaging/DigitalDataLayer/Block/Ddl.php +7 -0
- app/code/community/TriggeredMessaging/DigitalDataLayer/Helper/Data.php +7 -0
- app/code/community/TriggeredMessaging/DigitalDataLayer/Model/Container/Ddl.php +14 -0
- app/code/community/TriggeredMessaging/DigitalDataLayer/Model/Observer.php +49 -0
- app/code/community/TriggeredMessaging/DigitalDataLayer/Model/Page/Observer.php +1047 -0
- app/code/community/TriggeredMessaging/DigitalDataLayer/etc/adminhtml.xml +27 -0
- app/code/community/TriggeredMessaging/DigitalDataLayer/etc/cache.xml +11 -0
- app/code/community/TriggeredMessaging/DigitalDataLayer/etc/config.xml +66 -0
- app/code/community/TriggeredMessaging/DigitalDataLayer/etc/system.xml +155 -0
- app/design/frontend/base/default/layout/triggeredmessaging/digital_data_layer.xml +13 -0
- app/design/frontend/base/default/template/triggeredmessaging/digital_data_layer.phtml +78 -0
- app/design/frontend/base/default/template/triggeredmessaging/digital_data_layer_after_content.phtml +58 -0
- app/etc/modules/TriggeredMessaging_DigitalDataLayer.xml +9 -0
- package.xml +37 -0
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TriggeredMessaging_DigitalDataLayer_Block_Ddl extends Mage_Core_Block_Template {
|
4 |
+
|
5 |
+
}
|
6 |
+
|
7 |
+
?>
|
@@ -0,0 +1,7 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TriggeredMessaging_DigitalDataLayer_Helper_Data extends Mage_Core_Helper_Abstract {
|
4 |
+
|
5 |
+
}
|
6 |
+
|
7 |
+
?>
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class TriggeredMessaging_DigitalDataLayer_Model_Container_Ddl extends Enterprise_PageCache_Model_Container_Advanced_Quote
|
3 |
+
{
|
4 |
+
/**
|
5 |
+
* Render block content
|
6 |
+
*
|
7 |
+
* @return string
|
8 |
+
*/
|
9 |
+
protected function _renderBlock()
|
10 |
+
{
|
11 |
+
$block = $this->_getPlaceHolderBlock();
|
12 |
+
return $block->toHtml();
|
13 |
+
}
|
14 |
+
}
|
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
class TriggeredMessaging_DigitalDataLayer_Model_Observer
|
3 |
+
{
|
4 |
+
/**
|
5 |
+
* Is Enabled Full Page Cache
|
6 |
+
*
|
7 |
+
* @var bool
|
8 |
+
*/
|
9 |
+
protected $_isEnabled;
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Class constructor
|
13 |
+
*/
|
14 |
+
public function __construct()
|
15 |
+
{
|
16 |
+
try {
|
17 |
+
$this->_isEnabled = Mage::app()->useCache('full_page');
|
18 |
+
} catch (Exception $e) {
|
19 |
+
}
|
20 |
+
}
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Check if full page cache is enabled
|
24 |
+
*
|
25 |
+
* @return bool
|
26 |
+
*/
|
27 |
+
public function isCacheEnabled()
|
28 |
+
{
|
29 |
+
return $this->_isEnabled;
|
30 |
+
}
|
31 |
+
/**
|
32 |
+
* Set cart hash in cookie on quote change
|
33 |
+
*
|
34 |
+
* @param Varien_Event_Observer $observer
|
35 |
+
* @return Enterprise_PageCache_Model_Observer
|
36 |
+
*/
|
37 |
+
public function registerQuoteChange(Varien_Event_Observer $observer)
|
38 |
+
{
|
39 |
+
if (!$this->isCacheEnabled()) {
|
40 |
+
return $this;
|
41 |
+
}
|
42 |
+
try {
|
43 |
+
$cacheId = TriggeredMessaging_DigitalDataLayer_Model_Container_Ddl::getCacheId();
|
44 |
+
Enterprise_PageCache_Model_Cache::getCacheInstance()->remove($cacheId);
|
45 |
+
} catch (Exception $e) {
|
46 |
+
}
|
47 |
+
return $this;
|
48 |
+
}
|
49 |
+
}
|
@@ -0,0 +1,1047 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
class TriggeredMessaging_DigitalDataLayer_Model_Page_Observer {
|
4 |
+
|
5 |
+
// Specification is at
|
6 |
+
// http://www.w3.org/2013/12/ceddl-201312.pdf
|
7 |
+
protected $_version = "1.0";
|
8 |
+
protected $_user = null;
|
9 |
+
protected $_page = null;
|
10 |
+
protected $_cart = null;
|
11 |
+
protected $_product = null;
|
12 |
+
protected $_search = null;
|
13 |
+
protected $_transaction = null;
|
14 |
+
protected $_listing = null;
|
15 |
+
protected $_events = array();
|
16 |
+
|
17 |
+
protected $_debug = false;
|
18 |
+
|
19 |
+
protected function _getRequest() {
|
20 |
+
return Mage::app()->getFrontController()->getRequest();
|
21 |
+
}
|
22 |
+
|
23 |
+
/*
|
24 |
+
* Returns Controller Name
|
25 |
+
*/
|
26 |
+
protected function _getControllerName() {
|
27 |
+
return $this->_getRequest()->getControllerName();
|
28 |
+
}
|
29 |
+
|
30 |
+
protected function _getActionName() {
|
31 |
+
return $this->_getRequest()->getActionName();
|
32 |
+
}
|
33 |
+
|
34 |
+
protected function _getModuleName() {
|
35 |
+
return $this->_getRequest()->getModuleName();
|
36 |
+
}
|
37 |
+
|
38 |
+
protected function _getRouteName() {
|
39 |
+
return $this->_getRequest()->getRouteName();
|
40 |
+
}
|
41 |
+
|
42 |
+
protected function _getCustomer() {
|
43 |
+
return Mage::helper('customer')->getCustomer();
|
44 |
+
}
|
45 |
+
|
46 |
+
protected function _getBreadcrumb() {
|
47 |
+
return Mage::helper('catalog')->getBreadcrumbPath();
|
48 |
+
}
|
49 |
+
|
50 |
+
protected function _getCategory($category_id) {
|
51 |
+
return Mage::getModel('catalog/category')->load($category_id);
|
52 |
+
}
|
53 |
+
|
54 |
+
protected function _getCurrentProduct() {
|
55 |
+
return Mage::registry('current_product');
|
56 |
+
}
|
57 |
+
|
58 |
+
protected function _getProduct($productId) {
|
59 |
+
return Mage::getModel('catalog/product')->load($productId);
|
60 |
+
}
|
61 |
+
|
62 |
+
protected function _getCurrentCategory() {
|
63 |
+
return Mage::registry('current_category');
|
64 |
+
}
|
65 |
+
|
66 |
+
protected function _getCatalogSearch() {
|
67 |
+
return Mage::getSingleton('catalogsearch/advanced');
|
68 |
+
}
|
69 |
+
|
70 |
+
protected function _getCheckoutSession() {
|
71 |
+
return Mage::getSingleton('checkout/session');
|
72 |
+
}
|
73 |
+
|
74 |
+
protected function _getSalesOrder() {
|
75 |
+
return Mage::getModel('sales/order');
|
76 |
+
}
|
77 |
+
|
78 |
+
protected function _getOrderAddress() {
|
79 |
+
return Mage::getModel('sales/order_address');
|
80 |
+
}
|
81 |
+
|
82 |
+
/*
|
83 |
+
* Determine which page type we're on
|
84 |
+
*/
|
85 |
+
|
86 |
+
public function _isHome() {
|
87 |
+
if (Mage::app()->getRequest()->getRequestString() == "/") {
|
88 |
+
return true;
|
89 |
+
} else {
|
90 |
+
return false;
|
91 |
+
}
|
92 |
+
}
|
93 |
+
|
94 |
+
public function _isContent() {
|
95 |
+
if ($this->_getModuleName() == 'cms') {
|
96 |
+
return true;
|
97 |
+
} else {
|
98 |
+
return false;
|
99 |
+
}
|
100 |
+
}
|
101 |
+
|
102 |
+
public function _isCategory() {
|
103 |
+
if ($this->_getControllerName() == 'category') {
|
104 |
+
return true;
|
105 |
+
} else {
|
106 |
+
return false;
|
107 |
+
}
|
108 |
+
}
|
109 |
+
|
110 |
+
public function _isSearch() {
|
111 |
+
if ($this->_getModuleName() == 'catalogsearch') {
|
112 |
+
return true;
|
113 |
+
} else {
|
114 |
+
return false;
|
115 |
+
}
|
116 |
+
}
|
117 |
+
|
118 |
+
public function _isProduct() {
|
119 |
+
$onCatalog = false;
|
120 |
+
if(Mage::registry('current_product')) {
|
121 |
+
$onCatalog = true;
|
122 |
+
}
|
123 |
+
return $onCatalog;
|
124 |
+
}
|
125 |
+
|
126 |
+
public function _isCart() {
|
127 |
+
try {
|
128 |
+
$request = $this->_getRequest();
|
129 |
+
$module = $request->getModuleName();
|
130 |
+
$controller = $request->getControllerName();
|
131 |
+
$action = $request->getActionName();
|
132 |
+
if ($module == 'checkout' && $controller == 'cart' && $action == 'index') {
|
133 |
+
return true;
|
134 |
+
}
|
135 |
+
} catch (Exception $e) {
|
136 |
+
}
|
137 |
+
|
138 |
+
return false;
|
139 |
+
}
|
140 |
+
|
141 |
+
public function _isCheckout() {
|
142 |
+
if (strpos($this->_getModuleName(), 'checkout') !== false && $this->_getActionName() != 'success') {
|
143 |
+
return true;
|
144 |
+
} else {
|
145 |
+
return false;
|
146 |
+
}
|
147 |
+
}
|
148 |
+
|
149 |
+
public function _isConfirmation() {
|
150 |
+
// default controllerName is "onepage"
|
151 |
+
// relax the check, only check if it contains checkout
|
152 |
+
// some checkout systems have different prefix/postfix,
|
153 |
+
// but all contain checkout
|
154 |
+
if (strpos($this->_getModuleName(), 'checkout') !== false && $this->_getActionName() == "success") {
|
155 |
+
return true;
|
156 |
+
} else {
|
157 |
+
return false;
|
158 |
+
}
|
159 |
+
}
|
160 |
+
|
161 |
+
|
162 |
+
/*
|
163 |
+
* Get information on pages to pass to front end
|
164 |
+
*/
|
165 |
+
|
166 |
+
public function getVersion() {
|
167 |
+
return $this->_version;
|
168 |
+
}
|
169 |
+
|
170 |
+
public function getPurchaseCompleteQs() {
|
171 |
+
|
172 |
+
$orderId = $this->_getCheckoutSession()->getLastOrderId();
|
173 |
+
if ($orderId) {
|
174 |
+
$order = $this->_getSalesOrder()->load($orderId);
|
175 |
+
$email = $order->getCustomerEmail();
|
176 |
+
}else{
|
177 |
+
$email = $user->getEmail();
|
178 |
+
}
|
179 |
+
$qs = "e=" . urlencode($email);
|
180 |
+
|
181 |
+
if($orderId){
|
182 |
+
$qs = $qs . "&r=" . urlencode($orderId);
|
183 |
+
}
|
184 |
+
|
185 |
+
return $qs;
|
186 |
+
}
|
187 |
+
|
188 |
+
public function getUser() {
|
189 |
+
return $this->_user;
|
190 |
+
}
|
191 |
+
|
192 |
+
public function getPage() {
|
193 |
+
return $this->_page;
|
194 |
+
}
|
195 |
+
|
196 |
+
public function getProduct() {
|
197 |
+
return $this->_product;
|
198 |
+
}
|
199 |
+
|
200 |
+
public function getCart() {
|
201 |
+
return $this->_cart;
|
202 |
+
}
|
203 |
+
|
204 |
+
public function getTransaction() {
|
205 |
+
return $this->_transaction;
|
206 |
+
}
|
207 |
+
|
208 |
+
public function getListing() {
|
209 |
+
return $this->_listing;
|
210 |
+
}
|
211 |
+
|
212 |
+
public function getEvents() {
|
213 |
+
return array();
|
214 |
+
}
|
215 |
+
|
216 |
+
|
217 |
+
/*
|
218 |
+
* Set the model attributes to be passed front end
|
219 |
+
*/
|
220 |
+
|
221 |
+
public function _getPageType() {
|
222 |
+
try {
|
223 |
+
if ($this->_isHome()) {
|
224 |
+
return 'home';
|
225 |
+
} elseif ($this->_isContent()) {
|
226 |
+
return 'content';
|
227 |
+
} elseif ($this->_isCategory()) {
|
228 |
+
return 'category';
|
229 |
+
} elseif ($this->_isSearch()) {
|
230 |
+
return 'search';
|
231 |
+
} elseif ($this->_isProduct()) {
|
232 |
+
return 'product';
|
233 |
+
} elseif ($this->_isCart()) {
|
234 |
+
return 'basket';
|
235 |
+
} elseif ($this->_isCheckout()) {
|
236 |
+
return 'checkout';
|
237 |
+
} elseif ($this->_isConfirmation()) {
|
238 |
+
return 'confirmation';
|
239 |
+
} else {
|
240 |
+
return $this->_getModuleName();
|
241 |
+
}
|
242 |
+
} catch (Exception $e) {
|
243 |
+
}
|
244 |
+
}
|
245 |
+
|
246 |
+
public function _getPageBreadcrumb() {
|
247 |
+
$arr = $this->_getBreadcrumb();
|
248 |
+
$breadcrumb = array();
|
249 |
+
|
250 |
+
try {
|
251 |
+
foreach ($arr as $category) {
|
252 |
+
$breadcrumb[] = $category['label'];
|
253 |
+
}
|
254 |
+
} catch (Exception $e) {
|
255 |
+
}
|
256 |
+
|
257 |
+
return $breadcrumb;
|
258 |
+
}
|
259 |
+
|
260 |
+
public function _setPage() {
|
261 |
+
/*
|
262 |
+
Section 6.3 of http://www.w3.org/2013/12/ceddl-201312.pdf
|
263 |
+
page: {
|
264 |
+
pageInfo: {
|
265 |
+
pageID: "Great Winter Run 2015",
|
266 |
+
destinationURL: "http://www.greatrun.org/Events/Event.aspx?id=2"},
|
267 |
+
category: {
|
268 |
+
primaryCategory: "Cameras",
|
269 |
+
subCategory1: "Nikon",
|
270 |
+
pageType: "product"
|
271 |
+
}
|
272 |
+
*/
|
273 |
+
|
274 |
+
try {
|
275 |
+
$this->_page = array();
|
276 |
+
|
277 |
+
$this->_page['pageInfo'] = array();
|
278 |
+
// $this->_page['pageInfo']['pageID']
|
279 |
+
// $this->_page['pageInfo']['pageName']
|
280 |
+
$this->_page['pageInfo']['destinationURL'] = Mage::helper('core/url')->getCurrentUrl();
|
281 |
+
$referringURL = Mage::app()->getRequest()->getServer('HTTP_REFERER');
|
282 |
+
if ($referringURL) {
|
283 |
+
$this->_page['pageInfo']['referringURL'] = $referringURL;
|
284 |
+
}
|
285 |
+
// $this->_page['pageInfo']['sysEnv']
|
286 |
+
// $this->_page['pageInfo']['variant']
|
287 |
+
if ($this->_getPageBreadcrumb()) {
|
288 |
+
$this->_page['pageInfo']['breadcrumbs'] = $this->_getPageBreadcrumb();
|
289 |
+
}
|
290 |
+
// $this->_page['pageInfo']['author']
|
291 |
+
// $this->_page['pageInfo']['issueDate']
|
292 |
+
// $this->_page['pageInfo']['effectiveDate']
|
293 |
+
// $this->_page['pageInfo']['expiryDate']
|
294 |
+
$this->_page['pageInfo']['language'] = Mage::app()->getLocale()->getLocaleCode();
|
295 |
+
// $this->_page['pageInfo']['geoRegion']
|
296 |
+
// $this->_page['pageInfo']['industryCodes']
|
297 |
+
// $this->_page['pageInfo']['publisher']
|
298 |
+
|
299 |
+
$this->_page['category'] = array();
|
300 |
+
if (Mage::registry('current_category')) {
|
301 |
+
// There must be a better way than this
|
302 |
+
$this->_page['category']['primaryCategory'] = Mage::registry('current_category')->getName();
|
303 |
+
}
|
304 |
+
// $this->_page['category']['subCategory1'];
|
305 |
+
$this->_page['category']['pageType'] = $this->_getPageType();
|
306 |
+
|
307 |
+
// $this->_page['attributes'] = array();
|
308 |
+
|
309 |
+
if ($this->_debug) {
|
310 |
+
$modules = (array)Mage::getConfig()->getNode('modules')->children();
|
311 |
+
$mods = array();
|
312 |
+
foreach ($modules as $key => $value) {
|
313 |
+
if (strpos($key, 'Mage_')===false) {
|
314 |
+
$mods[] = $key;
|
315 |
+
|
316 |
+
}
|
317 |
+
}
|
318 |
+
$this->_page['extra_modules'] = $mods;
|
319 |
+
}
|
320 |
+
|
321 |
+
} catch (Exception $e) {
|
322 |
+
}
|
323 |
+
}
|
324 |
+
|
325 |
+
// Set the user info
|
326 |
+
public function _setUser() {
|
327 |
+
// Section 6.9 of http://www.w3.org/2013/12/ceddl-201312.pdf
|
328 |
+
|
329 |
+
try {
|
330 |
+
$this->_user = array();
|
331 |
+
$user = $this->_getCustomer();
|
332 |
+
$user_id = $user->getEntityId();
|
333 |
+
$firstName = $user->getFirstname();
|
334 |
+
$lastName = $user->getLastname();
|
335 |
+
|
336 |
+
if ($this->_isConfirmation()) {
|
337 |
+
$orderId = $this->_getCheckoutSession()->getLastOrderId();
|
338 |
+
if ($orderId) {
|
339 |
+
$order = $this->_getSalesOrder()->load($orderId);
|
340 |
+
$email = $order->getCustomerEmail();
|
341 |
+
}
|
342 |
+
} else {
|
343 |
+
$email = $user->getEmail();
|
344 |
+
}
|
345 |
+
|
346 |
+
// $this->_user['segment'] = array();
|
347 |
+
$this->_user['profile'] = array();
|
348 |
+
|
349 |
+
$profile = array();
|
350 |
+
|
351 |
+
$profile['profileInfo'] = array();
|
352 |
+
if ($user_id) {
|
353 |
+
$profile['profileInfo']['profileID'] = (string) $user_id;
|
354 |
+
}
|
355 |
+
if ($firstName){
|
356 |
+
$profile['profileInfo']['userFirstName'] = $firstName;
|
357 |
+
}
|
358 |
+
if ($lastName){
|
359 |
+
$profile['profileInfo']['userLastName'] = $lastName;
|
360 |
+
}
|
361 |
+
if ($email) {
|
362 |
+
$profile['profileInfo']['email'] = $email;
|
363 |
+
}
|
364 |
+
$profile['profileInfo']['language'] = Mage::getStoreConfig('general/locale/code', Mage::app()->getStore()->getId());
|
365 |
+
$profile['profileInfo']['returningStatus'] = $user_id ? 'true' : 'false';
|
366 |
+
// $profile['profileInfo']['type'];
|
367 |
+
|
368 |
+
// $profile['address'] = array();
|
369 |
+
// $profile['address']['line1'];
|
370 |
+
// $profile['address']['line2'];
|
371 |
+
// $profile['address']['city'];
|
372 |
+
// $profile['address']['stateProvince'];
|
373 |
+
// $profile['address']['postalCode'];
|
374 |
+
// $profile['address']['country'];
|
375 |
+
|
376 |
+
// $profile['social'] = array();
|
377 |
+
// $profile['attributes'] = array();
|
378 |
+
|
379 |
+
array_push($this->_user['profile'], $profile);
|
380 |
+
} catch (Exception $e) {
|
381 |
+
}
|
382 |
+
}
|
383 |
+
|
384 |
+
public function _getAddress($address) {
|
385 |
+
/*
|
386 |
+
address: {
|
387 |
+
line1: "",
|
388 |
+
line2: "",
|
389 |
+
city: "",
|
390 |
+
stateProvince: "",
|
391 |
+
postalCode: "",
|
392 |
+
country: ""
|
393 |
+
},
|
394 |
+
*/
|
395 |
+
|
396 |
+
$billing = array();
|
397 |
+
|
398 |
+
try {
|
399 |
+
if ($address) {
|
400 |
+
$billing['line1'] = $address->getName();
|
401 |
+
$billing['line2'] = $address->getStreetFull();
|
402 |
+
$billing['city'] = $address->getCity();
|
403 |
+
$billing['postalCode'] = $address->getPostcode();
|
404 |
+
$billing['country'] = $address->getCountry();
|
405 |
+
$state = $address->getRegion();
|
406 |
+
$billing['stateProvince'] = $state ? $state : '';
|
407 |
+
}
|
408 |
+
} catch (Exception $e) {
|
409 |
+
}
|
410 |
+
|
411 |
+
return $billing;
|
412 |
+
}
|
413 |
+
|
414 |
+
public function _getProductStock($product) {
|
415 |
+
return (int) Mage::getModel('cataloginventory/stock_item')->loadByProduct($product)->getQty();
|
416 |
+
}
|
417 |
+
|
418 |
+
public function _getCurrency() {
|
419 |
+
return Mage::app()->getStore()->getCurrentCurrencyCode();
|
420 |
+
}
|
421 |
+
|
422 |
+
public function _getProductModel($product) {
|
423 |
+
/*
|
424 |
+
Section 6.4 of http://www.w3.org/2013/12/ceddl-201312.pdf
|
425 |
+
product: [
|
426 |
+
{
|
427 |
+
productInfo: {
|
428 |
+
productID: "greatwinterrun2015", // Unique product ID
|
429 |
+
productName: "Great Winter Run",
|
430 |
+
description: "Running, in the winter, in Edinburgh",
|
431 |
+
productURL: "http://www.greatrun.org/Events/Event.aspx?id=2",
|
432 |
+
productImage: "http://www.greatrun.org/Events/App_Images/slideshow/cropped/saved/gwir_01f0a780d94.jpg",
|
433 |
+
productThumbnail: "http://www.greatrun.org/App_Images/2011/Events/logo_GWIR.jpg"
|
434 |
+
},
|
435 |
+
category: {
|
436 |
+
primaryCategory: "Somecategory",
|
437 |
+
subCategory1: "Subcat"
|
438 |
+
},
|
439 |
+
attributes: {
|
440 |
+
distance: 5000,
|
441 |
+
country: "Scotland",
|
442 |
+
date: "2015-01-11", // Dates in ISO 8601
|
443 |
+
city: "Edinburgh" // You can put any extended data you want passing through in attributes
|
444 |
+
},
|
445 |
+
price: {
|
446 |
+
basePrice: 40.00,
|
447 |
+
currency: "GBP",
|
448 |
+
taxRate: 0.2,
|
449 |
+
priceWithTax: 48.00
|
450 |
+
}
|
451 |
+
}
|
452 |
+
]
|
453 |
+
*/
|
454 |
+
|
455 |
+
$product_model = array();
|
456 |
+
|
457 |
+
try {
|
458 |
+
// Product Info
|
459 |
+
$product_model['productInfo'] = array();
|
460 |
+
$product_model['productInfo']['productID'] = $product->getId();
|
461 |
+
$product_model['productInfo']['productName'] = $product->getName();
|
462 |
+
$product_model['productInfo']['description'] = strip_tags($product->getShortDescription());
|
463 |
+
$product_model['productInfo']['productURL'] = $product->getProductUrl();
|
464 |
+
|
465 |
+
//Check if images contain placeholders
|
466 |
+
if(!($product->getImage()=="no_selection")){
|
467 |
+
$product_model['productInfo']['productImage'] = $product->getImageUrl();
|
468 |
+
}
|
469 |
+
if(!($product->getThumbnail()=="no_selection")){
|
470 |
+
$product_model['productInfo']['productThumbnail'] = $product->getThumbnailUrl();
|
471 |
+
}
|
472 |
+
// $product_model['productInfo']['manufacturer'];
|
473 |
+
if ($product->getWeight()) {
|
474 |
+
$product_model['productInfo']['size'] = $product->getWeight();
|
475 |
+
}
|
476 |
+
|
477 |
+
// Category
|
478 |
+
$categories = $this->_getProductCategories($product);
|
479 |
+
if (isset($categories[0])||isset($categories[1])||isset($categories[2])) {
|
480 |
+
$product_model['category'] = array();
|
481 |
+
|
482 |
+
if (isset($categories[0])) {
|
483 |
+
$product_model['category']['primaryCategory'] = $categories[0];
|
484 |
+
}
|
485 |
+
if (isset($categories[1])) {
|
486 |
+
$product_model['category']['subCategory1'] = $categories[1];
|
487 |
+
|
488 |
+
// Delete if subcategory is a duplicate of the primary category
|
489 |
+
if (isset($categories[0]) && $categories[0]===$categories[1]) {
|
490 |
+
unset( $product_model['category']['subCategory1'] );
|
491 |
+
}
|
492 |
+
}
|
493 |
+
if (isset($categories[2])) {
|
494 |
+
$product_model['category']['subCategory2'] = $categories[2];
|
495 |
+
|
496 |
+
// Delete if subcategory is a duplicate of previous subcategory
|
497 |
+
if (isset($categories[1]) && $categories[1]===$categories[2]) {
|
498 |
+
unset( $product_model['category']['subCategory2'] );
|
499 |
+
}
|
500 |
+
}
|
501 |
+
|
502 |
+
// $product_model['category']['productType'];
|
503 |
+
}
|
504 |
+
|
505 |
+
// Price
|
506 |
+
$product_model['price'] = array();
|
507 |
+
$product_model['price']['basePrice'] = floatval($product->getPrice());
|
508 |
+
$product_model['price']['currency'] = $this->_getCurrency();
|
509 |
+
$product_model['price']['priceWithTax'] = floatval($product->getFinalPrice()); // May be lower due to discounts! TODO
|
510 |
+
|
511 |
+
if (!$product_model['price']['priceWithTax']) {
|
512 |
+
unset( $product_model['price']['priceWithTax'] );
|
513 |
+
}
|
514 |
+
|
515 |
+
// In case 'basePrice' did not exist
|
516 |
+
if (!$product_model['price']['basePrice']) {
|
517 |
+
$product_model['price']['basePrice'] = floatval($product->getGroupPrice());
|
518 |
+
}
|
519 |
+
if (!$product_model['price']['basePrice']) {
|
520 |
+
$product_model['price']['basePrice'] = floatval($product->getMinimalPrice());
|
521 |
+
}
|
522 |
+
if (!$product_model['price']['basePrice']) {
|
523 |
+
$product_model['price']['basePrice'] = floatval($product->getSpecialPrice());
|
524 |
+
}
|
525 |
+
if (!$product_model['price']['basePrice']) {
|
526 |
+
// Extract price for bundle products
|
527 |
+
$price_model = $product->getPriceModel();
|
528 |
+
if (method_exists($price_model, 'getOptions')) {
|
529 |
+
$normal_price = 0.0;
|
530 |
+
$_options = $price_model->getOptions($product);
|
531 |
+
foreach($_options as $_option) {
|
532 |
+
if (!method_exists($_option, 'getDefaultSelection')) {
|
533 |
+
break;
|
534 |
+
}
|
535 |
+
$_selection = $_option->getDefaultSelection();
|
536 |
+
if ($_selection === null) continue;
|
537 |
+
$normal_price += floatval($_selection->getPrice());
|
538 |
+
}
|
539 |
+
$product_model['price']['basePrice'] = $normal_price;
|
540 |
+
}
|
541 |
+
}
|
542 |
+
|
543 |
+
if ($this->_debug) {
|
544 |
+
$product_model['price']['all'] = array();
|
545 |
+
$product_model['price']['all']['getPrice'] = $product->getPrice();
|
546 |
+
$product_model['price']['all']['getMinimalPrice'] = $product->getMinimalPrice();
|
547 |
+
$product_model['price']['all']['getPriceModel'] = $product->getPriceModel();
|
548 |
+
$product_model['price']['all']['getGroupPrice'] = $product->getGroupPrice();
|
549 |
+
$product_model['price']['all']['getTierPrice'] = $product->getTierPrice();
|
550 |
+
$product_model['price']['all']['getTierPriceCount'] = $product->getTierPriceCount();
|
551 |
+
$product_model['price']['all']['getFormatedTierPrice'] = $product->getFormatedTierPrice();
|
552 |
+
$product_model['price']['all']['getFormatedPrice'] = $product->getFormatedPrice();
|
553 |
+
$product_model['price']['all']['getFinalPrice'] = $product->getFinalPrice();
|
554 |
+
$product_model['price']['all']['getCalculatedFinalPrice'] = $product->getCalculatedFinalPrice();
|
555 |
+
$product_model['price']['all']['getSpecialPrice'] = $product->getSpecialPrice();
|
556 |
+
}
|
557 |
+
|
558 |
+
// Calculate Tax Rate
|
559 |
+
$store = Mage::app()->getStore('default');
|
560 |
+
$taxCalculation = Mage::getModel('tax/calculation');
|
561 |
+
$request = $taxCalculation->getRateRequest(null, null, null, $store);
|
562 |
+
$taxClassId = $product->getTaxClassId();
|
563 |
+
$percent = $taxCalculation->getRate($request->setProductClassId($taxClassId));
|
564 |
+
$product_model['price']['taxRate'] = ((float) $percent) / 100;
|
565 |
+
|
566 |
+
// For configurable/grouped/composite products, add all associated products to 'linkedProduct'
|
567 |
+
if ($product->isConfigurable() || $product->isGrouped() || $product->isComposite()) {
|
568 |
+
|
569 |
+
$product_model['linkedProduct'] = array();
|
570 |
+
$simple_collection = array();
|
571 |
+
|
572 |
+
// Add simple products related to configurable products
|
573 |
+
if ($product->isConfigurable()) {
|
574 |
+
$conf = Mage::getModel('catalog/product_type_configurable')->setProduct($product);
|
575 |
+
$simple_collection = $conf->getUsedProductCollection()->addAttributeToSelect('*')->addFilterByRequiredOptions();
|
576 |
+
}
|
577 |
+
else {
|
578 |
+
$type_instance = $product->getTypeInstance(true);
|
579 |
+
if (method_exists($type_instance, 'getSelectionsCollection')) {
|
580 |
+
// Add simple products related to bundle products
|
581 |
+
$simple_collection = $type_instance->getSelectionsCollection(
|
582 |
+
$type_instance->getOptionsIds($product), $product
|
583 |
+
);
|
584 |
+
} else if (method_exists($type_instance, 'getAssociatedProducts')) {
|
585 |
+
// Add simple products related to grouped products
|
586 |
+
$simple_collection = $type_instance->getAssociatedProducts($product);
|
587 |
+
}
|
588 |
+
}
|
589 |
+
|
590 |
+
// Add related products to the data layer
|
591 |
+
$min_price = 0.0;
|
592 |
+
foreach($simple_collection as $simple_product){
|
593 |
+
array_push($product_model['linkedProduct'], $this->_getProductModel($simple_product));
|
594 |
+
$simple_product_price = floatval($simple_product->getPrice());
|
595 |
+
if ($simple_product_price && (!$min_price || $simple_product_price<$min_price)) {
|
596 |
+
$min_price = $simple_product_price;
|
597 |
+
}
|
598 |
+
}
|
599 |
+
|
600 |
+
// If price could not be extracted before, can set it now
|
601 |
+
if (!$product_model['price']['basePrice']) {
|
602 |
+
$product_model['price']['basePrice'] = floatval($min_price);
|
603 |
+
}
|
604 |
+
|
605 |
+
if (!$product_model['linkedProduct']) {
|
606 |
+
unset($product_model['linkedProduct']);
|
607 |
+
}
|
608 |
+
}
|
609 |
+
|
610 |
+
if ($this->_debug) {
|
611 |
+
$product_model['more']['isConfigurable'] = $product->isConfigurable();
|
612 |
+
$product_model['more']['isSuperGroup'] = $product->isSuperGroup();
|
613 |
+
$product_model['more']['isSuperConfig'] = $product->isSuperConfig();
|
614 |
+
$product_model['more']['isGrouped'] = $product->isGrouped();
|
615 |
+
$product_model['more']['isSuper'] = $product->isSuper();
|
616 |
+
$product_model['more']['isVirtual'] = $product->isVirtual();
|
617 |
+
$product_model['more']['isRecurring'] = $product->isRecurring();
|
618 |
+
$product_model['more']['isComposite'] = $product->isComposite();
|
619 |
+
$product_model['more']['getTypeId'] = $product->getTypeId();
|
620 |
+
}
|
621 |
+
|
622 |
+
// Other
|
623 |
+
// $product_model['attributes'] = array();
|
624 |
+
|
625 |
+
// The following are not used in W3C DDL but exist in Universal Variable:
|
626 |
+
// $product_model['sku_code'] = $product->getSku();
|
627 |
+
// $product_model['stock'] = (int) $this->_getProductStock($product);
|
628 |
+
} catch (Exception $e) {
|
629 |
+
}
|
630 |
+
|
631 |
+
return $product_model;
|
632 |
+
}
|
633 |
+
|
634 |
+
public function _getProductCategories($product) {
|
635 |
+
try {
|
636 |
+
$cats = $product->getCategoryIds();
|
637 |
+
if ($cats) {
|
638 |
+
$category_names = array();
|
639 |
+
foreach ($cats as $category_id) {
|
640 |
+
$_cat = $this->_getCategory($category_id);
|
641 |
+
$category_names[] = $_cat->getName();
|
642 |
+
}
|
643 |
+
return $category_names;
|
644 |
+
}
|
645 |
+
} catch (Exception $e) {
|
646 |
+
}
|
647 |
+
|
648 |
+
return false;
|
649 |
+
}
|
650 |
+
|
651 |
+
public function _getLineItems($items, $page_type) {
|
652 |
+
/*
|
653 |
+
item: [
|
654 |
+
{
|
655 |
+
productInfo: {
|
656 |
+
productID: "greatwinterrun2015", // Unique product ID - links the prod in the cart to the one browsed
|
657 |
+
// If data isn't available on the cart page, as long as the productID is present, it will be filled
|
658 |
+
// out from our product database (e.g. name, images, category, extra attributes, price)
|
659 |
+
productName: "Great Winter Run",
|
660 |
+
description: "Running, in the winter, in Edinburgh",
|
661 |
+
productURL: "http://www.greatrun.org/Events/Event.aspx?id=2",
|
662 |
+
productImage: "http://www.greatrun.org/Events/App_Images/slideshow/cropped/saved/gwir_01f0a780d94.jpg",
|
663 |
+
productThumbnail: "http://www.greatrun.org/App_Images/2011/Events/logo_GWIR.jpg"
|
664 |
+
},
|
665 |
+
category: {
|
666 |
+
primaryCategory: "Somecategory",
|
667 |
+
subCategory1: "Subcat"
|
668 |
+
},
|
669 |
+
attributes: {
|
670 |
+
distance: 5000,
|
671 |
+
country: "Scotland",
|
672 |
+
date: "2015-01-11", // Dates in ISO 8601
|
673 |
+
city: "Edinburgh" // You can put any extended data you want passing through in attributes
|
674 |
+
},
|
675 |
+
price: {
|
676 |
+
basePrice: 40.00,
|
677 |
+
currency: "GBP",
|
678 |
+
taxRate: 0.2,
|
679 |
+
priceWithTax: 48.00
|
680 |
+
}
|
681 |
+
}
|
682 |
+
]
|
683 |
+
*/
|
684 |
+
|
685 |
+
$line_items = array();
|
686 |
+
|
687 |
+
try {
|
688 |
+
foreach($items as $item) {
|
689 |
+
$productId = $item->getProductId();
|
690 |
+
$product = $this->_getProduct($productId);
|
691 |
+
// product needs to be visible
|
692 |
+
if ($product->isVisibleInSiteVisibility()) {
|
693 |
+
|
694 |
+
$litem_model = $this->_getProductModel($product);
|
695 |
+
|
696 |
+
if ($page_type == 'cart') {
|
697 |
+
$litem_model['quantity'] = floatval($item->getQty());
|
698 |
+
} else {
|
699 |
+
$litem_model['quantity'] = floatval($item->getQtyOrdered());
|
700 |
+
}
|
701 |
+
|
702 |
+
if (!is_array($litem_model['price'])) {
|
703 |
+
$litem_model['price'] = array();
|
704 |
+
}
|
705 |
+
if ($item->getCouponCode()) {
|
706 |
+
$litem_model['price']['voucherCode'] = $item->getCouponCode();
|
707 |
+
}
|
708 |
+
if ($item->getDiscountAmount()) {
|
709 |
+
$litem_model['price']['voucherDiscount'] = abs(floatval($item->getDiscountAmount()));
|
710 |
+
}
|
711 |
+
// $litem_model['price']['shipping'];
|
712 |
+
// $litem_model['price']['shippingMethod'] = $this->_extractShippingMethod($item->getQuote());
|
713 |
+
$litem_model['price']['priceWithTax'] = floatval($item->getBasePriceInclTax()); // TODO: This may be different from that in _getProductModel()
|
714 |
+
$litem_model['price']['cartTotal'] = floatval($item->getRowTotalInclTax());
|
715 |
+
|
716 |
+
if ($this->_debug) {
|
717 |
+
$litem_model['price']['all']['_getCalculationPrice'] = $product->getCalculationPrice();
|
718 |
+
$litem_model['price']['all']['_getCalculationPriceOriginal'] = $product->getCalculationPriceOriginal();
|
719 |
+
$litem_model['price']['all']['_getBaseCalculationPrice'] = $product->getBaseCalculationPrice();
|
720 |
+
$litem_model['price']['all']['_getBaseCalculationPriceOriginal'] = $product->getBaseCalculationPriceOriginal();
|
721 |
+
$litem_model['price']['all']['_getOriginalPrice'] = $product->getOriginalPrice();
|
722 |
+
$litem_model['price']['all']['_getBaseOriginalPrice'] = $product->getBaseOriginalPrice();
|
723 |
+
$litem_model['price']['all']['_getConvertedPrice'] = $product->getConvertedPrice();
|
724 |
+
}
|
725 |
+
|
726 |
+
// $litem_model['linkedProduct'] = array();
|
727 |
+
// $litem_model['attributes'] = array();
|
728 |
+
|
729 |
+
array_push($line_items, $litem_model);
|
730 |
+
}
|
731 |
+
}
|
732 |
+
} catch (Exception $e) {
|
733 |
+
}
|
734 |
+
|
735 |
+
return $line_items;
|
736 |
+
}
|
737 |
+
|
738 |
+
public function _setListing() {
|
739 |
+
try {
|
740 |
+
$this->_listing = array();
|
741 |
+
if ($this->_isCategory()) {
|
742 |
+
$category = $this->_getCurrentCategory();
|
743 |
+
} elseif ($this->_isSearch()) {
|
744 |
+
$category = $this->_getCatalogSearch();
|
745 |
+
if (isset($_GET['q'])) {
|
746 |
+
$this->_listing['query'] = $_GET['q'];
|
747 |
+
}
|
748 |
+
}
|
749 |
+
|
750 |
+
// Note: data on products are retrieved later, after the content layout block,
|
751 |
+
// since the product list is compiled then.
|
752 |
+
} catch (Exception $e) {
|
753 |
+
}
|
754 |
+
}
|
755 |
+
|
756 |
+
public function _setProduct() {
|
757 |
+
try {
|
758 |
+
$product = $this->_getCurrentProduct();
|
759 |
+
if (!$product) return false;
|
760 |
+
$this->_product = array();
|
761 |
+
array_push($this->_product, $this->_getProductModel($product));
|
762 |
+
} catch (Exception $e) {
|
763 |
+
}
|
764 |
+
}
|
765 |
+
|
766 |
+
public function _setCart() {
|
767 |
+
/*
|
768 |
+
Section 6.5 of http://www.w3.org/2013/12/ceddl-201312.pdf
|
769 |
+
cart: {
|
770 |
+
price: {
|
771 |
+
basePrice: 40.00,
|
772 |
+
currency: "GBP",
|
773 |
+
taxRate: 0.2,
|
774 |
+
cartTotal: 48.00
|
775 |
+
},
|
776 |
+
item: [
|
777 |
+
{
|
778 |
+
productInfo: {
|
779 |
+
productID: "greatwinterrun2015", // Unique product ID - links the prod in the cart to the one browsed
|
780 |
+
// If data isn't available on the cart page, as long as the productID is present, it will be filled
|
781 |
+
// out from our product database (e.g. name, images, category, extra attributes, price)
|
782 |
+
productName: "Great Winter Run",
|
783 |
+
description: "Running, in the winter, in Edinburgh",
|
784 |
+
productURL: "http://www.greatrun.org/Events/Event.aspx?id=2",
|
785 |
+
productImage: "http://www.greatrun.org/Events/App_Images/slideshow/cropped/saved/gwir_01f0a780d94.jpg",
|
786 |
+
productThumbnail: "http://www.greatrun.org/App_Images/2011/Events/logo_GWIR.jpg"
|
787 |
+
},
|
788 |
+
category: {
|
789 |
+
primaryCategory: "Somecategory",
|
790 |
+
subCategory1: "Subcat"
|
791 |
+
},
|
792 |
+
attributes: {
|
793 |
+
distance: 5000,
|
794 |
+
country: "Scotland",
|
795 |
+
date: "2015-01-11", // Dates in ISO 8601
|
796 |
+
city: "Edinburgh" // You can put any extended data you want passing through in attributes
|
797 |
+
},
|
798 |
+
price: {
|
799 |
+
basePrice: 40.00,
|
800 |
+
currency: "GBP",
|
801 |
+
taxRate: 0.2,
|
802 |
+
priceWithTax: 48.00
|
803 |
+
}
|
804 |
+
}
|
805 |
+
]
|
806 |
+
}
|
807 |
+
*/
|
808 |
+
|
809 |
+
try {
|
810 |
+
$basket = $this->_getCheckoutSession();
|
811 |
+
|
812 |
+
if (!isset($basket)) {
|
813 |
+
return;
|
814 |
+
}
|
815 |
+
|
816 |
+
$cart = array();
|
817 |
+
$quote = $basket->getQuote();
|
818 |
+
|
819 |
+
// Set normal params
|
820 |
+
$cart_id = $basket->getQuoteId();
|
821 |
+
if ($cart_id) {
|
822 |
+
$cart['cartID'] = (string) $cart_id;
|
823 |
+
}
|
824 |
+
$cart['price'] = array();
|
825 |
+
$cart['price']['basePrice'] = (float) $quote->getBaseSubtotal();
|
826 |
+
if ($quote->getShippingAddress()->getCouponCode()) {
|
827 |
+
$cart['price']['voucherCode'] = $quote->getShippingAddress()->getCouponCode();
|
828 |
+
}
|
829 |
+
if ($quote->getShippingAddress()->getDiscountAmount()) {
|
830 |
+
$cart['price']['voucherDiscount'] = abs((float) $quote->getShippingAddress()->getDiscountAmount());
|
831 |
+
}
|
832 |
+
$cart['price']['currency'] = $this->_getCurrency();
|
833 |
+
|
834 |
+
$taxRate = (float) $quote->getShippingAddress()->getTaxAmount() / $quote->getBaseSubtotal();
|
835 |
+
$cart['price']['taxRate'] = round($taxRate, 3); // TODO: Find a better way
|
836 |
+
if ($quote->getShippingAmount()) {
|
837 |
+
$cart['price']['shipping'] = (float) $quote->getShippingAmount();
|
838 |
+
}
|
839 |
+
if ($this->_extractShippingMethod($quote)) {
|
840 |
+
$cart['price']['shippingMethod'] = $this->_extractShippingMethod($quote);
|
841 |
+
}
|
842 |
+
$cart['price']['priceWithTax'] = (float) $quote->getShippingAddress()->getTaxAmount() + $quote->getBaseSubtotal(); // TODO: Find a better way
|
843 |
+
$cart['price']['cartTotal'] = (float) $quote->getGrandTotal();
|
844 |
+
// $cart['attributes'] = array();
|
845 |
+
if ($cart['price']['basePrice']===0.0&&$cart['price']['cartTotal']===0.0&&$cart['price']['priceWithTax']===0.0) {
|
846 |
+
unset($cart['price']);
|
847 |
+
}
|
848 |
+
|
849 |
+
// Line items
|
850 |
+
$items = $quote->getAllVisibleItems();
|
851 |
+
if (!$items && $cart['price']) {
|
852 |
+
if ($this->_debug) {
|
853 |
+
$cart['price']['testLog'] = "Second method used to retrieve cart items.";
|
854 |
+
}
|
855 |
+
|
856 |
+
// In case items were not retrieved for some reason
|
857 |
+
$cartHelper = Mage::helper('checkout/cart');
|
858 |
+
$items = $cartHelper->getCart()->getItems();
|
859 |
+
}
|
860 |
+
$cart['items'] = $this->_getLineItems($items, 'cart');
|
861 |
+
if (empty($cart['items'])) {
|
862 |
+
unset($cart['items']);
|
863 |
+
}
|
864 |
+
|
865 |
+
// The following are not used in W3C DDL but exist in Universal Variable:
|
866 |
+
// $cart['subtotal'] = (float) $quote->getSubtotal();
|
867 |
+
// $cart['tax'] = (float) $quote->getShippingAddress()->getTaxAmount();
|
868 |
+
// $cart['subtotal_include_tax'] = (boolean) $this->_doesSubtotalIncludeTax($quote, $cart['tax']);
|
869 |
+
|
870 |
+
if ($cart_id||isset($cart['items'])||isset($cart['price'])) {
|
871 |
+
$this->_cart = $cart;
|
872 |
+
}
|
873 |
+
} catch (Exception $e) {
|
874 |
+
}
|
875 |
+
}
|
876 |
+
|
877 |
+
public function _doesSubtotalIncludeTax($order, $tax) {
|
878 |
+
/*
|
879 |
+
Conditions:
|
880 |
+
- if tax is zero, then set to false
|
881 |
+
- Assume that if grand total is bigger than total after subtracting shipping, then subtotal does NOT include tax
|
882 |
+
*/
|
883 |
+
try {
|
884 |
+
$grandTotalWithoutShipping = $order->getGrandTotal() - $order->getShippingAmount();
|
885 |
+
if ($tax == 0 || $grandTotalWithoutShipping > $order->getSubtotal()) {
|
886 |
+
return false;
|
887 |
+
} else {
|
888 |
+
return true;
|
889 |
+
}
|
890 |
+
} catch (Exception $e) {
|
891 |
+
}
|
892 |
+
}
|
893 |
+
|
894 |
+
public function _extractShippingMethod($order) {
|
895 |
+
try {
|
896 |
+
$shipping_method = $order->getShippingMethod();
|
897 |
+
} catch (Exception $e) {
|
898 |
+
}
|
899 |
+
return $shipping_method ? $shipping_method : '';
|
900 |
+
}
|
901 |
+
|
902 |
+
public function _setTransaction() {
|
903 |
+
/*
|
904 |
+
Spec:
|
905 |
+
transaction {
|
906 |
+
transactionID: "",
|
907 |
+
profile: {
|
908 |
+
profileInfo: {
|
909 |
+
profileID: "",
|
910 |
+
userName: "",
|
911 |
+
email: ""
|
912 |
+
},
|
913 |
+
address: {
|
914 |
+
line1: "",
|
915 |
+
line2: "",
|
916 |
+
city: "",
|
917 |
+
stateProvince: "",
|
918 |
+
postalCode: "",
|
919 |
+
country: ""
|
920 |
+
},
|
921 |
+
shippingAddress: {
|
922 |
+
line1: "",
|
923 |
+
line2: "",
|
924 |
+
city: "",
|
925 |
+
stateProvince: "",
|
926 |
+
postalCode: "",
|
927 |
+
country: ""
|
928 |
+
}
|
929 |
+
},
|
930 |
+
total: {
|
931 |
+
basePrice: 0,
|
932 |
+
voucherCode: "",
|
933 |
+
voucherDiscount: 0,
|
934 |
+
currency: "USD",
|
935 |
+
taxRate: 0,
|
936 |
+
shipping: 0,
|
937 |
+
shippingMethod: "",
|
938 |
+
priceWithTax: 0,
|
939 |
+
transactionTotal: 0
|
940 |
+
},
|
941 |
+
attributes: {},
|
942 |
+
item: [
|
943 |
+
{
|
944 |
+
productInfo
|
945 |
+
category
|
946 |
+
quantity
|
947 |
+
price
|
948 |
+
linkedProduct
|
949 |
+
attributes
|
950 |
+
}
|
951 |
+
]
|
952 |
+
}
|
953 |
+
*/
|
954 |
+
|
955 |
+
try {
|
956 |
+
$orderId = $this->_getCheckoutSession()->getLastOrderId();
|
957 |
+
if ($orderId) {
|
958 |
+
$transaction = array();
|
959 |
+
$order = $this->_getSalesOrder()->load($orderId);
|
960 |
+
|
961 |
+
// Get general details
|
962 |
+
$transaction['transactionID'] = $order->getIncrementId();
|
963 |
+
$transaction['total'] = array();
|
964 |
+
$transaction['total']['currency'] = $this->_getCurrency();
|
965 |
+
$transaction['total']['basePrice'] = (float) $order->getSubtotal();
|
966 |
+
// $transaction['tax'] = (float) $order->getTaxAmount();
|
967 |
+
// $transaction['subtotal_include_tax'] = $this->_doesSubtotalIncludeTax($order, $transaction['tax']);
|
968 |
+
// $transaction['payment_type'] = $order->getPayment()->getMethodInstance()->getTitle();
|
969 |
+
$transaction['total']['transactionTotal'] = (float) $order->getGrandTotal();
|
970 |
+
|
971 |
+
$voucher = $order->getCouponCode();
|
972 |
+
$transaction['total']['voucherCode'] = $voucher ? $voucher : "";
|
973 |
+
$voucher_discount = -1 * $order->getDiscountAmount();
|
974 |
+
$transaction['total']['voucherDiscount'] = $voucher_discount ? $voucher_discount : 0;
|
975 |
+
|
976 |
+
$transaction['total']['shipping'] = (float) $order->getShippingAmount();
|
977 |
+
$transaction['total']['shippingMethod'] = $this->_extractShippingMethod($order);
|
978 |
+
|
979 |
+
// Get addresses
|
980 |
+
$shippingId = $order->getShippingAddress()->getId();
|
981 |
+
$address = $this->_getOrderAddress()->load($shippingId);
|
982 |
+
$billingAddress = $order->getBillingAddress();
|
983 |
+
$shippingAddress = $order->getShippingAddress();
|
984 |
+
$transaction['profile'] = array();
|
985 |
+
$transaction['profile']['address'] = $this->_getAddress($billingAddress);
|
986 |
+
$transaction['profile']['shippingAddress'] = $this->_getAddress($shippingAddress);
|
987 |
+
|
988 |
+
// Get items
|
989 |
+
$items = $order->getAllItems();
|
990 |
+
$line_items = $this->_getLineItems($items, 'transaction');
|
991 |
+
$transaction['item'] = $line_items;
|
992 |
+
|
993 |
+
$this->_transaction = $transaction;
|
994 |
+
}
|
995 |
+
} catch (Exception $e) {
|
996 |
+
}
|
997 |
+
}
|
998 |
+
|
999 |
+
public function setDigitalDataLayer(Varien_Event_Observer $observer) {
|
1000 |
+
// W3C DDL
|
1001 |
+
// - pageInstanceID
|
1002 |
+
// - page
|
1003 |
+
// - product[n]
|
1004 |
+
// - cart
|
1005 |
+
// - transaction
|
1006 |
+
// - event[n]
|
1007 |
+
// - component[n]
|
1008 |
+
// - user[n]
|
1009 |
+
// - privacyAccessCategories
|
1010 |
+
// - version = "1.0"
|
1011 |
+
|
1012 |
+
try {
|
1013 |
+
$triggered_messaging_digital_data_layer_enabled = (boolean)Mage::getStoreConfig('triggered_messaging/triggered_messaging_digital_data_layer_enabled');
|
1014 |
+
|
1015 |
+
if ($triggered_messaging_digital_data_layer_enabled==1) {
|
1016 |
+
$this->_debug = (boolean)Mage::getStoreConfig('triggered_messaging/triggered_messaging_digital_data_layer_debug_enabled');
|
1017 |
+
|
1018 |
+
$this->_setUser();
|
1019 |
+
$this->_setPage();
|
1020 |
+
|
1021 |
+
if ($this->_isProduct()) {
|
1022 |
+
$this->_setProduct();
|
1023 |
+
}
|
1024 |
+
|
1025 |
+
if ($this->_isCategory() || $this->_isSearch()) {
|
1026 |
+
$this->_setListing();
|
1027 |
+
}
|
1028 |
+
|
1029 |
+
if (!$this->_isConfirmation()) {
|
1030 |
+
$this->_setCart();
|
1031 |
+
}
|
1032 |
+
|
1033 |
+
if ($this->_isConfirmation()) {
|
1034 |
+
$this->_setTransaction();
|
1035 |
+
}
|
1036 |
+
|
1037 |
+
// Add script after content block, to grab products shown on category and search pages
|
1038 |
+
$layout = $observer->getEvent()->getLayout()->getUpdate();
|
1039 |
+
$layout->addHandle('tms_block_after_content');
|
1040 |
+
}
|
1041 |
+
} catch(Exception $e) {
|
1042 |
+
}
|
1043 |
+
|
1044 |
+
return $this;
|
1045 |
+
}
|
1046 |
+
}
|
1047 |
+
?>
|
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<config>
|
3 |
+
<acl>
|
4 |
+
<resources>
|
5 |
+
<admin>
|
6 |
+
<children>
|
7 |
+
<system>
|
8 |
+
<children>
|
9 |
+
<config>
|
10 |
+
<children>
|
11 |
+
<triggeredmessaging_digitaldatalayer_configuration translate="title" module="digital_data_layer_main">
|
12 |
+
<sort_order>0</sort_order>
|
13 |
+
<title>Manage Triggered Messaging Digital Data Layer Extension</title>
|
14 |
+
</triggeredmessaging_digitaldatalayer_configuration>
|
15 |
+
<triggeredmessaging_digitaldatalayer_support translate="title" module="digital_data_layer_main">
|
16 |
+
<sort_order>1</sort_order>
|
17 |
+
<title>Triggered Messaging Support Information</title>
|
18 |
+
</triggeredmessaging_digitaldatalayer_support>
|
19 |
+
</children>
|
20 |
+
</config>
|
21 |
+
</children>
|
22 |
+
</system>
|
23 |
+
</children>
|
24 |
+
</admin>
|
25 |
+
</resources>
|
26 |
+
</acl>
|
27 |
+
</config>
|
@@ -0,0 +1,11 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0" encoding="UTF-8"?>
|
2 |
+
<config>
|
3 |
+
<placeholders>
|
4 |
+
<triggeredmessaging_ddl_session_data>
|
5 |
+
<block>digital_data_layer_main/ddl</block>
|
6 |
+
<name>digital_data_layer_session_data</name>
|
7 |
+
<placeholder>DDL_SESSION</placeholder>
|
8 |
+
<container>TriggeredMessaging_DigitalDataLayer_Model_Container_Ddl</container>
|
9 |
+
</triggeredmessaging_ddl_session_data>
|
10 |
+
</placeholders>
|
11 |
+
</config>
|
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<config>
|
3 |
+
<modules>
|
4 |
+
<TriggeredMessaging_DigitalDataLayer>
|
5 |
+
<version>0.3.0</version>
|
6 |
+
</TriggeredMessaging_DigitalDataLayer>
|
7 |
+
</modules>
|
8 |
+
|
9 |
+
<global>
|
10 |
+
<models>
|
11 |
+
<digital_data_layer_main>
|
12 |
+
<class>TriggeredMessaging_DigitalDataLayer_Model</class>
|
13 |
+
</digital_data_layer_main>
|
14 |
+
</models>
|
15 |
+
<helpers>
|
16 |
+
<digital_data_layer_main>
|
17 |
+
<class>TriggeredMessaging_DigitalDataLayer_Helper</class>
|
18 |
+
</digital_data_layer_main>
|
19 |
+
</helpers>
|
20 |
+
<blocks>
|
21 |
+
<digital_data_layer_main>
|
22 |
+
<class>TriggeredMessaging_DigitalDataLayer_Block</class>
|
23 |
+
</digital_data_layer_main>
|
24 |
+
</blocks>
|
25 |
+
</global>
|
26 |
+
|
27 |
+
<frontend>
|
28 |
+
<!-- Layout -->
|
29 |
+
<layout>
|
30 |
+
<updates>
|
31 |
+
<triggered_messaging_digital_data_layer>
|
32 |
+
<file>triggeredmessaging/digital_data_layer.xml</file>
|
33 |
+
</triggered_messaging_digital_data_layer>
|
34 |
+
</updates>
|
35 |
+
</layout>
|
36 |
+
<events>
|
37 |
+
<controller_action_layout_load_before>
|
38 |
+
<observers>
|
39 |
+
<TriggeredMessaging_DigitalDataLayer_Model_Page_Observer>
|
40 |
+
<type>singleton</type>
|
41 |
+
<class>digital_data_layer_main/page_observer</class>
|
42 |
+
<method>setDigitalDataLayer</method>
|
43 |
+
</TriggeredMessaging_DigitalDataLayer_Model_Page_Observer>
|
44 |
+
</observers>
|
45 |
+
</controller_action_layout_load_before>
|
46 |
+
<sales_quote_save_after>
|
47 |
+
<observers>
|
48 |
+
<triggeredmessaging_digital_data_layer>
|
49 |
+
<class>digital_data_layer_main/observer</class>
|
50 |
+
<method>registerQuoteChange</method>
|
51 |
+
</triggeredmessaging_digital_data_layer>
|
52 |
+
</observers>
|
53 |
+
</sales_quote_save_after>
|
54 |
+
</events>
|
55 |
+
</frontend>
|
56 |
+
|
57 |
+
<!-- Admin Configuration Default Values -->
|
58 |
+
<default>
|
59 |
+
<triggered_messaging>
|
60 |
+
<triggered_messaging_digital_data_layer_enabled>1</triggered_messaging_digital_data_layer_enabled>
|
61 |
+
<triggered_messaging_digital_data_layer_debug_enabled>0</triggered_messaging_digital_data_layer_debug_enabled>
|
62 |
+
<triggered_messaging_script_enabled>1</triggered_messaging_script_enabled>
|
63 |
+
<triggered_messaging_website_id></triggered_messaging_website_id>
|
64 |
+
</triggered_messaging>
|
65 |
+
</default>
|
66 |
+
</config>
|
@@ -0,0 +1,155 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<config>
|
3 |
+
<tabs>
|
4 |
+
<TriggeredMessaging_DigitalDataLayer_tab translate="label">
|
5 |
+
<label>W3C Digital Data Layer</label>
|
6 |
+
<sort_order>100</sort_order>
|
7 |
+
</TriggeredMessaging_DigitalDataLayer_tab>
|
8 |
+
</tabs>
|
9 |
+
|
10 |
+
<sections>
|
11 |
+
<triggeredmessaging_digitaldatalayer_configuration translate="label">
|
12 |
+
<label>Configuration</label>
|
13 |
+
<tab>TriggeredMessaging_DigitalDataLayer_tab</tab>
|
14 |
+
<sort_order>0</sort_order>
|
15 |
+
<show_in_default>1</show_in_default>
|
16 |
+
<show_in_website>1</show_in_website>
|
17 |
+
<show_in_store>1</show_in_store>
|
18 |
+
<groups>
|
19 |
+
<TriggeredMessaging_DigitalDataLayer_Settings translate="label">
|
20 |
+
<label>Digital Data Layer Configuration</label>
|
21 |
+
<sort_order>1</sort_order>
|
22 |
+
<show_in_default>1</show_in_default>
|
23 |
+
<show_in_website>1</show_in_website>
|
24 |
+
<show_in_store>1</show_in_store>
|
25 |
+
<fields>
|
26 |
+
<TriggeredMessaging_DigitalDataLayer_Enabled translate="label">
|
27 |
+
<label>Enable Digital Data Layer</label>
|
28 |
+
<frontend_type>select</frontend_type>
|
29 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
30 |
+
<config_path>triggered_messaging/triggered_messaging_digital_data_layer_enabled</config_path>
|
31 |
+
<comment><![CDATA[ See <a href="http://www.w3.org/2013/12/ceddl-201312.pdf" target="_blank">http://www.w3.org/2013/12/ceddl-201312.pdf</a> for the specification. ]]></comment>
|
32 |
+
<sort_order>1</sort_order>
|
33 |
+
<show_in_default>1</show_in_default>
|
34 |
+
<show_in_website>1</show_in_website>
|
35 |
+
<show_in_store>1</show_in_store>
|
36 |
+
</TriggeredMessaging_DigitalDataLayer_Enabled>
|
37 |
+
|
38 |
+
<TriggeredMessaging_DigitalDataLayer_DebugEnabled translate="label">
|
39 |
+
<label>Enable Debug Mode</label>
|
40 |
+
<frontend_type>select</frontend_type>
|
41 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
42 |
+
<config_path>triggered_messaging/triggered_messaging_digital_data_layer_debug_enabled</config_path>
|
43 |
+
<comment><![CDATA[ Outputs more data about the page to the digitalData layer, for debugging purposes. Should be disabled for production use. ]]></comment>
|
44 |
+
<sort_order>2</sort_order>
|
45 |
+
<show_in_default>1</show_in_default>
|
46 |
+
<show_in_website>1</show_in_website>
|
47 |
+
<show_in_store>1</show_in_store>
|
48 |
+
<depends>
|
49 |
+
<TriggeredMessaging_DigitalDataLayer_Enabled>1</TriggeredMessaging_DigitalDataLayer_Enabled>
|
50 |
+
</depends>
|
51 |
+
</TriggeredMessaging_DigitalDataLayer_DebugEnabled>
|
52 |
+
</fields>
|
53 |
+
<expanded>1</expanded>
|
54 |
+
</TriggeredMessaging_DigitalDataLayer_Settings>
|
55 |
+
|
56 |
+
<TriggeredMessaging_Script_Settings translate="label">
|
57 |
+
<label>Triggered Messaging Script Configuration (Optional)</label>
|
58 |
+
<sort_order>2</sort_order>
|
59 |
+
<show_in_default>1</show_in_default>
|
60 |
+
<show_in_website>1</show_in_website>
|
61 |
+
<show_in_store>1</show_in_store>
|
62 |
+
<fields>
|
63 |
+
<TriggeredMessaging_Script_Enabled translate="label">
|
64 |
+
<label>Enable Script</label>
|
65 |
+
<frontend_type>select</frontend_type>
|
66 |
+
<source_model>adminhtml/system_config_source_yesno</source_model>
|
67 |
+
<config_path>triggered_messaging/triggered_messaging_script_enabled</config_path>
|
68 |
+
<comment><![CDATA[ <a href="http://www.triggeredmessaging.com/supported-ecommerce-platforms/magento?utm_campaign=magento_plugin&utm_medium=web&utm_source=magento" target="_blank">More information on Triggered Messaging and Magento</a>. ]]></comment>
|
69 |
+
<sort_order>1</sort_order>
|
70 |
+
<show_in_default>1</show_in_default>
|
71 |
+
<show_in_website>1</show_in_website>
|
72 |
+
<show_in_store>1</show_in_store>
|
73 |
+
</TriggeredMessaging_Script_Enabled>
|
74 |
+
|
75 |
+
<TriggeredMessaging_Website_Id translate="label">
|
76 |
+
<label>Website ID</label>
|
77 |
+
<frontend_type>text</frontend_type>
|
78 |
+
<config_path>triggered_messaging/triggered_messaging_website_id</config_path>
|
79 |
+
<comment><![CDATA[ You can find your Website ID within your <a href="https://admin.triggeredmessaging.com/" target="_blank">Triggered Messaging admin area</a>. ]]>
|
80 |
+
</comment>
|
81 |
+
<validate>validate-alphanum</validate>
|
82 |
+
<sort_order>2</sort_order>
|
83 |
+
<show_in_default>1</show_in_default>
|
84 |
+
<show_in_website>1</show_in_website>
|
85 |
+
<show_in_store>1</show_in_store>
|
86 |
+
<depends>
|
87 |
+
<TriggeredMessaging_Script_Enabled>1</TriggeredMessaging_Script_Enabled>
|
88 |
+
</depends>
|
89 |
+
</TriggeredMessaging_Website_Id>
|
90 |
+
</fields>
|
91 |
+
<expanded>1</expanded>
|
92 |
+
</TriggeredMessaging_Script_Settings>
|
93 |
+
</groups>
|
94 |
+
</triggeredmessaging_digitaldatalayer_configuration>
|
95 |
+
|
96 |
+
<triggeredmessaging_digitaldatalayer_support translate="label">
|
97 |
+
<label>Support</label>
|
98 |
+
<tab>TriggeredMessaging_DigitalDataLayer_tab</tab>
|
99 |
+
<sort_order>1</sort_order>
|
100 |
+
<show_in_default>1</show_in_default>
|
101 |
+
<show_in_website>1</show_in_website>
|
102 |
+
<show_in_store>1</show_in_store>
|
103 |
+
<groups>
|
104 |
+
<TriggeredMessaging_Info_Support translate="label">
|
105 |
+
<label>Support Details</label>
|
106 |
+
<sort_order>1</sort_order>
|
107 |
+
<show_in_default>1</show_in_default>
|
108 |
+
<show_in_website>1</show_in_website>
|
109 |
+
<show_in_store>1</show_in_store>
|
110 |
+
<fields>
|
111 |
+
<TriggeredMessaging_Info_Support_Extension translate="label">
|
112 |
+
<label>Plugin Support</label>
|
113 |
+
<frontend_type>label</frontend_type>
|
114 |
+
<comment><![CDATA[ For issues with the extension, create an issue in the github repository: <a href="https://github.com/TriggeredMessaging/digitalDataMagentoExtension/issues" target="_blank">TriggeredMessaging/digitalDataMagentoExtension</a> ]]></comment>
|
115 |
+
<sort_order>1</sort_order>
|
116 |
+
<show_in_default>1</show_in_default>
|
117 |
+
<show_in_website>1</show_in_website>
|
118 |
+
<show_in_store>1</show_in_store>
|
119 |
+
</TriggeredMessaging_Info_Support_Extension>
|
120 |
+
<TriggeredMessaging_Info_Support_Script translate="label">
|
121 |
+
<label>Triggered Messaging Support</label>
|
122 |
+
<frontend_type>label</frontend_type>
|
123 |
+
<comment><![CDATA[ For issues with the Triggered Messaging functionality, contact support: <a href="mailto:hello@triggeredmessaging.com?Subject=Magento%20Extension%20Support%20Request" target="_blank">hello@triggeredmessaging.com</a> ]]></comment>
|
124 |
+
<sort_order>2</sort_order>
|
125 |
+
<show_in_default>1</show_in_default>
|
126 |
+
<show_in_website>1</show_in_website>
|
127 |
+
<show_in_store>1</show_in_store>
|
128 |
+
</TriggeredMessaging_Info_Support_Script>
|
129 |
+
</fields>
|
130 |
+
<expanded>1</expanded>
|
131 |
+
</TriggeredMessaging_Info_Support>
|
132 |
+
|
133 |
+
<TriggeredMessaging_Info_Testing translate="label">
|
134 |
+
<label>Testing</label>
|
135 |
+
<sort_order>2</sort_order>
|
136 |
+
<show_in_default>1</show_in_default>
|
137 |
+
<show_in_website>1</show_in_website>
|
138 |
+
<show_in_store>1</show_in_store>
|
139 |
+
<fields>
|
140 |
+
<TriggeredMessaging_Info_Testing_Note translate="label">
|
141 |
+
<label>Testing</label>
|
142 |
+
<frontend_type>label</frontend_type>
|
143 |
+
<comment><![CDATA[ You can test that your store is exposing the correct data by entering your URL at <a href="http://digitaldatavalidator.com/" target="_blank">digitalDataValidator.com</a> ]]></comment>
|
144 |
+
<sort_order>1</sort_order>
|
145 |
+
<show_in_default>1</show_in_default>
|
146 |
+
<show_in_website>1</show_in_website>
|
147 |
+
<show_in_store>1</show_in_store>
|
148 |
+
</TriggeredMessaging_Info_Testing_Note>
|
149 |
+
</fields>
|
150 |
+
<expanded>1</expanded>
|
151 |
+
</TriggeredMessaging_Info_Testing>
|
152 |
+
</groups>
|
153 |
+
</triggeredmessaging_digitaldatalayer_support>
|
154 |
+
</sections>
|
155 |
+
</config>
|
@@ -0,0 +1,13 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<layout version="1.0.0">
|
3 |
+
<default>
|
4 |
+
<reference name="head">
|
5 |
+
<block type="digital_data_layer_main/ddl" name="digital_data_layer" as="digital_data_layer" template="triggeredmessaging/digital_data_layer.phtml"/>
|
6 |
+
</reference>
|
7 |
+
</default>
|
8 |
+
<tms_block_after_content>
|
9 |
+
<reference name="content">
|
10 |
+
<block type="digital_data_layer_main/ddl" name="digital_data_layer" as="digital_data_layer" template="triggeredmessaging/digital_data_layer_after_content.phtml"/>
|
11 |
+
</reference>
|
12 |
+
</tms_block_after_content>
|
13 |
+
</layout>
|
@@ -0,0 +1,78 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php try { ?>
|
2 |
+
<?php
|
3 |
+
/* @var $this TriggeredMessaging_DigitalDataLayer_Block_Ddl */
|
4 |
+
$triggered_messaging_website_id = Mage::getStoreConfig('triggered_messaging/triggered_messaging_website_id');
|
5 |
+
$triggered_messaging_script_enabled = Mage::getStoreConfig('triggered_messaging/triggered_messaging_script_enabled');
|
6 |
+
$triggered_messaging_digital_data_layer_enabled = Mage::getStoreConfig('triggered_messaging/triggered_messaging_digital_data_layer_enabled');
|
7 |
+
|
8 |
+
$observer = 'digital_data_layer_main/page_observer';
|
9 |
+
$mage = Mage::getSingleton($observer);
|
10 |
+
?>
|
11 |
+
<?php if ($triggered_messaging_digital_data_layer_enabled == 1) :?>
|
12 |
+
<?php
|
13 |
+
// extract variable only when digital data layer is enabled
|
14 |
+
$version = $mage->getVersion();
|
15 |
+
$page = $mage->getPage();
|
16 |
+
$user = $mage->getUser();
|
17 |
+
$product = $mage->getProduct();
|
18 |
+
$cart = $mage->getCart();
|
19 |
+
$listing = $mage->getListing();
|
20 |
+
$transaction = $mage->getTransaction();
|
21 |
+
$events = $mage->getEvents();
|
22 |
+
?>
|
23 |
+
<?php
|
24 |
+
try {
|
25 |
+
// Extract things only available within template (and not model)
|
26 |
+
if (!$page['pageInfo']) {
|
27 |
+
$page['pageInfo'] = array();
|
28 |
+
}
|
29 |
+
if (!$page['pageInfo']['pageName']) {
|
30 |
+
$page['pageInfo']['pageName'] = $this->getLayout()->getBlock('head')->getTitle();
|
31 |
+
}
|
32 |
+
} catch(Exception $e) {}
|
33 |
+
?>
|
34 |
+
<!-- W3C Digital Data Layer Start -->
|
35 |
+
<script type="text/javascript">
|
36 |
+
try {
|
37 |
+
window.digitalData = window.digitalData || {};
|
38 |
+
window.digitalData.version = <?php echo json_encode($version); ?>;
|
39 |
+
window.digitalData.page = <?php echo json_encode($page); ?>;
|
40 |
+
window.digitalData.user = <?php echo json_encode($user); ?>;
|
41 |
+
<?php if ($product) : ?>
|
42 |
+
window.digitalData.product = <?php echo json_encode($product) ?>;
|
43 |
+
<?php endif; ?>
|
44 |
+
<?php if ($cart) : ?>
|
45 |
+
window.digitalData.cart = <?php echo json_encode($cart) ?>;
|
46 |
+
<?php endif; ?>
|
47 |
+
<?php if ($listing): ?>
|
48 |
+
window.digitalData.listing = <?php echo json_encode($listing) ?>;
|
49 |
+
<?php endif; ?>
|
50 |
+
<?php if ($transaction): ?>
|
51 |
+
window.digitalData.transaction = <?php echo json_encode($transaction) ?>;
|
52 |
+
<?php endif; ?>
|
53 |
+
<?php if ($events): ?>
|
54 |
+
window.digitalData.events = <?php echo json_encode($events); ?>;
|
55 |
+
<?php endif; ?>
|
56 |
+
} catch(e) {
|
57 |
+
}
|
58 |
+
</script>
|
59 |
+
<!-- W3C Digital Data Layer End -->
|
60 |
+
<?php endif; ?>
|
61 |
+
|
62 |
+
<?php if ($triggered_messaging_script_enabled) :?>
|
63 |
+
<!-- Triggered Messaging Script Start -->
|
64 |
+
<?php if ($triggered_messaging_website_id) :?>
|
65 |
+
<script defer="defer" async="async" src='//d81mfvml8p5ml.cloudfront.net/<?php echo $triggered_messaging_website_id; ?>.js'></script>
|
66 |
+
<?php if ($mage->_isConfirmation()) :?>
|
67 |
+
<?php $pcqs = $mage->getPurchaseCompleteQs(); ?>
|
68 |
+
<img src="//d1f0tbk1v3e25u.cloudfront.net/pc/<?php echo $triggered_messaging_website_id; ?>/?<?php echo $pcqs; ?>" />
|
69 |
+
<?php endif;?>
|
70 |
+
<?php else: ?>
|
71 |
+
<script type="text/javascript">
|
72 |
+
console.log("You have enabled the Triggered Messaging script from the Magento Admin Configuration Panel, but have not supplied a website ID. Please contact hello@triggeredmessaging.com if you would like some assistance.");
|
73 |
+
</script>
|
74 |
+
<?php endif;?>
|
75 |
+
<!-- Triggered Messaging Script End -->
|
76 |
+
<?php endif;?>
|
77 |
+
|
78 |
+
<?php } catch (Exception $e) {} ?>
|
@@ -0,0 +1,58 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php try {
|
2 |
+
|
3 |
+
/* @var $this TriggeredMessaging_DigitalDataLayer_Block_Ddl */
|
4 |
+
$triggered_messaging_digital_data_layer_enabled = Mage::getStoreConfig('triggered_messaging/triggered_messaging_digital_data_layer_enabled');
|
5 |
+
|
6 |
+
// extract variable only when digital data layer is enabled
|
7 |
+
if ($triggered_messaging_digital_data_layer_enabled == 1) :
|
8 |
+
|
9 |
+
$observer = 'digital_data_layer_main/page_observer';
|
10 |
+
$mage = Mage::getSingleton($observer);
|
11 |
+
|
12 |
+
$page = $mage->getPage();
|
13 |
+
if (isset($page['category']) &&
|
14 |
+
isset($page['category']['pageType'])) {
|
15 |
+
switch ($page['category']['pageType']) {
|
16 |
+
case 'category':
|
17 |
+
case 'search':
|
18 |
+
case 'tag':
|
19 |
+
break;
|
20 |
+
default:
|
21 |
+
return;
|
22 |
+
}
|
23 |
+
}
|
24 |
+
|
25 |
+
// Grab product list data (from category and search pages)
|
26 |
+
$that = Mage::getBlockSingleton('catalog/product_list');
|
27 |
+
if (!$that) return;
|
28 |
+
$_productCollection = $that->getLoadedProductCollection();
|
29 |
+
if (!$_productCollection) return;
|
30 |
+
if ($_productCollection->count()===0) return;
|
31 |
+
|
32 |
+
// Extract products displayed on category page
|
33 |
+
// Need to do it after content block as the specified products are loaded then
|
34 |
+
$products = array();
|
35 |
+
foreach ($_productCollection as $_product) {
|
36 |
+
array_push($products, $mage->_getProductModel($_product));
|
37 |
+
}
|
38 |
+
|
39 |
+
$preloaded_product = $mage->getProduct();
|
40 |
+
?>
|
41 |
+
<!-- W3C Digital Data Layer Extra Info Start -->
|
42 |
+
<script type="text/javascript">
|
43 |
+
try {
|
44 |
+
<?php if ($products) : ?>
|
45 |
+
<?php if (!$preloaded_product) : ?>
|
46 |
+
window.digitalData.product = <?php echo json_encode($products) ?>;
|
47 |
+
<?php else : ?>
|
48 |
+
window.digitalData.product.push.apply(window.digitalData.product, <?php echo json_encode($products) ?>);
|
49 |
+
<?php endif; ?>
|
50 |
+
<?php endif; ?>
|
51 |
+
} catch(e) {
|
52 |
+
}
|
53 |
+
</script>
|
54 |
+
<!-- W3C Digital Data Layer Extra Info End -->
|
55 |
+
<?php
|
56 |
+
endif;
|
57 |
+
|
58 |
+
} catch (Exception $e) {} ?>
|
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version = "1.0"?>
|
2 |
+
<config>
|
3 |
+
<modules>
|
4 |
+
<TriggeredMessaging_DigitalDataLayer>
|
5 |
+
<active>true</active>
|
6 |
+
<codePool>community</codePool>
|
7 |
+
</TriggeredMessaging_DigitalDataLayer>
|
8 |
+
</modules>
|
9 |
+
</config>
|
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<package>
|
3 |
+
<name>W3CDigitalDataLayerByTriggeredMessaging</name>
|
4 |
+
<version>0.3.3</version>
|
5 |
+
<stability>stable</stability>
|
6 |
+
<license uri="http://opensource.org/licenses/apachepl.php">Apache Software License v2</license>
|
7 |
+
<channel>community</channel>
|
8 |
+
<extends/>
|
9 |
+
<summary>Adds the W3C Digital Data Layer spec to your store.</summary>
|
10 |
+
<description>Adds the W3C Digital Data Layer to Magento. The Digital Data Layer (DDL) is a standardised way of exposing data on your eCommerce site. If you implement to the specification, it will mean that you will not have to duplicate your work to expose data to multiple providers (e.g. an analytics provider and a tag management provider).
|
11 |
+
The plugin also allows easy installation of Triggered Messaging scripts in your store.
|
12 |
+

|
13 |
+
Any bugs or support requests should be raised here:
|
14 |
+

|
15 |
+
https://github.com/TriggeredMessaging/digitalDataMagentoExtension/issues</description>
|
16 |
+
<notes>All basic features included.
|
17 |
+
- It can handle full page caching.
|
18 |
+
- Exception handling has been added.
|
19 |
+
- Removed empty objects and arrays; Removed duplicated subcategories.
|
20 |
+
- Added product data for products on category and search pages.
|
21 |
+
- Fixed issue where configurable products have multiple product entries, and incorrect prices, in the cart object.
|
22 |
+
- Added more data into digitalData object so websites can be debugged.
|
23 |
+
- Configurable products have each of their configurations listed under 'linkedProduct'.
|
24 |
+
- Fixed bug that was breaking some styling.
|
25 |
+
- Added 'pageName' attribute and fixed type of 'returningStatus' object.
|
26 |
+
- Tweaks to configuration panel and default values.
|
27 |
+
- List of all installed non-Magento extensions are exposed (for debug purposes)
|
28 |
+
- Products associated with a Grouped Product have been included.
|
29 |
+
- Minimum prices of grouped and bundled products can be extracted.
|
30 |
+
- Output of debug data can now be controlled through admin configuration panel.</notes>
|
31 |
+
<authors><author><name>Muhammed Miah</name><user>momiah1234</user><email>muhammed.miah@triggeredmessaging.com</email></author><author><name>Triggered Messaging</name><user>tmsdemo</user><email>demostore@triggeredmessaging.com</email></author><author><name>Mike Austin</name><user>tmsdemo</user><email>dev@triggeredmessaging.com</email></author></authors>
|
32 |
+
<date>2014-09-29</date>
|
33 |
+
<time>12:59:57</time>
|
34 |
+
<contents><target name="magecommunity"><dir name="TriggeredMessaging"><dir name="DigitalDataLayer"><dir name="Block"><file name="Ddl.php" hash="134766e2a49c3ecfbf03d1025dd41e8b"/></dir><dir name="Helper"><file name="Data.php" hash="5a6e19225e7db056946c95b1477e5c18"/></dir><dir name="Model"><dir name="Container"><file name="Ddl.php" hash="cc9dcd8cf4e460a01c242ac675ce5634"/></dir><file name="Observer.php" hash="26e0dcfc7a19d5310e44e004c144c23e"/><dir name="Page"><file name="Observer.php" hash="2f438462d1372e7e993b301b552ac861"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="8b98dee82241e0b69661bf4699cba334"/><file name="cache.xml" hash="1b6658073a8126cd655cb18109559f49"/><file name="config.xml" hash="a29f9fb1250c40a8d973e470ffab46ac"/><file name="system.xml" hash="a72e032172f1a6b05ba969415bf33f63"/></dir></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="template"><dir name="triggeredmessaging"><file name="digital_data_layer.phtml" hash="61001c0d1d3478f9db8366f4386da754"/><file name="digital_data_layer_after_content.phtml" hash="6ee383b4d2011fd7e718b2930b7cd95d"/></dir></dir><dir name="layout"><dir name="triggeredmessaging"><file name="digital_data_layer.xml" hash="3c58b9faec1d9c63e1fb0a3fcc35a2d8"/></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="TriggeredMessaging_DigitalDataLayer.xml" hash="cfc3b1bff54f3e1f224f120e536bc411"/></dir></target></contents>
|
35 |
+
<compatible/>
|
36 |
+
<dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies>
|
37 |
+
</package>
|