Panalysis_TagManager - Version 0.5.3

Version Notes

Late beta release. This has been tested on 1.8 and 1.9 editions plus 1.4.1.1

Download this release

Release Info

Developer Rod Jacka
Extension Panalysis_TagManager
Version 0.5.3
Comparing to
See all releases


Version 0.5.3

app/code/community/Panalysis/TagManager/Block/Adminhtml/Version.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Panalysis_TagManager_Block_Adminhtml_Version
4
+ extends Mage_Adminhtml_Block_System_Config_Form_Field
5
+ {
6
+ protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
7
+ {
8
+ return (string) Mage::helper('panalysis_tagmanager')->getExtensionVersion();
9
+ }
10
+ }
11
+
12
+
app/code/community/Panalysis/TagManager/Block/Tagmanager.php ADDED
@@ -0,0 +1,273 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Panalysis_TagManager_Block_Tagmanager extends Mage_Core_Block_Template
4
+ {
5
+ public function buildDataLayer()
6
+ {
7
+
8
+ $helper = Mage::helper('panalysis_tagmanager');
9
+ $session = Mage::getSingleton('core/session');
10
+ $trackProductLists = $helper->getTrackProductList();
11
+
12
+ // to store the main data layer values
13
+ $dataLayer = array();
14
+ // to store other secondary events that can occur once the page has loaded such as add to cart, remove from cart
15
+ $additionalEventsAdd = array();
16
+ $additionalEventsRemove = array();
17
+
18
+ $visitorState = $this->getVisitorData();
19
+ $dataLayer += $visitorState;
20
+
21
+ if ($this->getPage() == 'Product Detail') $dataLayer += $helper->buildProductDetailsData($this->getProductDetails());
22
+ if ($this->getPage() == 'Order Success') $dataLayer += $helper->buildOrderData($this->getOrderData());
23
+ //if ($this->getPage() == 'Product Category' && $trackProductLists) $dataLayer += $helper->buildCategoryData($this->getCategoryProducts());
24
+ if ($this->getPage() == 'Shopping Cart') $dataLayer += $helper->buildCheckoutData($this->getCartProducts());
25
+ if ($this->getPage() == 'Onepage Checkout') $dataLayer += $helper->buildOnePageCartCheckoutData($this->getCartProducts());
26
+
27
+ // Add to Cart Events
28
+ $tmProduct = $session->getTmProduct();
29
+ if($tmProduct) $additionalEventsAdd = $helper->buildAddToCartData($tmProduct); // then there is an add to cart product
30
+ $session->unsTmProduct();
31
+
32
+ // Remove from Cart Events
33
+ $rmProducts = $session->getRmProducts();
34
+ if ($rmProducts) $additionalEventsRemove = $this->buildRemoveFromCartData($rmProducts);
35
+ $session->unsRmProducts();
36
+
37
+ $dataLayerJs = "dataLayer.push(" . json_encode($dataLayer,JSON_PRETTY_PRINT) .");";
38
+ if($additionalEventsAdd) $dataLayerJs .= "dataLayer.push(" . json_encode($additionalEventsAdd,JSON_PRETTY_PRINT) .");";
39
+ if($additionalEventsRemove) $dataLayerJs .= "dataLayer.push(" . json_encode($additionalEventsRemove,JSON_PRETTY_PRINT) .");";
40
+
41
+ return $dataLayerJs;
42
+ }
43
+
44
+
45
+ public function getTwitterDetails()
46
+ {
47
+ $helper = Mage::helper('panalysis_tagmanager');
48
+ $twitterData = [];
49
+ $twitterData['store_username'] = $helper->getTwitterStoreUsername();
50
+ if($helper->getTwitterCreatorUsername() != "")
51
+ {
52
+ $twitterData['creator_username'] = $helper->getTwitterCreatorUsername();
53
+ }
54
+ else
55
+ {
56
+ $twitterData['creator_username'] = $twitterData['store_username'];
57
+ }
58
+
59
+ if($helper->useTwitterLageImage()){
60
+ $twitterData['card_format'] = 'summary_large_image';
61
+ }else{
62
+ $twitterData['card_format'] = 'summary';
63
+ }
64
+
65
+ if($this->getPage() == "Product Detail"){
66
+ $twitterData['image'] = Mage::registry('product')->getImageUrl();
67
+ }
68
+ else{
69
+ $twitterData['image'] = $helper->getTwitterImage();
70
+ }
71
+
72
+ return $twitterData;
73
+ }
74
+
75
+ public function getPage()
76
+ {
77
+ $page = '';
78
+ if ($this->getRequest()->getModuleName() == 'catalog'
79
+ && $this->getRequest()->getControllerName() == 'product'
80
+ && Mage::registry('current_product')
81
+ ) {
82
+ $page = 'Product Detail';
83
+ }
84
+ if ($this->getRequest()->getModuleName() == 'checkout'
85
+ && $this->getRequest()->getControllerName() == 'onepage'
86
+ && $this->getRequest()->getActionName() == 'success'
87
+ ) {
88
+ $page = 'Order Success';
89
+ }
90
+ if ($this->getRequest()->getModuleName() == 'checkout'
91
+ && $this->getRequest()->getControllerName() == 'onepage'
92
+ && $this->getRequest()->getActionName() == 'index'
93
+ ) {
94
+ $page = 'Onepage Checkout';
95
+ }
96
+ if ($this->getRequest()->getModuleName() == 'checkout'
97
+ && $this->getRequest()->getControllerName() == 'cart'
98
+ && $this->getRequest()->getActionName() == 'index'
99
+ ) {
100
+ $page = 'Shopping Cart';
101
+ }
102
+ if ($this->getRequest()->getModuleName() == 'catalog'
103
+ && $this->getRequest()->getControllerName() == 'category'
104
+ && $this->getRequest()->getActionName() == 'view'
105
+ ) {
106
+ $page = 'Product Category';
107
+ }
108
+
109
+ Mage::log("Panalysis - " . $page, null, 'events.log', true);
110
+ return $page;
111
+ }
112
+
113
+ public function getProductDetails()
114
+ {
115
+ $helper = Mage::helper('panalysis_tagmanager');
116
+ $_product = Mage::registry('current_product');
117
+ $tm = Mage::getModel('panalysis_tagmanager/tagmanager');
118
+ $products = array();
119
+ $productType = $_product->getTypeId();
120
+ if ($productType === Mage_Catalog_Model_Product_Type::TYPE_BUNDLE)
121
+ {
122
+ $associated_ids = $helper->getBundleProducts($_product->getId());
123
+ foreach($associated_ids as $child)
124
+ {
125
+ $products[] = $helper->CreateProductArray($child);
126
+ }
127
+ } elseif($productType === Mage_Catalog_Model_Product_Type::TYPE_GROUPED) {
128
+ $associatedProducts = $_product->getTypeInstance(true)->getAssociatedProducts($_product);
129
+ $i = 0;
130
+ foreach($associatedProducts as $option)
131
+ {
132
+ $products[$i] = $helper->CreateProductArray($option->getId(), $option->getQty());
133
+ $products[$i]['id'] = $option->getSku();
134
+ $products[$i]['name'] = $option->getName();
135
+ ++$i;
136
+ }
137
+
138
+ } else {
139
+ $products[] = $helper->CreateProductArray($_product->getId());
140
+ }
141
+
142
+ return $products;
143
+ }
144
+
145
+ public function getOrderData()
146
+ {
147
+
148
+ $tm = Mage::getModel('panalysis_tagmanager/tagmanager');
149
+ $helper = Mage::helper('panalysis_tagmanager');
150
+ $order = Mage::getSingleton('sales/order');
151
+ $order->load(Mage::getSingleton('checkout/session')->getLastOrderId());
152
+ $storeName = Mage::app()->getStore()->getName();
153
+ $data = array();
154
+
155
+ try {
156
+ if ($order->getId()) {
157
+
158
+ $products = array();
159
+
160
+ $data = array(
161
+ 'actionField' => array(
162
+ 'id' => $order->getIncrementId(),
163
+ 'affiliation' => $storeName,
164
+ 'revenue' => (float) $order->getBaseGrandTotal(),
165
+ 'tax' => (float) $order->getBaseTaxAmount(),
166
+ 'shipping' => (float) $order->getBaseShippingAmount(),
167
+ 'coupon' => ($order->getCouponCode() ? $order->getCouponCode() : ''),
168
+ ),
169
+ 'products' => array()
170
+ );
171
+
172
+ foreach ($order->getAllItems() as $item)
173
+ {
174
+
175
+ $product = Mage::getModel('catalog/product')->load($item->getProductId());
176
+ $product_type = $product->getTypeId();
177
+
178
+ if ($product_type === Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE)
179
+ $product = Mage::getModel('catalog/product')->loadByAttribute('sku', $item->getSku());
180
+
181
+ if ($product_type === Mage_Catalog_Model_Product_Type::TYPE_BUNDLE) continue;
182
+
183
+ if (empty($products[$item->getSku()])) {
184
+ $products[$item->getSku()] = $helper->CreateProductArray($product->getId(), $item->getQtyOrdered(), true);
185
+ }elseif((int)$item->getPrice()) {
186
+ $products[$item->getSku()]['quantity'] += (int)$item->getQtyOrdered();
187
+ }
188
+
189
+ }
190
+
191
+ foreach ($products as $product)
192
+ {
193
+ $data['transactionProducts'][] = $product;
194
+ }
195
+ }
196
+ } catch (exception $e) {
197
+ Mage::logException($e);
198
+ }
199
+
200
+ return $data;
201
+
202
+ }
203
+
204
+ public function getCheckoutUrl()
205
+ {
206
+ return $this->getUrl('checkout/onepage', array('_secure'=>true));
207
+ }
208
+
209
+ public function buildRemoveFromCartData($prods){
210
+ $data = array(
211
+ 'event' => 'removeFromCart',
212
+ 'ecommerce' => array(
213
+ 'remove' => array(
214
+ 'products' => $prods
215
+ )
216
+ )
217
+ );
218
+
219
+ return $data;
220
+ }
221
+
222
+ public function getCartProducts(){
223
+ try
224
+ {
225
+ $helper = Mage::helper('panalysis_tagmanager');
226
+ $cart = Mage::getModel("checkout/cart");
227
+ $cartItems = $cart->getItems();
228
+ if(count($cartItems) ==0) return;
229
+
230
+ $tm = Mage::getSingleton('panalysis_tagmanager/tagmanager');
231
+ $cartProducts = array();
232
+
233
+ foreach ($cartItems as $item)
234
+ {
235
+ //$itemId = $item->getId();
236
+ $productId = $item->getProductId();
237
+ $product = Mage::getSingleton('catalog/product')->load($productId);
238
+ if($item->getProductType() != 'configurable' && $item->getProductType() != 'bundle')
239
+ {
240
+ $myItem = $helper->CreateProductArray($product->getId(), $item->getQty());
241
+
242
+ if($item->getParentItemId())
243
+ {
244
+ $parent = Mage::getModel('sales/quote_item')->load($item->getParentItemId());
245
+ $myItem['quantity'] = (int)$parent->getQty();
246
+ }
247
+
248
+ array_push($cartProducts,$myItem);
249
+ }
250
+ }
251
+ return $cartProducts;
252
+ }
253
+ catch(exception $e)
254
+ {
255
+ Mage::logException($e);
256
+ }
257
+ }
258
+
259
+ public function getCheckoutState(){
260
+ $tm = Mage::getSingleton('panalysis_tagmanager/tagmanager');
261
+ return $tm->getCheckoutState();
262
+ }
263
+
264
+ public function getCategoryProducts(){
265
+ $tm = Mage::getSingleton('panalysis_tagmanager/tagmanager');
266
+ return $tm->getCategoryProducts();
267
+ }
268
+
269
+ public function getVisitorData(){
270
+ $tm = Mage::getModel('panalysis_tagmanager/tagmanager');
271
+ return $tm->getVisitorData();
272
+ }
273
+ }
app/code/community/Panalysis/TagManager/Helper/Data.php ADDED
@@ -0,0 +1,252 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Panalysis_TagManager_Helper_Data extends Mage_Core_Helper_Abstract
4
+ {
5
+ const GTM_CONTAINER_ID = 'panalysis_tagmanager/gtm/containerid';
6
+ const GTM_TRACK_PRODUCT_LISTS = 'panalysis_tagmanager/gtm/enable_product_lists';
7
+ const OG_IS_ENABLED = 'panalysis_tagmanager/opengraph/is_enabled';
8
+ const FB_APP_ID = 'panalysis_tagmanager/opengraph/facebookappid';
9
+ const FB_ADMIN_ID = 'panalysis_tagmanager/opengraph/facebookadminid';
10
+ const PINTEREST_ID = 'panalysis_tagmanager/opengraph/pinterestid';
11
+ const TWITTER_ENABLED = 'panalysis_tagmanager/opengraph/use_twittercards';
12
+ const TWITTER_USELARGEIMAGE = 'panalysis_tagmanager/opengraph/use_largeimage';
13
+ const TWITTER_STORE_USERNAME = 'panalysis_tagmanager/opengraph/twitterstoreid';
14
+ const TWITTER_CREATOR_USERNAME = 'panalysis_tagmanager/opengraph/twittercreatorid';
15
+ const TWITTER_IMAGE = 'panalysis_tagmanager/opengraph/twitterimage';
16
+ const GTM_MAX_PRODUCTS_IN_LISTS = 'panalysis_tagmanager/gtm/max_products';
17
+ const GTM_BRAND_CODE = 'panalysis_tagmanager/gtm/brandcode';
18
+ const GTM_COLOR_CODE = 'panalysis_tagmanager/gtm/colorcode';
19
+ const AJAX_ENABLED = 'panalysis_tagmanager/gtm/enable_ajax';
20
+
21
+ private $store_id = 0;
22
+
23
+ function __construct() {
24
+ $this->store_id = Mage::app()->getStore()->getStoreId();
25
+ }
26
+
27
+ public function getExtensionVersion()
28
+ {
29
+ return (string) Mage::getConfig()->getNode()->modules->Panalysis_TagManager->version;
30
+ }
31
+
32
+ public function getContainerId()
33
+ {
34
+ return Mage::getStoreConfig(self::GTM_CONTAINER_ID, $this->store_id);
35
+ }
36
+
37
+ public function getTrackProductList()
38
+ {
39
+ return Mage::getStoreConfig(self::GTM_TRACK_PRODUCT_LISTS, $this->store_id);
40
+ }
41
+
42
+ public function useOpenGraph()
43
+ {
44
+ return Mage::getStoreConfig(self::OG_IS_ENABLED, $this->store_id);
45
+ }
46
+
47
+ public function getFacebookAppId()
48
+ {
49
+ return Mage::getStoreConfig(self::FB_APP_ID, $this->store_id);
50
+ }
51
+
52
+ public function getFacebookAdminId()
53
+ {
54
+ return Mage::getStoreConfig(self::FB_ADMIN_ID, $this->store_id);
55
+ }
56
+
57
+ public function getPinterestId()
58
+ {
59
+ return Mage::getStoreConfig(self::PINTEREST_ID, $this->store_id);
60
+ }
61
+
62
+ public function useTwitterCards()
63
+ {
64
+ return Mage::getStoreConfig(self::TWITTER_ENABLED, $this->store_id);
65
+ }
66
+
67
+ public function useTwitterLageImage()
68
+ {
69
+ return Mage::getStoreConfig(self::TWITTER_USELARGEIMAGE, $this->store_id);
70
+ }
71
+
72
+ public function getTwitterStoreUsername()
73
+ {
74
+ return Mage::getStoreConfig(self::TWITTER_STORE_USERNAME, $this->store_id);
75
+ }
76
+
77
+ public function getTwitterCreatorUsername()
78
+ {
79
+ return Mage::getStoreConfig(self::TWITTER_CREATOR_USERNAME, $this->store_id);
80
+ }
81
+
82
+ public function getTwitterImage()
83
+ {
84
+ return Mage::getStoreConfig(self::TWITTER_IMAGE, $this->store_id);
85
+ }
86
+
87
+ public function getListMaxProducts()
88
+ {
89
+ return (int)Mage::getStoreConfig(self::GTM_MAX_PRODUCTS_IN_LISTS, $this->store_id);
90
+ }
91
+
92
+ public function getBrandCode()
93
+ {
94
+ return Mage::getStoreConfig(self::GTM_BRAND_CODE, $this->store_id);
95
+ }
96
+
97
+ public function getColorCode()
98
+ {
99
+ return Mage::getStoreConfig(self::GTM_COLOR_CODE, $this->store_id);
100
+ }
101
+
102
+ public function CreateProductArray($product_id, $qty = 1, $full_category = false)
103
+ {
104
+ $product = Mage::getModel('catalog/product')->load($product_id);
105
+ if($product)
106
+ {
107
+ $tm = Mage::getSingleton('panalysis_tagmanager/tagmanager');
108
+ $final_price = $tm->getPrice($product->getId());
109
+
110
+ $product_array = array(
111
+ 'name' => $product->getName(),
112
+ 'id' => $product->getSku(),
113
+ 'price' => $final_price,
114
+ );
115
+
116
+ if($brand = $tm->getBrand($product)) $product_array['brand'] = $brand;
117
+ if($variant = $tm->getVariant($product)) $product_array['variant'] = $variant;
118
+
119
+ if($full_category) $product_array['category'] = $tm->getCatArray($product);
120
+ elseif($current_category = Mage::registry('current_category')) $product_array['category'] = $current_category->getName();
121
+ else $product_array['category'] = $tm->getCategory($product);
122
+
123
+ if($qty !== false && (int)$qty) $product_array['quantity'] = (int)$qty;
124
+
125
+ return $product_array;
126
+
127
+ }else return array();
128
+ }
129
+
130
+ //get products just once
131
+ public function getBundleProducts($product_id)
132
+ {
133
+ $_product = Mage::getModel('catalog/product')->load($product_id);
134
+ if ($_product->getTypeId() === Mage_Catalog_Model_Product_Type::TYPE_BUNDLE)
135
+ {
136
+ $associated = $_product->getTypeInstance(true)->getChildrenIds($_product->getId(), false);
137
+ $associated_ids = array();
138
+ foreach($associated as $group)
139
+ {
140
+ foreach($group as $child)
141
+ {
142
+ if (!in_array($child, $associated_ids))
143
+ {
144
+ $associated_ids[] = $child;
145
+ }
146
+ }
147
+ }
148
+
149
+ return $associated_ids;
150
+ }
151
+
152
+ return array();
153
+ }
154
+
155
+ public function buildProductDetailsData($products){
156
+ $data = array(
157
+ 'ecommerce' => array(
158
+ 'currencyCode' => Mage::app()->getStore()->getCurrentCurrencyCode(),
159
+ 'detail' => array(
160
+ 'products' => $products
161
+ )
162
+ )
163
+ );
164
+ return $data;
165
+ }
166
+
167
+ public function buildOrderData($order){
168
+ $data = array(
169
+ 'ecommerce' => array(
170
+ 'purchase' => array(
171
+ 'actionField' => $order['actionField'],
172
+ 'products' => $order['transactionProducts']
173
+ )
174
+ )
175
+ );
176
+
177
+ return $data;
178
+
179
+ }
180
+
181
+ public function buildCategoryData($prodlist){
182
+ $data = array();
183
+ if(count($prodlist)>0){
184
+
185
+ $data = array(
186
+ 'ecommerce' => array(
187
+ 'currencyCode' => Mage::app()->getStore()->getCurrentCurrencyCode(),
188
+ 'impressions' => $prodlist
189
+ )
190
+ );
191
+ }
192
+
193
+ return $data;
194
+ }
195
+
196
+ public function buildCheckoutData($products){
197
+ if(empty($products)) return array();
198
+ $data = array(
199
+ 'event' => 'checkout',
200
+ 'ecommerce' => array(
201
+ 'currencyCode' => Mage::app()->getStore()->getCurrentCurrencyCode(),
202
+ 'checkout' => array(
203
+ 'actionField' => array(
204
+ 'step' =>'checkout',
205
+ 'option' => 'review cart'
206
+ ),
207
+ 'products' => $products
208
+ )
209
+ )
210
+ );
211
+
212
+ return $data;
213
+ }
214
+
215
+ public function buildOnePageCartCheckoutData($products){
216
+ $data = array(
217
+ 'event' => 'checkout',
218
+ 'ecommerce' => array(
219
+ 'checkout' => array(
220
+ 'actionField' => array(
221
+ 'step' =>'checkout',
222
+ 'option' => 'start checkout'
223
+ ),
224
+ 'products' => $products
225
+ )
226
+ )
227
+ );
228
+
229
+ return $data;
230
+ }
231
+
232
+ public function buildAddToCartData($prods)
233
+ {
234
+ $data = array(
235
+ 'event' => 'addToCart',
236
+ 'ecommerce' => array(
237
+ 'currencyCode' => Mage::app()->getStore()->getCurrentCurrencyCode(),
238
+ 'add' => array(
239
+ 'products' => $prods
240
+ )
241
+ )
242
+ );
243
+
244
+ return $data;
245
+ }
246
+
247
+ public function AjaxEnabled()
248
+ {
249
+ return Mage::getStoreConfig(self::AJAX_ENABLED, $this->store_id);
250
+ }
251
+
252
+ }
app/code/community/Panalysis/TagManager/Model/Config/Data/NotEmpty.php ADDED
@@ -0,0 +1,11 @@
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Panalysis_TagManager_Model_Config_Data_NotEmpty extends Mage_Core_Model_Config_Data
3
+ {
4
+ public function _beforeSave()
5
+ {
6
+ $val = $this->getValue();
7
+ if (empty($val)) {
8
+ Mage::throwException($this->getFieldConfig()->label . " must not be empty");
9
+ }
10
+ }
11
+ }
app/code/community/Panalysis/TagManager/Model/Observer.php ADDED
@@ -0,0 +1,241 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Panalysis_TagManager_Model_Observer
4
+ {
5
+ public function getLayout()
6
+ {
7
+ return Mage::getSingleton('core/layout');
8
+ }
9
+
10
+ public function checkoutCartAddProductComplete($observer)
11
+ {
12
+ $helper = Mage::helper('panalysis_tagmanager');
13
+ try {
14
+ $product = $observer->getProduct();
15
+ $params = $observer->getRequest()->getParams();
16
+ $qty = 1;
17
+ $price = '';
18
+ $tmProduct = array();
19
+
20
+ if (isset($params['qty'])) {
21
+ $filter = new Zend_Filter_LocalizedToNormalized(
22
+ array('locale' => Mage::app()->getLocale()->getLocaleCode())
23
+ );
24
+ $qty = $filter->filter($params['qty']);
25
+ }
26
+
27
+ $type = $product->getTypeID();
28
+
29
+ if ($type === Mage_Catalog_Model_Product_Type::TYPE_GROUPED) {
30
+ $associatedProducts = $product->getTypeInstance(true)->getAssociatedProducts($product);
31
+ foreach($associatedProducts as $ip)
32
+ {
33
+ $my_qty = $params['super_group'][$ip->getId()];
34
+ if($my_qty > 0){
35
+ $tmProduct[] = $helper->CreateProductArray($ip->getId(), $my_qty);
36
+ }
37
+ }
38
+
39
+ } elseif ($type === Mage_Catalog_Model_Product_Type::TYPE_BUNDLE) {
40
+ $optionCollection = $product->getTypeInstance()->getOptionsCollection();
41
+ $selectionCollection =$product->getTypeInstance()->getSelectionsCollection($product->getTypeInstance()->getOptionsIds());
42
+ $options = $optionCollection->appendSelections($selectionCollection);
43
+ foreach( $options as $option )
44
+ {
45
+ $_selections = $option->getSelections();
46
+
47
+ foreach( $_selections as $selection )
48
+ {
49
+ $tmProduct[] = $helper->CreateProductArray($selection->getId(), $qty);
50
+ }
51
+ }
52
+ } elseif($type === Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE){
53
+ $product = Mage::getModel('catalog/product')->loadByAttribute('sku', $product->getSku());
54
+ $tmProduct[] = $helper->CreateProductArray($product->getId(), $qty);
55
+ }else {
56
+ $tmProduct[] = $helper->CreateProductArray($product->getId(), $qty);
57
+ }
58
+
59
+ $session = Mage::getSingleton('core/session');
60
+
61
+ if(Mage::app()->getRequest()->isXmlHttpRequest()){
62
+ $session->setData('panalysis_tagmanager',1);
63
+ }
64
+
65
+ $session->setTmProduct($tmProduct);
66
+
67
+ } catch (exception $e) {
68
+ Mage::logException($e);
69
+ }
70
+ }
71
+
72
+ public function hookToUpdateToCart($event)
73
+ {
74
+ $new_qty = Mage::app()->getRequest()->getParam('cart');
75
+ $updated_cart = array();
76
+ foreach($new_qty as $key => $item)
77
+ {
78
+ $updated_cart[$key] = (int)$item['qty'];
79
+ }
80
+
81
+ $cart = Mage::getModel('checkout/cart')->getQuote();
82
+ $cartItems = $cart->getAllItems();
83
+
84
+ foreach ($cartItems as $item)
85
+ {
86
+ if (array_key_exists($item->getId(), $updated_cart) || $item->getParentItemId())
87
+ {
88
+ $product = Mage::getModel('catalog/product')->load($item->getProductId());
89
+ if($product->getTypeId() === Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE ||
90
+ $product->getTypeId() === Mage_Catalog_Model_Product_Type::TYPE_BUNDLE)
91
+ continue;
92
+
93
+ if($item->getParentItemId())
94
+ {
95
+ $parent = Mage::getModel('sales/quote_item')->load($item->getParentItemId());
96
+ $new_qty = $updated_cart[$item->getParentItemId()];
97
+ $old_qty = (int)$parent->getQty();
98
+ }else{
99
+ $new_qty = $updated_cart[$item->getId()];
100
+ $old_qty = $item->getQty();
101
+ }
102
+
103
+ if($old_qty > $new_qty) //item removed from cart
104
+ {
105
+ $new_qty = $old_qty - $new_qty;
106
+ $this->removeItemFromCart($product->getId(), $new_qty);
107
+ }elseif($old_qty < $new_qty) //item added to cart (qty increment)
108
+ {
109
+ $new_qty = $new_qty - $old_qty;
110
+ $this->addItemToCart($product->getId(), $new_qty);
111
+ }
112
+ }
113
+ }
114
+ return $event;
115
+ }
116
+
117
+ private function addItemToCart($product_id, $qty=1)
118
+ {
119
+ $helper = Mage::helper('panalysis_tagmanager');
120
+ try {
121
+ $addProduct = array();
122
+ $tm = Mage::getSingleton('panalysis_tagmanager/tagmanager');
123
+ $current_updated = Mage::getSingleton('core/session')->getTmProduct();
124
+ if($current_updated) $addProduct[] = $current_updated;
125
+ $addProduct[] = $helper->CreateProductArray($product_id, $qty);
126
+ $session = Mage::getSingleton('core/session');
127
+ $session->setTmProduct($addProduct);
128
+ } catch (exception $e) {
129
+ Mage::logException($e);
130
+ }
131
+ }
132
+
133
+ private function removeItemFromCart($product_id, $qty)
134
+ {
135
+ $helper = Mage::helper('panalysis_tagmanager');
136
+ try {
137
+ $rmProduct = array();
138
+ $tm = Mage::getSingleton('panalysis_tagmanager/tagmanager');
139
+ $current_updated = Mage::getSingleton('core/session')->getRmProducts();
140
+ if($current_updated) $rmProduct[] = $current_updated;
141
+ $rmProduct[] = $helper->CreateProductArray($product_id, $qty);
142
+ $session = Mage::getSingleton('core/session');
143
+ $session->setRmProducts($rmProduct);
144
+ } catch (exception $e) {
145
+ Mage::logException($e);
146
+ }
147
+ }
148
+
149
+ public function salesQuoteRemoveItem($observer)
150
+ {
151
+ $item = $observer->getQuoteItem()->getProduct();
152
+
153
+ $product = Mage::getModel('catalog/product')->load($item->getId());
154
+ if($product->getTypeId() === Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE)
155
+ {
156
+ $product = Mage::getModel('catalog/product')->loadByAttribute('sku', $item->getSku());
157
+ return $this->removeItemFromCart($product->getId(), $item->getQty());
158
+ }elseif($product->getTypeId() === Mage_Catalog_Model_Product_Type::TYPE_BUNDLE)
159
+ {
160
+ $qty = $item->getQty();
161
+ $quote_id = $observer->getQuoteItem()->getData('quote_id');
162
+ $quote_item_id = $observer->getQuoteItem()->getData('item_id');
163
+
164
+ $parent_quote = Mage::getModel("sales/quote")->load($quote_id);
165
+
166
+ $aChildQuoteItems = Mage::getModel("sales/quote_item")
167
+ ->getCollection()
168
+ ->setQuote($parent_quote)
169
+ ->addFieldToFilter("parent_item_id", $quote_item_id);
170
+
171
+ foreach ($aChildQuoteItems->getItems() as $child)
172
+ {
173
+ $this->removeItemFromCart($child->getProductId(), $item->getQty());
174
+ }
175
+
176
+ return true;
177
+ }else return $this->removeItemFromCart($product->getId(), $item->getQty());
178
+ }
179
+
180
+ public function checkoutCartEmpty()
181
+ {
182
+ $helper = Mage::helper('panalysis_tagmanager');
183
+ $post = Mage::app()->getRequest()->getPost('update_cart_action');
184
+ if ($post == 'empty_cart') {
185
+ $rmProducts = array();
186
+ try {
187
+ $quote = Mage::helper('checkout/cart')->getQuote(); //quote
188
+ $allQuoteItems = $quote->getAllItems(); // quote items
189
+ foreach ($allQuoteItems as $item) {
190
+ $product = Mage::getSingleton('catalog/product')->load($item->getProductId());
191
+ $tm = Mage::getSingleton('panalysis_tagmanager/tagmanager');
192
+ $rmProduct = $helper->CreateProductArray($product->getId(), $item->getQty());
193
+
194
+ $rmProducts[] = $rmProduct;
195
+ }
196
+ $session = Mage::getSingleton('core/session');
197
+ $session->setRmProducts($rmProducts);
198
+
199
+ } catch (exception $e) {
200
+ Mage::logException($e);
201
+ }
202
+ }
203
+ }
204
+
205
+ public function categoryView(Varien_Event_Observer $observer)
206
+ {
207
+ $helper = Mage::helper('panalysis_tagmanager');
208
+ $catProducts = array();
209
+ $_products = $observer->getEvent()->getCollection()->load();
210
+
211
+ $limit = $helper->getListMaxProducts();
212
+
213
+ if(Mage::app()->getRequest()->getModuleName() == 'catalogsearch') $view = 'Search Results';
214
+ else $view = 'category';
215
+
216
+ $i = 0;
217
+ foreach ($_products as $_product)
218
+ {
219
+ if($i >= $limit) break;
220
+
221
+ $prod = $helper->CreateProductArray($_product->getId());
222
+ $prod['list'] = $view;
223
+ $prod['position'] = ++$i;
224
+ $catProducts[] = $prod;
225
+ }
226
+
227
+ $dataLayer = $helper->buildCategoryData($catProducts);
228
+ $dataLayerJs = "<script type='text/javascript'>var dataLayer = dataLayer || []; dataLayer.push(" . json_encode($dataLayer,JSON_PRETTY_PRINT) .");</script>";
229
+
230
+ echo $dataLayerJs;
231
+
232
+ }
233
+
234
+ public function startCheckout($observer)
235
+ {
236
+ $myDataLayer = Mage::app()->getLayout()->createBlock('panalysis_tagmanager/tagmanager');
237
+ $tm = Mage::getSingleton('panalysis_tagmanager/tagmanager');
238
+ $tm->setCheckoutState("start");
239
+ Mage::dispatchEvent('panalysis_start_checkout');
240
+ }
241
+ }
app/code/community/Panalysis/TagManager/Model/Tagmanager.php ADDED
@@ -0,0 +1,205 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Panalysis_TagManager_Model_Tagmanager extends Mage_Core_Model_Abstract
4
+ {
5
+
6
+ public $checkoutState = "";
7
+ public $categoryProducts = array();
8
+
9
+ public function getAttributes($product)
10
+ {
11
+ $eavConfig = Mage::getModel('eav/config');
12
+ $attributes = $eavConfig->getEntityAttributeCodes(
13
+ Mage_Catalog_Model_Product::ENTITY,
14
+ $product
15
+ );
16
+ return $attributes;
17
+ }
18
+
19
+ /**
20
+ * @param $product
21
+ * @return mixed
22
+ */
23
+ public function getPrice($product_id)
24
+ {
25
+ $storeId = Mage::app()->getStore()->getStoreId();
26
+ $product = Mage::getModel('catalog/product')->setStoreId($storeId)->load($product_id);
27
+
28
+ $priceModel = $product->getPriceModel();
29
+ if ($product->getTypeId() === Mage_Catalog_Model_Product_Type::TYPE_BUNDLE) {
30
+ list($minimalPrice, $maximalPrice) = $priceModel->getTotalPrices($product, null, null, false);
31
+ $price = $minimalPrice;
32
+ } elseif ($product->isGrouped()) {
33
+ $prices = array();
34
+ foreach ($product->getTypeInstance(true)->getAssociatedProducts($product) as $assoProd) {
35
+ $prices[] = $assoProd->getFinalPrice();
36
+ }
37
+ $price = min($prices);
38
+ } else {
39
+ $price = $product->getFinalPrice();
40
+ }
41
+
42
+ $price = Mage::helper('core')->currency($price, false, false);
43
+ $final_price = Mage::app()->getStore()->roundPrice($price);
44
+
45
+ return $final_price;
46
+ }
47
+
48
+
49
+ public function getBrand($product)
50
+ {
51
+ $brand = '';
52
+ $product = Mage::getModel('catalog/product')->load($product->getID());
53
+ $brandAttr = Mage::helper('panalysis_tagmanager')->getBrandCode();
54
+ $attributes = $this->getAttributes($product);
55
+
56
+ if (in_array($brandAttr, $attributes) && @$product->getAttributeText($brandAttr)) {
57
+ $brand = @$product->getAttributeText($brandAttr);
58
+ } else {
59
+ if (in_array('manufacturer', $attributes)) {
60
+ $brand = @$product->getAttributeText('manufacturer');
61
+ }
62
+ }
63
+ return $brand;
64
+ }
65
+
66
+ public function getVariant($product)
67
+ {
68
+ $color = '';
69
+ $product = Mage::getModel('catalog/product')->load($product->getID());
70
+ $colorAttr = Mage::helper('panalysis_tagmanager')->getColorCode();
71
+ $attributes = $this->getAttributes($product);
72
+
73
+ if (in_array($colorAttr, $attributes)) {
74
+ $color = @$product->getAttributeText($colorAttr);
75
+ } else {
76
+ if (in_array('color', $attributes)) {
77
+ $color = @$product->getAttributeText('color');
78
+ }
79
+ }
80
+ return $color;
81
+ }
82
+
83
+ public function getCategory($product)
84
+ {
85
+ $category = Mage::registry('current_category');
86
+ $catName = '';
87
+ if (isset($category)) {
88
+ $catName = $category->getName();
89
+ } else {
90
+ $category = $product->getCategoryCollection()
91
+ ->addAttributeToSelect('name')
92
+ ->getFirstItem();
93
+ if($category->getName()) $catName = $category->getName();
94
+ }
95
+ return $catName;
96
+ }
97
+
98
+ public function getCatArray($product)
99
+ {
100
+ $cateNames = array();
101
+ $product = Mage::getModel('catalog/product')->load($product->getId());
102
+ $categoryCollection = $product->getCategoryCollection()->addAttributeToSelect('name');
103
+
104
+ foreach($categoryCollection as $category)
105
+ {
106
+ $cateNames[] = $category->getName();
107
+ }
108
+
109
+ return $cateNames;
110
+ }
111
+
112
+ public function setCheckoutState($state){
113
+ $this->state = $state;
114
+ }
115
+
116
+ public function getCheckoutState(){
117
+ return $this->state;
118
+ }
119
+
120
+ public function setCategoryProducts($list){
121
+ $this->categoryProducts = $list;
122
+ }
123
+
124
+ public function getCategoryProducts() {
125
+ return $this->categoryProducts;
126
+ }
127
+
128
+ // the following function is modified from https://github.com/CVM/Magento_GoogleTagManager
129
+
130
+ public function getVisitorData()
131
+ {
132
+ $data = array();
133
+ $customer = Mage::getSingleton('customer/session');
134
+
135
+ // visitorId
136
+ if ($customer->getCustomerId()) $data['visitorId'] = (string)$customer->getCustomerId();
137
+
138
+ // visitorLoginState
139
+ $data['visitorLoginState'] = ($customer->isLoggedIn()) ? 'Logged in' : 'Logged out';
140
+
141
+ // visitorType
142
+ $data['visitorType'] = (string)Mage::getModel('customer/group')->load($customer->getCustomerGroupId())->getCode();
143
+
144
+ $data = $this->getVisitorOrderData($customer);
145
+
146
+ return $data;
147
+ }
148
+
149
+ //check if user placed orders before and get total
150
+ private function getVisitorOrderData($customer = false)
151
+ {
152
+ $data = array();
153
+ $orders = false;
154
+
155
+ if(!$customer) $customer = Mage::getSingleton('customer/session');
156
+
157
+ if(Mage::getSingleton('customer/session')->isLoggedIn())
158
+ {
159
+ $orders = Mage::getResourceModel('sales/order_collection')->addFieldToSelect('grand_total')->addFieldToFilter('customer_id',$customer->getId());
160
+ $data['visitorExistingCustomer'] = 'Yes';
161
+ }else{
162
+
163
+ $quote = Mage::getSingleton('checkout/session')->getQuote();
164
+
165
+ $email = $quote->getBillingAddress()->getEmail();
166
+ $data['visitorExistingCustomer'] = 'No';
167
+
168
+ if($email)
169
+ {
170
+ $orders = Mage::getModel('sales/order')->getCollection();
171
+ $orders->addFieldToSelect('grand_total');
172
+ $orders->addFieldToFilter('customer_email', $email);
173
+
174
+ if($orders) $data['visitorExistingCustomer'] = 'Yes';
175
+ }
176
+ }
177
+
178
+ $ordersTotal = 0;
179
+ if($orders)
180
+ {
181
+ foreach ($orders as $order)
182
+ {
183
+ $ordersTotal += $order->getGrandTotal();
184
+ }
185
+ }
186
+
187
+ $data['visitorLifetimeValue'] = $this->convertCurrency($ordersTotal);
188
+
189
+ return $data;
190
+ }
191
+
192
+ private function convertCurrency($price)
193
+ {
194
+ $from = Mage::app()->getStore()->getBaseCurrencyCode();
195
+ $to = Mage::app()->getStore()->getCurrentCurrencyCode();
196
+
197
+ if($from != $to)
198
+ {
199
+ $price = Mage::helper('directory')->currencyConvert($price, $from, $to);
200
+ $price = Mage::app()->getStore()->roundPrice($price);
201
+ }
202
+
203
+ return $price;
204
+ }
205
+ }
app/code/community/Panalysis/TagManager/controllers/AjaxController.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Panalysis_Tagmanager_AjaxController extends Mage_Core_Controller_Front_Action
4
+ {
5
+ public function indexAction()
6
+ {
7
+ echo "Hi";
8
+
9
+ //$this->loadLayout();
10
+ //$this->renderLayout();
11
+ }
12
+
13
+ public function getCheckoutStateAction()
14
+ {
15
+ echo "start";
16
+ }
17
+
18
+ public function checkAjaxAction()
19
+ {
20
+ $session = Mage::getSingleton('core/session');
21
+ $ajax_flag = Mage::app()->getRequest()->getParam('ajax_layer', false);
22
+ $ajax_request = Mage::app()->getRequest()->isXmlHttpRequest();
23
+ $tmProduct = $session->getTmProduct();
24
+ $ajax_product = $session->getData('panalysis_tagmanager', false);
25
+
26
+ $data = array();
27
+ if ($ajax_product && $ajax_flag && $ajax_request && $tmProduct)
28
+ {
29
+ $helper = Mage::helper('panalysis_tagmanager');
30
+
31
+ $tmProduct = $session->getTmProduct();
32
+ if($tmProduct) $code = $helper->buildAddToCartData($tmProduct);
33
+ $session->unsTmProduct();
34
+ $session->unsData('panalysis_tagmanager');
35
+
36
+ $data['code'] = $code;
37
+ $data['response'] = 'datalayer';
38
+
39
+ }else{
40
+ $data['response'] = '';
41
+ }
42
+
43
+ $response = Mage::helper('core')->jsonEncode($data);
44
+
45
+ $this->getResponse()->clearHeaders()->setHeader('Content-type','application/json',true);
46
+ $this->getResponse()->setBody($response);
47
+ }
48
+
49
+ }
app/code/community/Panalysis/TagManager/etc/config.xml ADDED
@@ -0,0 +1,138 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Panalysis_TagManager>
5
+ <version>0.5.3</version>
6
+ </Panalysis_TagManager>
7
+ </modules>
8
+ <default>
9
+ <panalysis_tagmanager>
10
+ <gtm>
11
+ <max_products>25</max_products>
12
+ </gtm>
13
+ </panalysis_tagmanager>
14
+ </default>
15
+ <global>
16
+ <models>
17
+ <panalysis_tagmanager>
18
+ <class>Panalysis_TagManager_Model</class>
19
+ </panalysis_tagmanager>
20
+ </models>
21
+ <blocks>
22
+ <panalysis_tagmanager>
23
+ <class>Panalysis_TagManager_Block</class>
24
+ </panalysis_tagmanager>
25
+ </blocks>
26
+ <helpers>
27
+ <panalysis_tagmanager>
28
+ <class>Panalysis_TagManager_Helper</class>
29
+ </panalysis_tagmanager>
30
+ </helpers>
31
+ <events>
32
+ <checkout_cart_add_product_complete>
33
+ <observers>
34
+ <panalysis_tagmanager>
35
+ <type>singleton</type>
36
+ <class>panalysis_tagmanager/observer</class>
37
+ <method>checkoutCartAddProductComplete</method>
38
+ </panalysis_tagmanager>
39
+ </observers>
40
+ </checkout_cart_add_product_complete>
41
+
42
+ <checkout_cart_update_items_before>
43
+ <observers>
44
+ <panalysis_tagmanager>
45
+ <class>panalysis_tagmanager/observer</class>
46
+ <method>hookToUpdateToCart</method>
47
+ </panalysis_tagmanager>
48
+ </observers>
49
+ </checkout_cart_update_items_before>
50
+
51
+ <sales_quote_remove_item>
52
+ <observers>
53
+ <panalysis_tagmanager_remove_item>
54
+ <type>singleton</type>
55
+ <class>panalysis_tagmanager/observer</class>
56
+ <method>salesQuoteRemoveItem</method>
57
+ </panalysis_tagmanager_remove_item>
58
+ </observers>
59
+ </sales_quote_remove_item>
60
+
61
+ <controller_action_predispatch_checkout_cart_updatePost>
62
+ <observers>
63
+ <panalysis_tagmanager_empty_cart>
64
+ <type>singleton</type>
65
+ <class>panalysis_tagmanager/observer</class>
66
+ <method>checkoutCartEmpty</method>
67
+ </panalysis_tagmanager_empty_cart>
68
+ </observers>
69
+ </controller_action_predispatch_checkout_cart_updatePost>
70
+
71
+ <catalog_block_product_list_collection>
72
+ <observers>
73
+ <panalysis_tagmanager_category_view>
74
+ <type>singleton</type>
75
+ <class>panalysis_tagmanager/observer</class>
76
+ <method>categoryView</method>
77
+ </panalysis_tagmanager_category_view>
78
+ </observers>
79
+ </catalog_block_product_list_collection>
80
+
81
+ <controller_action_layout_render_before_checkout_onepage_index>
82
+ <observers>
83
+ <panalysis_tagmanager_start_checkout>
84
+ <type>singleton</type>
85
+ <class>panalysis_tagmanager/observer</class>
86
+ <method>startCheckout</method>
87
+ </panalysis_tagmanager_start_checkout>
88
+ </observers>
89
+ </controller_action_layout_render_before_checkout_onepage_index>
90
+ </events>
91
+ </global>
92
+ <frontend>
93
+ <routers>
94
+ <tagmanager>
95
+ <use>standard</use>
96
+ <args>
97
+ <module>Panalysis_TagManager</module>
98
+ <frontName>tagmanager</frontName>
99
+ </args>
100
+ </tagmanager>
101
+ </routers>
102
+ <layout>
103
+ <updates>
104
+ <panalysis_tagmanager>
105
+ <file>panalysis/tagmanager.xml</file>
106
+ </panalysis_tagmanager>
107
+ </updates>
108
+ </layout>
109
+ </frontend>
110
+ <adminhtml>
111
+ <layout>
112
+ <updates>
113
+ <panalysis_tagmanager>
114
+ <file>panalysis/tagmanager.xml</file>
115
+ </panalysis_tagmanager>
116
+ </updates>
117
+ </layout>
118
+ <acl>
119
+ <resources>
120
+ <admin>
121
+ <children>
122
+ <system>
123
+ <children>
124
+ <config>
125
+ <children>
126
+ <panalysis_tagmanager>
127
+ <title>Panalysis Tag Manager</title>
128
+ </panalysis_tagmanager>
129
+ </children>
130
+ </config>
131
+ </children>
132
+ </system>
133
+ </children>
134
+ </admin>
135
+ </resources>
136
+ </acl>
137
+ </adminhtml>
138
+ </config>
app/code/community/Panalysis/TagManager/etc/system.xml ADDED
@@ -0,0 +1,241 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <sections>
4
+ <panalysis_tagmanager translate="label" module="panalysis_tagmanager">
5
+ <label>Tag Management</label>
6
+ <class>separator-top</class>
7
+ <tab>general</tab>
8
+ <frontend_type>text</frontend_type>
9
+ <sort_order>9999</sort_order>
10
+ <show_in_default>1</show_in_default>
11
+ <show_in_website>1</show_in_website>
12
+ <show_in_store>1</show_in_store>
13
+ <groups>
14
+ <gtm translate="label">
15
+ <label>Google Tag Manager</label>
16
+ <sort_order>10</sort_order>
17
+ <show_in_default>1</show_in_default>
18
+ <show_in_website>1</show_in_website>
19
+ <show_in_store>1</show_in_store>
20
+ <expanded>true</expanded>
21
+ <comment><![CDATA[<span style="float:right;clear:right;margin-right:13px; width:200px;">
22
+ <div>
23
+ <a href="http://bit.ly/MagentoExtension" target="_blank"><img src="data:image/jpeg;base64,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" width=200 height=24 style="margin-bottom:20px;" alt="Panalysis - Experts in Web Analytics"/></a>
24
+ </div>
25
+ <strong><i>Tag Management makes your analytics much simpler.</i></strong>
26
+ <p>This extension will assist you to correctly implement the Google Tag Management service using the enhanced e-commerce settings via the data layer.</p>
27
+ <p>For support and assistance with this extension please visit <a href="http://bit.ly/MagentoExtension" target="_blank">the support page</a></p>
28
+ </span>
29
+ ]]></comment>
30
+ <fields>
31
+ <version translate="label">
32
+ <label>TagManager Version</label>
33
+ <frontend_type>select</frontend_type>
34
+ <frontend_model>Panalysis_TagManager_Block_Adminhtml_Version</frontend_model>
35
+ <sort_order>0</sort_order>
36
+ <show_in_default>1</show_in_default>
37
+ <show_in_website>1</show_in_website>
38
+ <show_in_store>1</show_in_store>
39
+ </version>
40
+ <containerid translate="label">
41
+ <label>Container ID</label>
42
+ <frontend_type>text</frontend_type>
43
+ <backend_model>Panalysis_TagManager_Model_Config_Data_NotEmpty</backend_model>
44
+ <comment>Please enter the container of your google tag manager account.</comment>
45
+ <sort_order>10</sort_order>
46
+ <show_in_default>1</show_in_default>
47
+ <show_in_website>1</show_in_website>
48
+ <show_in_store>1</show_in_store>
49
+ </containerid>
50
+ <brandcode translate="label">
51
+ <label>Brand Attribute Code</label>
52
+ <frontend_type>text</frontend_type>
53
+ <comment>Please enter the attribute code for manufacturer/brand attribute used in your website. If not specified, default manufacturer attribute would be used</comment>
54
+ <sort_order>20</sort_order>
55
+ <show_in_default>1</show_in_default>
56
+ <show_in_website>1</show_in_website>
57
+ <show_in_store>1</show_in_store>
58
+ </brandcode>
59
+ <colorcode translate="label">
60
+ <label>Product Color Attribute Code</label>
61
+ <frontend_type>text</frontend_type>
62
+ <comment>Please enter the attribute code for color/variant attribute used in your website. If not specified, default color attribute would be used</comment>
63
+ <sort_order>30</sort_order>
64
+ <show_in_default>1</show_in_default>
65
+ <show_in_website>1</show_in_website>
66
+ <show_in_store>1</show_in_store>
67
+ </colorcode>
68
+ <enable_product_lists translate="label">
69
+ <label>Enable Product List View Tracking</label>
70
+ <frontend_type>select</frontend_type>
71
+ <source_model>adminhtml/system_config_source_yesno</source_model>
72
+ <comment>Turn this on if you would like to track product list impressions.</comment>
73
+ <sort_order>40</sort_order>
74
+ <show_in_default>1</show_in_default>
75
+ <show_in_website>1</show_in_website>
76
+ <show_in_store>1</show_in_store>
77
+ </enable_product_lists>
78
+
79
+
80
+ <max_products translate="label">
81
+ <label>Maximum number of products in list</label>
82
+ <frontend_type>text</frontend_type>
83
+ <comment>Due to limits in Google Analytics longer product lists will prevent the data being sent to Google Analytics</comment>
84
+ <sort_order>50</sort_order>
85
+ <show_in_default>1</show_in_default>
86
+ <show_in_website>1</show_in_website>
87
+ <show_in_store>1</show_in_store>
88
+ <depends>
89
+ <enable_product_lists>1</enable_product_lists>
90
+ </depends>
91
+ </max_products>
92
+ <enable_ajax translate="label">
93
+ <label>Enable ajax add to cart tracking</label>
94
+ <frontend_type>select</frontend_type>
95
+ <source_model>adminhtml/system_config_source_yesno</source_model>
96
+ <comment>Turn this on if site does suppot ajax add to cart feature</comment>
97
+ <sort_order>60</sort_order>
98
+ <show_in_default>1</show_in_default>
99
+ <show_in_website>1</show_in_website>
100
+ <show_in_store>1</show_in_store>
101
+ </enable_ajax>
102
+ </fields>
103
+ </gtm>
104
+ <opengraph translate="label">
105
+ <label>Open Graph for Facebook and Twitter Cards</label>
106
+ <sort_order>20</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
+ <expanded>true</expanded>
111
+ <comment><![CDATA[<p>Enabling this feature will insert the Open Graph tags for Facebook and optionally for Twitter Cards.</p>]]></comment>
112
+ <fields>
113
+ <is_enabled translate="label">
114
+ <label>Enabled</label>
115
+ <frontend_type>select</frontend_type>
116
+ <source_model>adminhtml/system_config_source_yesno</source_model>
117
+ <sort_order>10</sort_order>
118
+ <show_in_default>1</show_in_default>
119
+ <show_in_website>1</show_in_website>
120
+ <show_in_store>1</show_in_store>
121
+ </is_enabled>
122
+
123
+ <facebookappid translate="label">
124
+ <label>Facebook App ID</label>
125
+ <frontend_type>text</frontend_type>
126
+ <backend_model>Panalysis_TagManager_Model_Config_Data_NotEmpty</backend_model>
127
+ <comment>Please enter your Facebook App ID if you are using Open Graph.</comment>
128
+ <sort_order>20</sort_order>
129
+ <show_in_default>1</show_in_default>
130
+ <show_in_website>1</show_in_website>
131
+ <show_in_store>1</show_in_store>
132
+ <depends>
133
+ <is_enabled>1</is_enabled>
134
+ </depends>
135
+ </facebookappid>
136
+
137
+ <facebookadminid translate="label">
138
+ <label>Facebook Admin ID</label>
139
+ <frontend_type>text</frontend_type>
140
+ <backend_model>Panalysis_TagManager_Model_Config_Data_NotEmpty</backend_model>
141
+ <comment>Please enter your Facebook Admin ID if you are using Open Graph.</comment>
142
+ <sort_order>20</sort_order>
143
+ <show_in_default>1</show_in_default>
144
+ <show_in_website>1</show_in_website>
145
+ <show_in_store>1</show_in_store>
146
+ <depends>
147
+ <is_enabled>1</is_enabled>
148
+ </depends>
149
+ </facebookadminid>
150
+
151
+ <pinterestid translate="label">
152
+ <label>Pinterest Domain Verification Code</label>
153
+ <frontend_type>text</frontend_type>
154
+ <comment>If you want to set up Pinterest to confirm your website enter the token here. https://help.pinterest.com/en/articles/confirm-your-website</comment>
155
+ <sort_order>20</sort_order>
156
+ <show_in_default>1</show_in_default>
157
+ <show_in_website>1</show_in_website>
158
+ <show_in_store>1</show_in_store>
159
+ <depends>
160
+ <is_enabled>1</is_enabled>
161
+ </depends>
162
+ </pinterestid>
163
+
164
+ <use_twittercards translate="label">
165
+ <label>Use Twitter Cards</label>
166
+ <frontend_type>select</frontend_type>
167
+ <source_model>adminhtml/system_config_source_yesno</source_model>
168
+ <sort_order>30</sort_order>
169
+ <show_in_default>1</show_in_default>
170
+ <show_in_website>1</show_in_website>
171
+ <show_in_store>1</show_in_store>
172
+ <depends>
173
+ <is_enabled>1</is_enabled>
174
+ </depends>
175
+ </use_twittercards>
176
+
177
+ <twitterstoreid>
178
+ <label>Twitter Store Username</label>
179
+ <frontend_type>text</frontend_type>
180
+ <backend_model>Panalysis_TagManager_Model_Config_Data_NotEmpty</backend_model>
181
+ <comment>Please enter your Twitter ID (@...) for your store</comment>
182
+ <sort_order>40</sort_order>
183
+ <show_in_default>1</show_in_default>
184
+ <show_in_website>1</show_in_website>
185
+ <show_in_store>1</show_in_store>
186
+ <depends>
187
+ <is_enabled>1</is_enabled>
188
+ <use_twittercards>1</use_twittercards>
189
+ </depends>
190
+ </twitterstoreid>
191
+
192
+ <twittercreatorid>
193
+ <label>Twitter Creator Username</label>
194
+ <frontend_type>text</frontend_type>
195
+ <comment>If you want to specify a separate Twitter user name for content authorship then enter a value here. The store username will be used if no value is entered here.</comment>
196
+ <sort_order>45</sort_order>
197
+ <show_in_default>1</show_in_default>
198
+ <show_in_website>1</show_in_website>
199
+ <show_in_store>1</show_in_store>
200
+ <depends>
201
+ <is_enabled>1</is_enabled>
202
+ <use_twittercards>1</use_twittercards>
203
+ </depends>
204
+ </twittercreatorid>
205
+
206
+ <use_largeimage translate="label">
207
+ <label>Use Twitter Summary Card with Large Image Feature?</label>
208
+ <frontend_type>select</frontend_type>
209
+ <source_model>adminhtml/system_config_source_yesno</source_model>
210
+ <sort_order>46</sort_order>
211
+ <show_in_default>1</show_in_default>
212
+ <show_in_website>1</show_in_website>
213
+ <show_in_store>1</show_in_store>
214
+ <depends>
215
+ <is_enabled>1</is_enabled>
216
+ <use_twittercards>1</use_twittercards>
217
+ </depends>
218
+ </use_largeimage>
219
+
220
+ <twitterimage translate="label comment">
221
+ <label>Default Twitter Card Image</label>
222
+ <comment>Allowed file types: jpeg, gif, png. Note that for products the product image will be used.</comment>
223
+ <sort_order>47</sort_order>
224
+ <frontend_type>image</frontend_type>
225
+ <backend_model>adminhtml/system_config_backend_image</backend_model>
226
+ <upload_dir config="system/filesystem/media" scope_info="1">theme</upload_dir>
227
+ <base_url type="media" scope_info="1">theme</base_url>
228
+ <show_in_default>1</show_in_default>
229
+ <show_in_website>1</show_in_website>
230
+ <show_in_store>1</show_in_store>
231
+ <depends>
232
+ <is_enabled>1</is_enabled>
233
+ <use_twittercards>1</use_twittercards>
234
+ </depends>
235
+ </twitterimage>
236
+ </fields>
237
+ </opengraph>
238
+ </groups>
239
+ </panalysis_tagmanager>
240
+ </sections>
241
+ </config>
app/design/frontend/base/default/layout/panalysis/tagmanager.xml ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+
3
+ <layout version="0.1.0">
4
+ <default>
5
+ <reference name="after_body_start">
6
+ <block type="panalysis_tagmanager/tagmanager" name="tag.manager" as="gtm"
7
+ template="panalysis/tagmanager/tagmanager.phtml"></block>
8
+ </reference>
9
+ <reference name="head">
10
+ <block type="panalysis_tagmanager/tagmanager" name="datalayer"
11
+ template="panalysis/tagmanager/datalayer.phtml"></block>
12
+ </reference>
13
+ <reference name="head">
14
+ <block type="panalysis_tagmanager/tagmanager" name="opengraph"
15
+ template="panalysis/tagmanager/opengraph.phtml"></block>
16
+ </reference>
17
+ </default>
18
+ </layout>
app/design/frontend/base/default/template/panalysis/tagmanager/datalayer.phtml ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $helper = Mage::helper('panalysis_tagmanager');
3
+
4
+ $contId = $helper->getContainerId();
5
+ $checkoutState = $this->getCheckoutState();
6
+ if(isset($contId)):
7
+ ?>
8
+ <script type="text/javascript">
9
+ var dataLayer = dataLayer || [];
10
+ <?php echo $this->buildDataLayer();?>
11
+ <?php if($helper->AjaxEnabled() && Mage::app()->getRequest()->getModuleName() != 'checkout'): ?>
12
+ Ajax.Responders.register({
13
+ onCreate: function() {
14
+ //create ajax request
15
+ },
16
+ onComplete: function() {
17
+ jQuery.ajax({
18
+ url: "<?php echo $this->getUrl('tagmanager/ajax/checkAjax') ?>",
19
+ dataType: 'json',
20
+ data: "ajax_layer=1",
21
+ success: function(e, xhr, settings) {
22
+ var data = (e);
23
+
24
+ if(settings.status == 200 && data.response == 'datalayer')
25
+ {
26
+ dataLayer.push(data.code);
27
+ }
28
+ }
29
+ });
30
+ }
31
+ });
32
+ <?php endif ?>
33
+ </script>
34
+ <?php endif; ?>
35
+
app/design/frontend/base/default/template/panalysis/tagmanager/opengraph.phtml ADDED
@@ -0,0 +1,85 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $helper = Mage::helper('panalysis_tagmanager');
3
+ $tm = Mage::getSingleton('panalysis_tagmanager/tagmanager');
4
+
5
+ $storeId = Mage::app()->getStore()->getStoreId();
6
+
7
+ $pgtm_og = [];
8
+
9
+ $pgtm_og['page_type'] = $this->getPage();
10
+
11
+ $pgtm_og['title'] = htmlspecialchars($this->getLayout()->getBlock('head')->getTitle(),ENT_QUOTES, null, false);
12
+
13
+ $pgtm_og['fbappid'] = $helper->getFacebookAppId();
14
+ $pgtm_og['fbadminid'] = $helper->getFacebookAdminId();
15
+ $pgtm_og['pinterestid'] = $helper->getPinterestId();
16
+
17
+ $pgtm_twitter = $this->getTwitterDetails();
18
+
19
+ if($helper->useOpenGraph()):
20
+ ?>
21
+
22
+ <?php if( $pgtm_og['fbappid'] != ""): ?>
23
+ <meta property="fb:app_id" content="<?php echo $pgtm_og['fbappid']; ?>" />
24
+ <?php endif;?>
25
+ <?php if( $pgtm_og['fbadminid'] != ""): ?>
26
+ <meta property="fb:admins" content="<?php echo $pgtm_og['fbadminid']; ?>" />
27
+ <?php endif;?>
28
+ <?php if( $pgtm_og['pinterestid'] != ""): ?>
29
+ <meta name="p:domain_verify" content="<?php echo $pgtm_og['pinterestid']; ?>"/>
30
+ <?php endif;?>
31
+
32
+
33
+ <?php if( $helper->useTwitterCards()): ?>
34
+
35
+ <meta property="twitter:card" content="<?php echo $pgtm_twitter['card_format']; ?>" />
36
+ <meta property="twitter:site" content="<?php echo $pgtm_twitter['store_username']; ?>" />
37
+ <meta property="twitter:creator" content="<?php echo $pgtm_twitter['creator_username']; ?>" />
38
+ <meta property="twitter:image" content="<?php echo $pgtm_twitter['image']; ?>" />
39
+
40
+ <?php endif;?>
41
+
42
+ <meta property="og:title" content="<?php echo $pgtm_og['title']; ?>" />
43
+ <meta property="og:type" content="product" />
44
+ <?php
45
+ if($pgtm_og['page_type']=="Product Detail"):
46
+ if(Mage::registry('current_product')):
47
+ $pan_product_id = Mage::registry('current_product')->getId();
48
+ $pan_product= Mage::getModel('catalog/product')->setStoreId($storeId)->load($pan_product_id);
49
+ ?>
50
+ <meta property="og:url" content="<?php echo $pan_product->getUrlInStore(array('_ignore_category' => true)); ?>"/>
51
+ <meta property="og:description" content="<?php echo Mage::helper('core')->quoteEscape($pan_product->getDescription()) ?>"/>
52
+ <?php
53
+ if($pan_product->getTypeId() === Mage_Catalog_Model_Product_Type::TYPE_GROUPED)
54
+ {
55
+ foreach ($pan_product->getTypeInstance(true)->getAssociatedProducts($pan_product) as $assoProd)
56
+ {
57
+ echo('<meta property="product:price:amount" content="'.$tm->getPrice($assoProd->getId()).'"/>'."\n");
58
+ }
59
+ echo('<meta property="product:price:currency" content="' . Mage::app()->getStore()->getCurrentCurrencyCode() . '"/>'."\n");
60
+ }elseif($pan_product->getTypeId() === Mage_Catalog_Model_Product_Type::TYPE_BUNDLE)
61
+ {
62
+ $associated_ids = $helper->getBundleProducts($pan_product_id);
63
+ foreach($associated_ids as $child)
64
+ {
65
+ echo('<meta property="product:price:amount" content="'.$tm->getPrice($child).'"/>'."\n");
66
+ }
67
+ echo('<meta property="product:price:currency" content="' . Mage::app()->getStore()->getCurrentCurrencyCode() . '"/>'."\n");
68
+ }else{
69
+ echo('<meta property="product:price:amount" content="'.$tm->getPrice($pan_product_id).'"/>'."\n");
70
+ echo('<meta property="product:price:currency" content="' . Mage::app()->getStore()->getCurrentCurrencyCode() . '"/>'."\n");
71
+ }
72
+ endif;
73
+ endif;
74
+
75
+ if($pgtm_og['page_type']=="Product Category"):
76
+ ?>
77
+ <meta property="og:type" content="product.group" />
78
+ <meta property="og:url" content="<?php echo Mage::helper('core/url')->getCurrentUrl() ?>"/>
79
+ <?php
80
+ endif;
81
+ endif
82
+ ?>
83
+
84
+
85
+
app/design/frontend/base/default/template/panalysis/tagmanager/tagmanager.phtml ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ $helper = Mage::helper('panalysis_tagmanager');
3
+ $contId = $helper->getContainerId();
4
+ ?>
5
+ <!-- Start Google Tag Manager -->
6
+ <?php if(isset($contId)): ?>
7
+
8
+
9
+ <!-- Google Tag Manager -->
10
+ <noscript><iframe src="//www.googletagmanager.com/ns.html?id=<?php echo $contId; ?>"
11
+ height="0" width="0" style="display:none;visibility:hidden"></iframe></noscript>
12
+ <script>(function(w,d,s,l,i){w[l]=w[l]||[];w[l].push({'gtm.start':
13
+ new Date().getTime(),event:'gtm.js'});var f=d.getElementsByTagName(s)[0],
14
+ j=d.createElement(s),dl=l!='dataLayer'?'&l='+l:'';j.async=true;j.src=
15
+ '//www.googletagmanager.com/gtm.js?id='+i+dl;f.parentNode.insertBefore(j,f);
16
+ })(window,document,'script','dataLayer','<?php echo $contId; ?>');</script>
17
+ <!-- End Google Tag Manager -->
18
+ <?php endif; ?>
app/etc/modules/Panalysis_TagManager.xml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Panalysis_TagManager>
5
+ <active>true</active>
6
+ <codePool>community</codePool>
7
+ </Panalysis_TagManager>
8
+ </modules>
9
+ </config>
package.xml ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>Panalysis_TagManager</name>
4
+ <version>0.5.3</version>
5
+ <stability>beta</stability>
6
+ <license uri="https://gnu.org/licenses/gpl.html">GPL Version 3</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>Provides support for the Google Tag Manager service with enhanced ecommerce as well as the Open Graph protocol and Twitter Card extensions.</summary>
10
+ <description>This extension provides a seamless way of connecting to the Google Tag Manager service by adding both the code snippet and the data layer with enhanced ecommerce references.&#xD;
11
+ &#xD;
12
+ In addition to this it also provides support for the Open Graph tags used by Facebook and Pinterest as well as the Twitter Card extensions</description>
13
+ <notes>Late beta release. This has been tested on 1.8 and 1.9 editions plus 1.4.1.1</notes>
14
+ <authors><author><name>Rod Jacka</name><user>panalysis</user><email>support@panalysis.com</email></author></authors>
15
+ <date>2016-03-03</date>
16
+ <time>23:13:23</time>
17
+ <contents><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><dir name="panalysis"><file name="tagmanager.xml" hash="84d5ada43613ce1dd51bc183fd7c5dbe"/></dir></dir><dir name="template"><dir name="panalysis"><dir name="tagmanager"><file name="datalayer.phtml" hash="ea18b8a3fc88218277baea41fc982da9"/><file name="opengraph.phtml" hash="9007cb51318e4455fc39cf4427e7b5e9"/><file name="tagmanager.phtml" hash="c15ee13fed00384e39e6b964e7924dd3"/></dir></dir></dir></dir></dir></dir></target><target name="magecommunity"><dir name="Panalysis"><dir name="TagManager"><dir name="Block"><dir name="Adminhtml"><file name="Version.php" hash="0edf6f9f427413344f8b2688211be290"/></dir><file name="Tagmanager.php" hash="d2207e03645af566c7fd23fb41e30d3e"/></dir><dir name="Helper"><file name="Data.php" hash="2da425e8dd49f3c438d3a28d18b79f3f"/></dir><dir name="Model"><dir name="Config"><dir name="Data"><file name="NotEmpty.php" hash="a38fa920e7f7c0505c7d17ed381f0e13"/></dir></dir><file name="Observer.php" hash="1627ce3abc61982b5fb353035ef51915"/><file name="Tagmanager.php" hash="b48095724c27b870ef9875ceb33ebe24"/></dir><dir name="controllers"><file name="AjaxController.php" hash="8b6a10a6796078adb0a3490cc4c07d51"/></dir><dir name="etc"><file name="config.xml" hash="06d0c7de0bdfd44260d68b6469c830c5"/><file name="system.xml" hash="29d391af2cf654dfb55dbb5932fcb646"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Panalysis_TagManager.xml" hash="04297a3ffe4f6462aa77006fc8076538"/></dir></target></contents>
18
+ <compatible/>
19
+ <dependencies><required><php><min>5.4.38</min><max>5.6.11</max></php></required></dependencies>
20
+ </package>