Ometria_Magento_Extension - Version 1.0.0

Version Notes

Release of new extension.

Download this release

Release Info

Developer Alastair James
Extension Ometria_Magento_Extension
Version 1.0.0
Comparing to
See all releases


Version 1.0.0

Files changed (45) hide show
  1. app/code/community/Ometria/AbandonedCarts/Helper/Config.php +16 -0
  2. app/code/community/Ometria/AbandonedCarts/Helper/Data.php +13 -0
  3. app/code/community/Ometria/AbandonedCarts/controllers/CartlinkController.php +60 -0
  4. app/code/community/Ometria/AbandonedCarts/etc/config.xml +60 -0
  5. app/code/community/Ometria/AbandonedCarts/etc/system.xml +59 -0
  6. app/code/community/Ometria/Api/Helper/Data.php +3 -0
  7. app/code/community/Ometria/Api/Model/Api.php +459 -0
  8. app/code/community/Ometria/Api/Model/Api2.php +1088 -0
  9. app/code/community/Ometria/Api/etc/api.xml +193 -0
  10. app/code/community/Ometria/Api/etc/config.xml +34 -0
  11. app/code/community/Ometria/Core/.DS_Store +0 -0
  12. app/code/community/Ometria/Core/Block/Adminhtml/System/Config/Startwizard.php +27 -0
  13. app/code/community/Ometria/Core/Block/Adminhtml/Wizard/Finished.php +33 -0
  14. app/code/community/Ometria/Core/Block/Adminhtml/Wizard/Start.php +20 -0
  15. app/code/community/Ometria/Core/Block/Adminhtml/Wizard/Start/Form.php +31 -0
  16. app/code/community/Ometria/Core/Block/Head.php +252 -0
  17. app/code/community/Ometria/Core/Helper/Config.php +37 -0
  18. app/code/community/Ometria/Core/Helper/Cookiechannel.php +47 -0
  19. app/code/community/Ometria/Core/Helper/Data.php +12 -0
  20. app/code/community/Ometria/Core/Helper/Ping.php +99 -0
  21. app/code/community/Ometria/Core/Helper/Product.php +74 -0
  22. app/code/community/Ometria/Core/Helper/Session.php +17 -0
  23. app/code/community/Ometria/Core/Model/.DS_Store +0 -0
  24. app/code/community/Ometria/Core/Model/Config/Source/Productmode.php +12 -0
  25. app/code/community/Ometria/Core/Model/Observer/Cart.php +65 -0
  26. app/code/community/Ometria/Core/Model/Observer/Customer.php +43 -0
  27. app/code/community/Ometria/Core/Model/Observer/Newsletter.php +30 -0
  28. app/code/community/Ometria/Core/Model/Observer/Order.php +19 -0
  29. app/code/community/Ometria/Core/Model/Observer/Product.php +91 -0
  30. app/code/community/Ometria/Core/Test/Config/Base.php +30 -0
  31. app/code/community/Ometria/Core/Test/Model/Observer/Order.php +23 -0
  32. app/code/community/Ometria/Core/Test/Model/Observer/Product.php +42 -0
  33. app/code/community/Ometria/Core/controllers/WizardController.php +134 -0
  34. app/code/community/Ometria/Core/etc/config.xml +243 -0
  35. app/code/community/Ometria/Core/etc/system.xml +130 -0
  36. app/design/adminhtml/default/default/layout/ometria/core.xml +16 -0
  37. app/design/adminhtml/default/default/template/ometria/system/config/start_wizard.phtml +14 -0
  38. app/design/adminhtml/default/default/template/ometria/wizard/finished.phtml +19 -0
  39. app/design/frontend/base/default/layout/ometria/core.xml +14 -0
  40. app/design/frontend/base/default/template/ometria/head.phtml +28 -0
  41. app/etc/modules/Ometria_AbandonedCarts.xml +9 -0
  42. app/etc/modules/Ometria_Api.xml +9 -0
  43. app/etc/modules/Ometria_Core.xml +14 -0
  44. js/ometria/checkout.js +13 -0
  45. package.xml +31 -0
app/code/community/Ometria/AbandonedCarts/Helper/Config.php ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Ometria_AbandonedCarts_Helper_Config extends Mage_Core_Helper_Abstract {
4
+
5
+ public function getCartUrl($store_id=null) {
6
+ return Mage::getStoreConfig('ometria_abandonedcarts/abandonedcarts/cartpath', $store_id);
7
+ }
8
+
9
+ public function isDeeplinkEnabled() {
10
+ return Mage::getStoreConfigFlag('ometria_abandonedcarts/abandonedcarts/enabled');
11
+ }
12
+
13
+ public function shouldCheckDeeplinkgToken() {
14
+ return Mage::getStoreConfigFlag('ometria_abandonedcarts/abandonedcarts/check_token');
15
+ }
16
+ }
app/code/community/Ometria/AbandonedCarts/Helper/Data.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Ometria_AbandonedCarts_Helper_Data extends Mage_Core_Helper_Abstract {
4
+
5
+ /**
6
+ * Get extension version
7
+ * @return string
8
+ */
9
+ public function getExtensionVersion() {
10
+ return Mage::getConfig()->getModuleConfig('Ometria_AbandonedCarts')->version;
11
+ }
12
+
13
+ }
app/code/community/Ometria/AbandonedCarts/controllers/CartlinkController.php ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once Mage::getModuleDir('controllers','Mage_Checkout').DS.'CartController.php';
4
+
5
+ class Ometria_AbandonedCarts_CartlinkController extends Mage_Checkout_CartController
6
+ {
7
+ public function indexAction(){
8
+
9
+ $message_incorrect_link = 'Cart link is incorrect or expired';
10
+
11
+ $session = Mage::getSingleton('customer/session');
12
+ $helper = Mage::helper('ometria_abandonedcarts/config');
13
+
14
+ if (!$helper->isDeeplinkEnabled()){
15
+ $this->_redirect('');
16
+ return;
17
+ }
18
+
19
+ $token = $this->getRequest()->getParam('token');
20
+ $id = $this->getRequest()->getParam('id');
21
+
22
+ $is_ok = false;
23
+
24
+ if ($id && $token){
25
+ $quote = Mage::getModel('sales/quote')->load($id);
26
+
27
+ if (!$quote || !$quote->getId()){
28
+ $session->addNotice($message_incorrect_link);
29
+ $this->_redirect('');
30
+ return;
31
+ }
32
+
33
+ if ($helper->shouldCheckDeeplinkgToken()){
34
+ $computed_token = md5($quote->created_at.$quote->remote_ip);
35
+
36
+ if ($token!=$computed_token) {
37
+ $session->addNotice($message_incorrect_link);
38
+ $this->_redirect('');
39
+ return;
40
+ }
41
+ }
42
+
43
+ $quote->setIsActive(true);
44
+ $quote->save();
45
+
46
+ $this->_getSession()->setQuoteId($quote->getId());
47
+
48
+ // @todo set cookie channel for new basket
49
+
50
+ $cart_path = $helper->getCartUrl();
51
+ if (substr($cart_path,0,7)=='http://' || substr($cart_path,0,8)=='https://'){
52
+ $this->_redirectUrl($cart_path);
53
+ } else {
54
+ $this->_redirect($cart_path);
55
+ }
56
+ } else {
57
+ $this->_redirect('');
58
+ }
59
+ }
60
+ }
app/code/community/Ometria/AbandonedCarts/etc/config.xml ADDED
@@ -0,0 +1,60 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Ometria_AbandonedCarts>
5
+ <version>1.0.0</version>
6
+ </Ometria_AbandonedCarts>
7
+ </modules>
8
+
9
+ <global>
10
+ <helpers>
11
+ <ometria_abandonedcarts>
12
+ <class>Ometria_AbandonedCarts_Helper</class>
13
+ </ometria_abandonedcarts>
14
+ </helpers>
15
+ </global>
16
+
17
+ <frontend>
18
+ <routers>
19
+ <omcart>
20
+ <use>standard</use>
21
+ <args>
22
+ <module>Ometria_AbandonedCarts</module>
23
+ <frontName>omcart</frontName>
24
+ </args>
25
+ </omcart>
26
+ </routers>
27
+ </frontend>
28
+
29
+ <default>
30
+ <ometria_abandonedcarts>
31
+ <abandonedcarts>
32
+ <cartpath>checkout/cart</cartpath>
33
+ <enabled>1</enabled>
34
+ <check_token>1</check_token>
35
+ </abandonedcarts>
36
+ </ometria_abandonedcarts>
37
+ </default>
38
+
39
+ <adminhtml>
40
+ <acl>
41
+ <resources>
42
+ <admin>
43
+ <children>
44
+ <system>
45
+ <children>
46
+ <config>
47
+ <children>
48
+ <ometria_abandonedcarts>
49
+ <title>Ometria Cart Abandonment</title>
50
+ </ometria_abandonedcarts>
51
+ </children>
52
+ </config>
53
+ </children>
54
+ </system>
55
+ </children>
56
+ </admin>
57
+ </resources>
58
+ </acl>
59
+ </adminhtml>
60
+ </config>
app/code/community/Ometria/AbandonedCarts/etc/system.xml ADDED
@@ -0,0 +1,59 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <config>
3
+ <tabs>
4
+ <ometria translate="label" module="ometria">
5
+ <label>Ometria</label>
6
+ <sort_order>450</sort_order>
7
+ </ometria>
8
+ </tabs>
9
+ <sections>
10
+ <ometria_abandonedcarts translate="label" module="ometria_abandonedcarts">
11
+ <label>Cart Abandonment</label>
12
+ <tab>ometria</tab>
13
+ <frontend_type>text</frontend_type>
14
+ <sort_order>2</sort_order>
15
+ <show_in_default>1</show_in_default>
16
+ <show_in_website>0</show_in_website>
17
+ <show_in_store>0</show_in_store>
18
+ <groups>
19
+ <abandonedcarts translate="label" module="ometria_abandonedcarts">
20
+ <label>Cart Deeplink Settings</label>
21
+ <frontend_type>text</frontend_type>
22
+ <sort_order>10</sort_order>
23
+ <show_in_default>1</show_in_default>
24
+ <show_in_website>0</show_in_website>
25
+ <show_in_store>0</show_in_store>
26
+ <fields>
27
+ <cartpath translate="label" module="ometria_abandonedcarts">
28
+ <label>Checkout Cart Path</label>
29
+ <frontend_type>text</frontend_type>
30
+ <sort_order>20</sort_order>
31
+ <show_in_default>1</show_in_default>
32
+ <show_in_website>0</show_in_website>
33
+ <show_in_store>0</show_in_store>
34
+ <default>/checkout/cart</default>
35
+ </cartpath>
36
+ <enabled translate="label" module="ometria">
37
+ <label>Deeplink enabled</label>
38
+ <frontend_type>select</frontend_type>
39
+ <source_model>adminhtml/system_config_source_yesno</source_model>
40
+ <sort_order>11</sort_order>
41
+ <show_in_default>1</show_in_default>
42
+ <show_in_website>0</show_in_website>
43
+ <show_in_store>0</show_in_store>
44
+ </enabled>
45
+ <check_token translate="label" module="ometria">
46
+ <label>Check Deeplink Token</label>
47
+ <frontend_type>select</frontend_type>
48
+ <source_model>adminhtml/system_config_source_yesno</source_model>
49
+ <sort_order>15</sort_order>
50
+ <show_in_default>1</show_in_default>
51
+ <show_in_website>0</show_in_website>
52
+ <show_in_store>0</show_in_store>
53
+ </check_token>
54
+ </fields>
55
+ </abandonedcarts>
56
+ </groups>
57
+ </ometria_abandonedcarts>
58
+ </sections>
59
+ </config>
app/code/community/Ometria/Api/Helper/Data.php ADDED
@@ -0,0 +1,3 @@
 
 
 
1
+ <?php
2
+ class Ometria_Api_Helper_Data extends Mage_Core_Helper_Abstract {
3
+ }
app/code/community/Ometria/Api/Model/Api.php ADDED
@@ -0,0 +1,459 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Ometria_Api_Model_Api extends Mage_Api_Model_Resource_Abstract {
3
+
4
+ /**
5
+ * Return current Ometria API version
6
+ */
7
+ public function version(){
8
+ return "3.0";
9
+ }
10
+
11
+ public function get_stock_levels($ids){
12
+ return $this->proxyApi('Mage_CatalogInventory_Model_Stock_Item_Api', 'items', array($ids));
13
+ }
14
+
15
+ public function list_stores(){
16
+ return $this->proxyApi('Mage_Core_Model_Store_Api', 'items');
17
+ }
18
+
19
+ public function list_categories(){
20
+ return $this->proxyApi('Mage_Catalog_Model_Category_Api', 'tree');
21
+ }
22
+
23
+ public function list_attributes(){
24
+ $attr_sets = $this->proxyApi('Mage_Catalog_Model_Product_Attribute_Set_Api', 'items');
25
+
26
+ foreach($attr_sets as &$attr_set){
27
+ $attr_set['attributes'] = $this->proxyApi('Mage_Catalog_Model_Product_Attribute_Api', 'items', array($attr_set['set_id']));
28
+ }
29
+
30
+ return $attr_sets;
31
+ }
32
+
33
+ public function list_attribute_options($attributeId){
34
+ return $this->proxyApi('Mage_Catalog_Model_Product_Attribute_Api', 'options', array($attributeId));
35
+ }
36
+
37
+ protected function proxyApi($model_class, $method, $args=array()){
38
+ $m = new $model_class();
39
+ return call_user_func_array(array($m, $method), $args);
40
+ }
41
+
42
+ public function list_subscribers($page=1, $pageSize=100){
43
+ $collection = Mage::getModel('newsletter/subscriber')->getCollection();
44
+
45
+ // setPage does not exist on this collection.
46
+ // Access lower lever setters.
47
+ $collection->setCurPage($page);
48
+ $collection->setPageSize($pageSize);
49
+
50
+ $collection->load();
51
+
52
+ $ret = array();
53
+
54
+ foreach($collection as $item){
55
+ $ret[] = array(
56
+ 'customer_id'=>$item->customer_id,
57
+ 'email'=>$item->subscriber_email,
58
+ 'store_id'=>$item->store_id,
59
+ 'status'=>$item->subscriber_status
60
+ );
61
+ }
62
+
63
+ return $ret;
64
+ }
65
+
66
+ public function list_customers($filters, $page = null, $pageSize = null) {
67
+ list ($from, $to, $page, $pageSize) = $this->_handleParameters($filters, $page, $pageSize);
68
+
69
+ $collection = Mage::getModel('customer/customer')->getCollection();
70
+
71
+ if ($from) $collection->addAttributeToFilter('updated_at', array('gteq' => $from->format('Y-m-d H:i:s')));
72
+ if ($to) $collection->addAttributeToFilter('updated_at', array('lteq' => $to->format('Y-m-d H:i:s')));
73
+
74
+ if ($page && $pageSize) {
75
+ $collection->setPage($page, $pageSize);
76
+ }
77
+ $collection->load();
78
+
79
+ return $collection->getLoadedIds();
80
+ }
81
+
82
+ public function get_customers($ids) {
83
+ /*$submodel = null;
84
+ try{
85
+ $submodel = Mage::getModel('newsletter/subscriber');
86
+ } catch (Exception $e) {
87
+ // pass
88
+ $submodel = null;
89
+ }*/
90
+
91
+ $subscriptions_by_customer_id = $this->_load_customer_subscriptions($ids);
92
+
93
+ $m = new Mage_Customer_Model_Customer_Api();
94
+ $ret = array();
95
+ foreach($ids as $id){
96
+ try{
97
+ $info = $m->info($id);
98
+ } catch(Exception $e){
99
+ $info = false;
100
+ }
101
+ $ret[$id] = $info;
102
+ if (!$info) continue;
103
+
104
+ $email = $info['email'];
105
+ /*try{
106
+ $subscriber = $submodel->loadByEmail($email);
107
+ $is_subscribed = ($subscriber && $subscriber->subscriber_email==$email);
108
+ $ret[$id]['subscription'] = $is_subscribed ? $subscriber->toArray() : false;
109
+ } catch(Exception $e){
110
+ // pass
111
+ }*/
112
+
113
+ $subscription = isset($subscriptions_by_customer_id[$id]) ? $subscriptions_by_customer_id[$id] : null;
114
+ $is_subscribed = ($subscription && $subscription['subscriber_email']==$email);
115
+ $ret[$id]['subscription'] = $is_subscribed ? $subscription : false;
116
+ }
117
+ return $ret;
118
+ }
119
+
120
+ private function _load_customer_subscriptions($customer_ids){
121
+ if (!$customer_ids) return array();
122
+
123
+ $db = Mage::getSingleton('core/resource')->getConnection('core_read');
124
+ $core_resource = Mage::getSingleton('core/resource');
125
+
126
+ $select = $db->select()
127
+ ->from(
128
+ array(
129
+ 's' => $core_resource->getTableName('newsletter_subscriber')
130
+ ),
131
+ array('*')
132
+ )
133
+ ->where('customer_id IN (?)', $customer_ids);
134
+
135
+ $rows = $db->fetchAll($select);
136
+
137
+ $ret = array();
138
+
139
+ foreach($rows as $row){
140
+ $ret[$row['customer_id']] = $row;
141
+ }
142
+
143
+ return $ret;
144
+ }
145
+
146
+ public function customer_collection_size($filters = null) {
147
+ list ($from, $to) = $this->_handleParameters($filters, null, null);
148
+
149
+ $collection = Mage::getModel('customer/customer')->getCollection();
150
+
151
+ if ($from && $to) {
152
+ $collection->addAttributeToFilter('updated_at', array('gteq' => $from->format('Y-m-d H:i:s')));
153
+ $collection->addAttributeToFilter('updated_at', array('lteq' => $to->format('Y-m-d H:i:s')));
154
+ }
155
+
156
+ return $collection->getSize();
157
+ }
158
+
159
+ /**
160
+ * API method for listing products IDs updated between a provided date range.
161
+ *
162
+ * If from date or to date is absent, or empty, then we return ALL product ids.
163
+ * If $page or $pageSize is absent, then we return an all results. Note, this is not advised for sites with a large
164
+ * product collection since you'll likely run out of memory.
165
+ *
166
+ * @param array $filters accepts an array of filters to apply to the colleciton. Currently supports just updatedFrom
167
+ * and updatedTo, which are date strings in ISO8601 format.
168
+ * @param int $page an integer denoting the current page. Note, Magento indexes collection pages at 1.
169
+ * @param int $pageSize an integer denoting the page size.
170
+ * @return array
171
+ */
172
+ public function list_products($filters, $page = null, $pageSize = null) {
173
+ list ($from, $to, $page, $pageSize) = $this->_handleParameters($filters, $page, $pageSize);
174
+
175
+ $collection = Mage::getModel('catalog/product')->getCollection();
176
+
177
+ if ($from && $to) {
178
+ $collection->addAttributeToFilter('updated_at', array('gteq' => $from->format('Y-m-d H:i:s')));
179
+ $collection->addAttributeToFilter('updated_at', array('lteq' => $to->format('Y-m-d H:i:s')));
180
+ }
181
+
182
+ if ($page && $pageSize) {
183
+ $collection->setPage($page, $pageSize);
184
+ }
185
+
186
+ $collection->load();
187
+
188
+ $ometria_product_helper = Mage::helper('ometria/product');
189
+ return $ometria_product_helper->getIdentifiersForProducts($collection);
190
+ }
191
+
192
+ public function get_products($ids) {
193
+
194
+ $ometria_product_helper = Mage::helper('ometria/product');
195
+ $is_sku_mode = $ometria_product_helper->isSkuMode();
196
+
197
+ $configurable_product_model = Mage::getModel('catalog/product_type_configurable');
198
+ $product = Mage::getModel('catalog/product');
199
+ $productMediaConfig = Mage::getModel('catalog/product_media_config');
200
+
201
+
202
+ $m = new Mage_Catalog_Model_Product_Api();
203
+
204
+ $rewrites = $this->_load_product_rewrites($ids);
205
+
206
+ $ret = array();
207
+ foreach($ids as $id){
208
+ try{
209
+ if ($is_sku_mode){
210
+ $info = $m->info($id, null, null, 'sku');
211
+ $info['_product_id'] = $info['product_id'];
212
+ $info['product_id'] = $info['sku'];
213
+ } else {
214
+ $info = $m->info($id);
215
+ }
216
+
217
+ // Additional code to return parent information if available
218
+ if ($info['type'] == "simple"){
219
+ if($parentIds = $configurable_product_model->getParentIdsByChild($info['product_id'])) {
220
+ $info['parent_product_ids'] = $parentIds;
221
+ }
222
+ }
223
+
224
+ // Get Image URL
225
+ $product->load($id);
226
+ if ($product && $product->getId()==$info['product_id']){
227
+ $imageUrl = $productMediaConfig->getMediaUrl($product->getSmallImage());
228
+ if (!$imageUrl) $imageUrl = $product->getImageUrl();
229
+ $info['image_url'] = $imageUrl;
230
+
231
+ $imageUrl = $productMediaConfig->getMediaUrl($product->getThumbnail());
232
+ $info['image_thumb_url'] = $imageUrl;
233
+ }
234
+
235
+ // URLs
236
+ $info['urls'] = isset($rewrites[$id]) ? array_values($rewrites[$id]) : array();
237
+
238
+ // Stock
239
+ try{
240
+ $stock_item = Mage::getModel('cataloginventory/stock_item')->loadByProduct($id);
241
+ $stock = array();
242
+ $stock['qty'] = $stock_item->getQty();
243
+ $stock['is_in_stock'] = $stock_item->getIsInStock();
244
+ $info['stock'] = $stock;
245
+ } catch(Exception $e){
246
+ // pass
247
+ }
248
+
249
+ } catch(Exception $e){
250
+ $info = false;
251
+ }
252
+ $ret[$id] = $info;
253
+ }
254
+ return $ret;
255
+ }
256
+
257
+ private function _load_product_rewrites($ids){
258
+ if (!$ids) return array();
259
+ try{
260
+ $db = Mage::getSingleton('core/resource')->getConnection('core_read');
261
+ $core_resource = Mage::getSingleton('core/resource');
262
+
263
+ $select = $db->select()
264
+ ->from(
265
+ array(
266
+ 's' => $core_resource->getTableName('core_url_rewrite')
267
+ ),
268
+ array('store_id', 'product_id','request_path')
269
+ )
270
+ ->where('product_id IN (?)', $ids)
271
+ ->order(new Zend_Db_Expr('category_id IS NOT NULL DESC'));
272
+
273
+ $rows = $db->fetchAll($select);
274
+
275
+ $ret = array();
276
+
277
+ $store_url_cache = array();
278
+
279
+ foreach($rows as $row){
280
+ $product_id = $row['product_id'];
281
+ $store_id = $row['store_id'];
282
+
283
+ if (!isset($store_url_cache[$store_id])) {
284
+ $store_url_cache[$store_id]=Mage::app()
285
+ ->getStore($store_id)
286
+ ->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_LINK);
287
+ }
288
+
289
+ $store_url = rtrim($store_url_cache[$store_id], '/').'/';
290
+
291
+ $ret[$product_id][$store_id] = array(
292
+ 'store'=>$store_id,
293
+ 'url' => $store_url.$row['request_path']
294
+ );
295
+ }
296
+
297
+ return $ret;
298
+ } catch (Exception $e) {
299
+ return array();
300
+ }
301
+ }
302
+
303
+ /**
304
+ * API method for listing order increment IDs updated between a provided date range.
305
+ *
306
+ * If from date or to date is absent, or empty, then we return ALL ids.
307
+ * If $page or $pageSize is absent, then we return an all results. Note, this is not advised for sites with a large
308
+ * product collection since you'll likely run out of memory.
309
+ *
310
+ * @param array $filters accepts an array of filters to apply to the colleciton. Currently supports just updatedFrom
311
+ * and updatedTo, which are date strings in ISO8601 format.
312
+ * @param int $page an integer denoting the current page. Note, Magento indexes collection pages at 1.
313
+ * @param int $pageSize an integer denoting the page size.
314
+ * @return array
315
+ */
316
+ public function list_transactions($filters = null, $page = null, $pageSize = null) {
317
+ list ($from, $to, $page, $pageSize) = $this->_handleParameters($filters, $page, $pageSize);
318
+
319
+ $collection = Mage::getModel('sales/order')->getCollection();
320
+
321
+ if ($from && $to) {
322
+ $collection->addAttributeToFilter('updated_at', array('gteq' => $from->format('Y-m-d H:i:s')));
323
+ $collection->addAttributeToFilter('updated_at', array('lteq' => $to->format('Y-m-d H:i:s')));
324
+ }
325
+
326
+ if ($page && $pageSize) {
327
+ $collection->setPage($page, $pageSize);
328
+ }
329
+
330
+ $collection->load();
331
+
332
+ $ids = array();
333
+ $items = $collection->getItems();
334
+
335
+ foreach ($items as $item) {
336
+ $ids []= $item ->getIncrementId();
337
+ }
338
+
339
+ return $ids;
340
+ }
341
+
342
+ public function get_transactions($ids) {
343
+
344
+ $ometria_product_helper = Mage::helper('ometria/product');
345
+ $is_sku_mode = $ometria_product_helper->isSkuMode();
346
+
347
+ $m = new Mage_Sales_Model_Order_Api();
348
+ $ret = array();
349
+ foreach($ids as $id){
350
+ try{
351
+ $info = $m->info($id);
352
+
353
+ if ($is_sku_mode && isset($info['items'])) {
354
+ $_items = $info['items'];
355
+ $items = array();
356
+ foreach($_items as $item){
357
+ $item['_product_id'] = $item['product_id'];
358
+ $item['product_id'] = $item['sku'];
359
+ $items[] = $item;
360
+ }
361
+ $info['items'] = $items;
362
+ }
363
+
364
+ } catch(Exception $e){
365
+ $info = false;
366
+ }
367
+ $ret[$id] = $info;
368
+ }
369
+ return $ret;
370
+ }
371
+
372
+ /**
373
+ * API method for retrieving the total number of products updated in a date range.
374
+ *
375
+ * If from date or to date is absent, or empty, then we count ALL products.
376
+ *
377
+ * @param array $filters accepts an array of filters to apply to the colleciton. Currently supports just updatedFrom
378
+ * and updatedTo, which are date strings in ISO8601 format.
379
+ * @return int
380
+ */
381
+ public function product_collection_size($filters = null) {
382
+ list ($from, $to) = $this->_handleParameters($filters, null, null);
383
+
384
+ $collection = Mage::getModel('catalog/product')->getCollection();
385
+
386
+ if ($from && $to) {
387
+ $collection->addAttributeToFilter('updated_at', array('gteq' => $from->format('Y-m-d H:i:s')));
388
+ $collection->addAttributeToFilter('updated_at', array('lteq' => $to->format('Y-m-d H:i:s')));
389
+ }
390
+
391
+ return $collection->getSize();
392
+ }
393
+
394
+ /**
395
+ * API method for retrieving the total number of transaction updated in a date range.
396
+ *
397
+ * If from date or to date is absent, or empty, then we count ALL products.
398
+ *
399
+ * @param array $filters accepts an array of filters to apply to the colleciton. Currently supports just updatedFrom
400
+ * and updatedTo, which are date strings in ISO8601 format.
401
+ * @return int
402
+ */
403
+ public function transaction_collection_size($filters = null) {
404
+ list ($from, $to) = $this->_handleParameters($filters, null, null);
405
+
406
+ $collection = Mage::getModel('sales/order')->getCollection();
407
+
408
+ if ($from && $to) {
409
+ $collection->addAttributeToFilter('updated_at', array('gteq' => $from->format('Y-m-d H:i:s')));
410
+ $collection->addAttributeToFilter('updated_at', array('lteq' => $to->format('Y-m-d H:i:s')));
411
+ }
412
+
413
+ return $collection->getSize();
414
+ }
415
+
416
+ /**
417
+ * Helper method to validate parameters
418
+ *
419
+ * @param array $filters accepts an array of filters to apply to the colleciton. Currently supports just updatedFrom
420
+ * and updatedTo, which are date strings in ISO8601 format.
421
+ * @param int $page an integer denoting the current page. Note, Magento indexes collection pages at 1.
422
+ * @param int $pageSize an integer denoting the page size.
423
+ * @return array
424
+ */
425
+ protected function _handleParameters($filters, $page, $pageSize) {
426
+ //Mage::log(sprintf("%s", print_r($filters, true)), Zend_Log::DEBUG, 'martin_dev.log', true);
427
+ $updatedFrom = false;
428
+ $updatedTo = false;
429
+ if (isset($filters['updatedFrom']) && $filters['updatedFrom']) {
430
+ if (!$updatedFrom = date_create_from_format(DATE_ISO8601, $filters['updatedFrom'])) {
431
+ $this->_fault('data_invalid', sprintf('Invalid from date passed. "%s" is not ISO8601 format.', $filters['updatedFrom']));
432
+ }
433
+ }
434
+ if (isset($filters['updatedTo']) && $filters['updatedTo']){
435
+ if (!$updatedTo = date_create_from_format(DATE_ISO8601, $filters['updatedTo'])) {
436
+ $this->_fault('data_invalid', sprintf('Invalid to date passed. "%s" is not ISO8601 format.', $filters['updatedTo']));
437
+ }
438
+ }
439
+ if ($updatedFrom && $updatedTo){
440
+ if ($updatedTo < $updatedFrom) {
441
+ $this->_fault('data_invalid', sprintf('To date cannot be less than from date.'));
442
+ }
443
+ }
444
+
445
+ // Validate page parameters
446
+ if ($page && !is_int($page)) {
447
+ $this->_fault('data_invalid', sprintf('Invalid page parameter passed, expected int and got "%s"', $page));
448
+ }
449
+
450
+ if ($pageSize && !is_int($pageSize)) {
451
+ $this->_fault('data_invalid', sprintf('Invalid pageSize parameter passed, expected int and got "%s"', $pageSize));
452
+ }
453
+
454
+ if (!$page) $page = 1;
455
+ if (!$pageSize) $pageSize = 50;
456
+
457
+ return array($updatedFrom, $updatedTo, $page, $pageSize);
458
+ }
459
+ }
app/code/community/Ometria/Api/Model/Api2.php ADDED
@@ -0,0 +1,1088 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Ometria_Api_Model_Api2 extends Mage_Api_Model_Resource_Abstract {
3
+
4
+
5
+ public function customers_list($filters, $page = null, $limit = null, $attributes=array('*')) {
6
+
7
+ $collection = Mage::getModel('customer/customer')
8
+ ->getCollection()
9
+ ->addAttributeToSelect('lastname')
10
+ ->addAttributeToSelect('firstname')
11
+ ->addAttributeToSelect('suffix')
12
+ ->addAttributeToSelect('middlename')
13
+ ->addAttributeToSelect('prefix');
14
+
15
+ foreach ($attributes as $attr) {
16
+ $collection->addAttributeToSelect($attr);
17
+ }
18
+
19
+ $this->_applyFiltersToCollection($collection, $filters, $page, $limit);
20
+
21
+ if (isset($filters['websites']) && $filters['websites']){
22
+ $collection->addAttributeToFilter('website_id', array('in'=>$filters['websites']));
23
+ }
24
+
25
+ $collection->load();
26
+
27
+ $customer_ids = array();
28
+ foreach($collection as $item){
29
+ $customer_ids[] = $item->getId();
30
+ }
31
+
32
+ $subscriptions_by_customer_id = $this->_load_customer_subscriptions($customer_ids);
33
+
34
+ $ret = array();
35
+
36
+ foreach($collection as $item){
37
+ $row = $item->getData();
38
+ $row['customer_id'] = $item->getId();
39
+
40
+ $id = $item->getId();
41
+ $subscription = isset($subscriptions_by_customer_id[$id]) ? $subscriptions_by_customer_id[$id] : null;
42
+ $is_subscribed = ($subscription && $subscription['subscriber_email']==$item->getEmail());
43
+ $row['subscription'] = $is_subscribed ? $subscription : false;
44
+
45
+ $ret[] = $row;
46
+ }
47
+
48
+ return $ret;
49
+ }
50
+
51
+ private function _load_customer_subscriptions($customer_ids){
52
+ if (!$customer_ids) return array();
53
+
54
+ $db = $this->_getReadDb();
55
+ $core_resource = Mage::getSingleton('core/resource');
56
+
57
+ $select = $db->select()
58
+ ->from(
59
+ array(
60
+ 's' => $core_resource->getTableName('newsletter_subscriber')
61
+ ),
62
+ array('*')
63
+ )
64
+ ->where('customer_id IN (?)', $customer_ids);
65
+
66
+ $rows = $db->fetchAll($select);
67
+
68
+ $ret = array();
69
+
70
+ foreach($rows as $row){
71
+ $ret[$row['customer_id']] = $row;
72
+ }
73
+
74
+ return $ret;
75
+ }
76
+
77
+ public function products_list($filters, $page = null, $limit = null, $attributes=array('*')) {
78
+
79
+ $ometria_product_helper = Mage::helper('ometria/product');
80
+ $is_sku_mode = $ometria_product_helper->isSkuMode();
81
+ $productMediaConfig = Mage::getModel('catalog/product_media_config');
82
+
83
+ $collection = Mage::getModel('catalog/product')
84
+ ->getCollection()
85
+ ->addAttributeToSelect('name')
86
+ ->addAttributeToSelect('sku')
87
+ ->addAttributeToSelect('price')
88
+ ->addAttributeToSelect('image');
89
+
90
+ foreach ($attributes as $attr) {
91
+ $collection->addAttributeToSelect($attr);
92
+ }
93
+
94
+ $this->_applyFiltersToCollection($collection, $filters, $page, $limit, $is_sku_mode ? 'sku' : 'entity_id');
95
+
96
+ if (isset($filters['websites']) && $filters['websites']){
97
+ $collection->addWebsiteFilter($filters['websites']);
98
+ }
99
+
100
+ $collection->load();
101
+
102
+ // Cache the mapping for website_ids => store_ids to avoid too many DB calls
103
+ $website_store_lookup = array();
104
+
105
+ // Collect loaded product ids
106
+ $product_ids = array();
107
+ foreach($collection as $item){
108
+ $product_ids[] = $item->getId();
109
+ }
110
+
111
+ // Load rewrites
112
+ $rewrites = $this->_load_product_rewrites($product_ids);
113
+
114
+ $ret = array();
115
+ foreach($collection as $item){
116
+ $row = $item->getData();
117
+
118
+ if ($is_sku_mode) {
119
+ $row['product_id'] = $item->getSku();
120
+ } else {
121
+ $row['product_id'] = $item->getId();
122
+ }
123
+
124
+ $website_ids = $item->getWebsiteIds();
125
+ $row['websites'] = $website_ids;
126
+
127
+ $stores_cache_key = implode(":", $row['websites']);
128
+ if (!isset($website_store_lookup[$stores_cache_key])) {
129
+ $website_store_lookup[$stores_cache_key] = $this->_getStoreIdsForWebsites($website_ids);
130
+ }
131
+ $store_ids = $website_store_lookup[$stores_cache_key];
132
+ $row['stores'] = $store_ids;
133
+
134
+ // Get image url (small_image first)
135
+ $imageUrl = $productMediaConfig->getMediaUrl($item->getSmallImage());
136
+ if (!$imageUrl) $imageUrl = $item->getImageUrl();
137
+ $row['image_url'] = $imageUrl;
138
+
139
+ // Get thumbnail
140
+ $imageUrl = $productMediaConfig->getMediaUrl($item->getThumbnail());
141
+ $row['image_thumb_url'] = $imageUrl;
142
+
143
+ // URLs
144
+ $product_id = $item->getId();
145
+ $row['urls'] = isset($rewrites[$product_id]) ? array_values($rewrites[$product_id]) : array();
146
+
147
+ // Stock
148
+ try{
149
+ $stock_item = Mage::getModel('cataloginventory/stock_item')->loadByProduct($id);
150
+ $stock = array();
151
+ $stock['qty'] = $stock_item->getQty();
152
+ $stock['is_in_stock'] = $stock_item->getIsInStock();
153
+ $row['stock'] = $stock;
154
+ } catch(Exception $e){
155
+ // pass
156
+ }
157
+
158
+ $ret[] = $row;
159
+ }
160
+
161
+ return $ret;
162
+ }
163
+
164
+ private function _load_product_rewrites($ids){
165
+ if (!$ids) return array();
166
+ try{
167
+ $db = Mage::getSingleton('core/resource')->getConnection('core_read');
168
+ $core_resource = Mage::getSingleton('core/resource');
169
+
170
+ $select = $db->select()
171
+ ->from(
172
+ array(
173
+ 's' => $core_resource->getTableName('core_url_rewrite')
174
+ ),
175
+ array('store_id', 'product_id','request_path')
176
+ )
177
+ ->where('product_id IN (?)', $ids)
178
+ ->order(new Zend_Db_Expr('category_id IS NOT NULL DESC'));
179
+
180
+ $rows = $db->fetchAll($select);
181
+
182
+ $ret = array();
183
+
184
+ $store_url_cache = array();
185
+
186
+ foreach($rows as $row){
187
+ $product_id = $row['product_id'];
188
+ $store_id = $row['store_id'];
189
+
190
+ if (!isset($store_url_cache[$store_id])) {
191
+ $store_url_cache[$store_id]=Mage::app()
192
+ ->getStore($store_id)
193
+ ->getBaseUrl(Mage_Core_Model_Store::URL_TYPE_LINK);
194
+ }
195
+
196
+ $store_url = rtrim($store_url_cache[$store_id], '/').'/';
197
+
198
+ $ret[$product_id][$store_id] = array(
199
+ 'store'=>$store_id,
200
+ 'url' => $store_url.$row['request_path']
201
+ );
202
+ }
203
+
204
+ return $ret;
205
+ } catch (Exception $e) {
206
+ return array();
207
+ }
208
+ }
209
+
210
+ public function subscribers_list($filters=array(), $page=1, $pageSize=100){
211
+ $collection = Mage::getModel('newsletter/subscriber')->getCollection();
212
+
213
+ // setPage does not exist on this collection.
214
+ // Access lower lever setters.
215
+ $collection->setCurPage($page);
216
+ $collection->setPageSize($pageSize);
217
+
218
+ if (isset($filters['websites']) && $filters['websites']){
219
+ $collection->addStoreFilter($this->_getStoreIdsForWebsites($filters['websites']));
220
+ }
221
+
222
+ if (isset($filters['updatedFrom']) && $filters['updatedFrom']){
223
+ $collection->addFieldToFilter('change_status_at', array('gteq' => $filters['updatedFrom']));
224
+ }
225
+
226
+ if (isset($filters['updatedTo']) && $filters['updatedTo']){
227
+ $collection->addFieldToFilter('change_status_at', array('lteq' => $filters['updatedTo']));
228
+ }
229
+
230
+ $collection->load();
231
+
232
+ $ret = array();
233
+
234
+ foreach($collection as $item){
235
+ $ret[] = array(
236
+ 'customer_id'=>$item->customer_id,
237
+ 'email'=>$item->subscriber_email,
238
+ 'store_id'=>$item->store_id,
239
+ 'status'=>$item->subscriber_status,
240
+ 'change_status_at'=>$item->change_status_at
241
+ );
242
+ }
243
+
244
+ return $ret;
245
+ }
246
+
247
+ public function subscribers_subscribe($email, $send_confirmation=false){
248
+
249
+ if (!$email) return;
250
+
251
+ $subscriber = Mage::getModel('newsletter/subscriber')->loadByEmail($email);
252
+
253
+ if (!$subscriber || !$subscriber->getId()){
254
+ Mage::getModel('newsletter/subscriber')->setImportMode(!$send_confirmation)->subscribe($email);
255
+ $subscriber = Mage::getModel('newsletter/subscriber')->loadByEmail($email);
256
+ }
257
+
258
+ if ($subscriber && $subscriber->getId()){
259
+ $subscriber->setStatus(Mage_Newsletter_Model_Subscriber::STATUS_SUBSCRIBED);
260
+ $subscriber->save();
261
+ return true;
262
+ }
263
+
264
+ return false;
265
+ }
266
+
267
+ public function subscribers_unsubscribe($email, $reason='UNSUBSCRIBED'){
268
+
269
+ if (!$email) return;
270
+
271
+ $to_status = null;
272
+ if ($reason=='UNSUBSCRIBED') $to_status = Mage_Newsletter_Model_Subscriber::STATUS_UNSUBSCRIBED;
273
+ if ($reason=='NOT_ACTIVE') $to_status = Mage_Newsletter_Model_Subscriber::STATUS_NOT_ACTIVE;
274
+ if ($reason=='UNCONFIRMED') $to_status = Mage_Newsletter_Model_Subscriber::STATUS_UNCONFIRMED;
275
+
276
+ $subscriber = Mage::getModel('newsletter/subscriber')->loadByEmail($email);
277
+ if ($subscriber && $subscriber->getId() && $to_status){
278
+ $subscriber->setStatus($to_status);
279
+ $subscriber->save();
280
+ return true;
281
+ } else {
282
+ return false;
283
+ }
284
+ }
285
+
286
+
287
+ //@todo add websites filter
288
+ public function salesrules_list($filters=array(), $page=1, $limit=100){
289
+ $db = Mage::getSingleton('core/resource')->getConnection('core_read');
290
+ $core_resource = Mage::getSingleton('core/resource');
291
+
292
+ $offset = ($page-1)*$limit;
293
+
294
+ $select = $db->select()
295
+ ->from(
296
+ array(
297
+ 's' => $core_resource->getTableName('salesrule/rule')
298
+ ),
299
+ array(
300
+ '*'
301
+ )
302
+ )
303
+ ->limit($limit, $offset);
304
+
305
+
306
+ return $db->fetchAll($select);
307
+ }
308
+
309
+ public function salesrules_list_coupons($rule_id, $filters=array(), $page=1, $limit=100){
310
+ $db = Mage::getSingleton('core/resource')->getConnection('core_read');
311
+ $core_resource = Mage::getSingleton('core/resource');
312
+
313
+ $offset = ($page-1)*$limit;
314
+
315
+ $select = $db->select()
316
+ ->from(
317
+ array(
318
+ 's' => $core_resource->getTableName('salesrule/coupon')
319
+ ),
320
+ array(
321
+ '*'
322
+ )
323
+ )
324
+ ->where('rule_id=?', $rule_id)
325
+ ->limit($limit, $offset);
326
+
327
+
328
+ return $db->fetchAll($select);
329
+ }
330
+
331
+ public function salesrules_create_coupons($rule_id, $count=1, $parameters=array()){
332
+ // Get the rule in question
333
+ $rule = Mage::getModel('salesrule/rule')->load($rule_id);
334
+ if (!$rule->getId()) return false;
335
+
336
+ $generator = Mage::getModel('salesrule/coupon_massgenerator');
337
+
338
+ $_parameters = array(
339
+ 'format'=>'alphanumeric',
340
+ 'dash_every_x_characters'=>4,
341
+ 'prefix'=>'',
342
+ 'suffix'=>'',
343
+ 'length'=>12
344
+ );
345
+ $parameters = array_merge($_parameters, $parameters);
346
+
347
+ if( !empty($parameters['format']) ){
348
+ switch( strtolower($parameters['format']) ){
349
+ case 'alphanumeric':
350
+ case 'alphanum':
351
+ $generator->setFormat( Mage_SalesRule_Helper_Coupon::COUPON_FORMAT_ALPHANUMERIC );
352
+ break;
353
+ case 'alphabetical':
354
+ case 'alpha':
355
+ $generator->setFormat( Mage_SalesRule_Helper_Coupon::COUPON_FORMAT_ALPHABETICAL );
356
+ break;
357
+ case 'numeric':
358
+ case 'num':
359
+ $generator->setFormat( Mage_SalesRule_Helper_Coupon::COUPON_FORMAT_NUMERIC );
360
+ break;
361
+ }
362
+ }
363
+
364
+ $generator->setDash((int) $parameters['dash_every_x_characters']);
365
+ $generator->setLength((int) $parameters['length']);
366
+ $generator->setPrefix($parameters['prefix']);
367
+ $generator->setSuffix($parameters['suffix']);
368
+
369
+ // Set the generator, and coupon type so it's able to generate
370
+ $rule->setCouponCodeGenerator($generator);
371
+ $rule->setCouponType( Mage_SalesRule_Model_Rule::COUPON_TYPE_AUTO );
372
+
373
+ // Get as many coupons as you required
374
+ $codes = array();
375
+ for( $i = 0; $i < $count; $i++ ){
376
+ $coupon = $rule->acquireCoupon();
377
+ $coupon->setType(Mage_SalesRule_Helper_Coupon::COUPON_TYPE_SPECIFIC_AUTOGENERATED)->save();
378
+ $code = $coupon->getCode();
379
+ $codes[] = $code;
380
+ }
381
+ return $codes;
382
+ }
383
+
384
+
385
+ public function stores_list($filters=array()){
386
+ $db = Mage::getSingleton('core/resource')->getConnection('core_read');
387
+ $core_resource = Mage::getSingleton('core/resource');
388
+
389
+ $select = $db->select()
390
+ ->from(
391
+ array(
392
+ 's' => $core_resource->getTableName('core_store')
393
+ ),
394
+ array(
395
+ '*'
396
+ )
397
+ )
398
+ ->join(
399
+ array(
400
+ 'w' => $core_resource->getTableName('core_website')
401
+ ),
402
+ 'w.website_id = s.website_id',
403
+ array(
404
+ 'website_name'=>'name'
405
+ )
406
+ )
407
+ ->where('store_id != 0');
408
+
409
+ if (isset($filters['websites']) && $filters['websites']){
410
+ $select->where('s.website_id IN (?)', $filters['websites']);
411
+ }
412
+
413
+ return $db->fetchAll($select);
414
+ }
415
+
416
+ public function product_attributes_list(){
417
+
418
+ $db = Mage::getSingleton('core/resource')->getConnection('core_read');
419
+ $core_resource = Mage::getSingleton('core/resource');
420
+
421
+ $product_entity_type_id = $this->_getEavEntityTypeId('catalog_product');
422
+
423
+ $select = $db->select()
424
+ ->from(
425
+ array(
426
+ 'a' => $core_resource->getTableName('eav_attribute')
427
+ ),
428
+ array(
429
+ 'attribute_code'
430
+ )
431
+ )
432
+ ->join(
433
+ array(
434
+ 'o' => $core_resource->getTableName('eav_attribute_option')
435
+ ),
436
+ 'o.attribute_id = a.attribute_id',
437
+ array(
438
+ 'option_id'
439
+ )
440
+ )
441
+ ->join(
442
+ array(
443
+ 'v' => $core_resource->getTableName('eav_attribute_option_value')
444
+ ),
445
+ 'o.option_id = v.option_id',
446
+ array(
447
+ 'store_id','value'
448
+ )
449
+ )
450
+ ->where('a.entity_type_id=?', $product_entity_type_id);
451
+
452
+ $rows = $db->fetchAll($select);
453
+
454
+ $ret = array();
455
+ foreach($rows as $row){
456
+ $type = $row['attribute_code'];
457
+ $id = $row['option_id'];
458
+ $label = $row['value'];
459
+ $store_id = $row['store_id'];
460
+
461
+ if (!isset($ret[$type])) $ret[$type] = array();
462
+ if (!isset($ret[$type][$id])) $ret[$type][$id] = array(
463
+ 'attribute_id'=>$id,
464
+ 'label'=>$label,
465
+ 'storeviews'=>array()
466
+ );
467
+ $ret[$type][$id]['storeviews'][$store_id] = $label;
468
+ }
469
+
470
+ return $ret;
471
+ }
472
+
473
+ public function products_flat_list($filters=array(), $page=1, $limit=100){
474
+ $db = $this->_getReadDb();
475
+ $core_resource = Mage::getSingleton('core/resource');
476
+
477
+ $ometria_product_helper = Mage::helper('ometria/product');
478
+ $is_sku_mode = $ometria_product_helper->isSkuMode();
479
+
480
+ // If filtered by websites, get default store id for first website id
481
+ if (isset($filters['websites']) && is_array($filters['websites']) && $filters['websites']){
482
+ $website_ids = $filters['websites'];
483
+ $website_ids = array_values($website_ids);
484
+ $website_id = $website_ids[0];
485
+
486
+ $store = Mage::app()
487
+ ->getWebsite($website_id)
488
+ ->getDefaultGroup()
489
+ ->getDefaultStoreId();
490
+ } else{
491
+ $store = 1;
492
+ }
493
+
494
+ // Override in case we need to
495
+ if (isset($filters['store']) && $filters['store']){
496
+ $store = $filters['store'];
497
+ }
498
+
499
+ $store = intval($store);
500
+ $offset = ($page-1) * $limit;
501
+
502
+ $select = $db->select()->from(
503
+ array('p' => $core_resource->getTableName('catalog_product_flat_'.$store))
504
+ )
505
+ ->join(
506
+ array('a'=>'eav_attribute_set'),
507
+ 'p.attribute_set_id=a.attribute_set_id',
508
+ array('attribute_set_name')
509
+ )
510
+ ->limit($limit, $offset)
511
+ ->order('entity_id');
512
+
513
+ // Filters
514
+ if (isset($filters['visibility'])) $select->where('visibility=?', $filters['visibility']);
515
+ if (isset($filters['updatedFrom'])) $select->where('updated_at>=?', $filters['updatedFrom']);
516
+ if (isset($filters['updatedTo'])) $select->where('updated_at<=?', $filters['updatedTo']);
517
+ if (isset($filters['createdFrom'])) $select->where('created_at>=?', $filters['createdFrom']);
518
+ if (isset($filters['createdTo'])) $select->where('created_at<=?', $filters['createdTo']);
519
+
520
+ if (isset($filters['id']) && !is_array($filters['id'])) {
521
+ if ($is_sku_mode) {
522
+ $select->where('sku=?', $filters['id']);
523
+ } else {
524
+ $select->where('entity_id=?', $filters['id']);
525
+ }
526
+ }
527
+ if (isset($filters['id']) && $filters['id']) {
528
+ $ids = $filters['id'];
529
+ if (!is_array($ids)) $ids = array($ids);
530
+ if ($is_sku_mode) {
531
+ $select->where('sku IN (?)', $ids);
532
+ } else {
533
+ $select->where('entity_id IN (?)', $ids);
534
+ }
535
+ }
536
+
537
+ $rows = $db->fetchAll($select);
538
+
539
+ // Collect product_ids
540
+ $product_ids = array();
541
+ foreach($rows as $row){
542
+ $product_ids[] = $row['entity_id'];
543
+ }
544
+
545
+ // Load website ids
546
+ $product_id_website_ids = $this->_load_product_website_mapping($product_ids);
547
+
548
+
549
+ $website_store_lookup = array();
550
+
551
+ // Add id field to each row based on product ID mode
552
+ foreach($rows as &$row){
553
+ if ($is_sku_mode) {
554
+ $row['product_id'] = $row['sku'];
555
+ } else {
556
+ $row['product_id'] = $row['entity_id'];
557
+ }
558
+
559
+ $entity_id = $row['entity_id'];
560
+ $website_ids = isset($product_id_website_ids[$entity_id]) ?
561
+ $product_id_website_ids[$entity_id] :
562
+ array();
563
+
564
+ $row['websites'] = $website_ids;
565
+ $stores_cache_key = implode(":", $website_ids);
566
+ if (!isset($website_store_lookup[$stores_cache_key])) {
567
+ $website_store_lookup[$stores_cache_key] = $this->_getStoreIdsForWebsites($website_ids);
568
+ }
569
+ $store_ids = $website_store_lookup[$stores_cache_key];
570
+ $row['stores'] = $store_ids;
571
+ }
572
+ unset($row);
573
+
574
+ return $rows;
575
+ }
576
+
577
+ private function _load_product_website_mapping($product_ids){
578
+ if (!$product_ids) return array();
579
+
580
+ $db = Mage::getSingleton('core/resource')->getConnection('core_read');
581
+ $core_resource = Mage::getSingleton('core/resource');
582
+
583
+ $select = $db->select()
584
+ ->from(
585
+ array(
586
+ 'pw' => $core_resource->getTableName('catalog_product_website')
587
+ ),
588
+ array(
589
+ '*'
590
+ )
591
+ )
592
+ ->where('product_id IN (?)', $product_ids);
593
+
594
+ $rows = $db->fetchAll($select);
595
+
596
+ $ret = array();
597
+
598
+ foreach($rows as $row){
599
+ $product_id = $row['product_id'];
600
+ $website_id = $row['website_id'];
601
+
602
+ if (!isset($ret[$product_id])) $ret[$product_id] = array();
603
+ $ret[$product_id][] = $website_id;
604
+ }
605
+
606
+ return $ret;
607
+ }
608
+
609
+ public function orders_statuses_list(){
610
+ $db = $this->_getReadDb();
611
+ $core_resource = Mage::getSingleton('core/resource');
612
+
613
+ $select = $db->select()
614
+ ->from(
615
+ array(
616
+ 'i' => $core_resource->getTableName('sales_order_status_state')
617
+ ),
618
+ array('*')
619
+ );
620
+
621
+ $rows = $db->fetchAll($select);
622
+
623
+ foreach($rows as &$row){
624
+ $row['label'] = $row['status']; //@todo
625
+ }
626
+ unset($row);
627
+
628
+ return $rows;
629
+ }
630
+
631
+ public function orders_count($filters=array(), $page=1, $limit=100){
632
+ $collection = Mage::getModel('sales/order')->getCollection();
633
+ $this->_applyFiltersToCollection($collection, $filters, $page, $limit);
634
+ if (isset($filters['websites']) && $filters['websites']){
635
+ $collection->addAttributeToFilter('store_id', array('in'=>$this->_getStoreIdsForWebsites($filters['websites'])));
636
+ }
637
+ return $collection->getSize();
638
+ }
639
+
640
+ public function orders_list($filters=array(), $page=1, $limit=100){
641
+
642
+ $ret = array();
643
+
644
+ // Load orders
645
+ $order_records = $this->_order_list_get_orders($filters, $page, $limit);
646
+
647
+ // Collect order_ids and address ids
648
+ $order_address_ids = array();
649
+ $order_entity_ids = array();
650
+ foreach($order_records as $order){
651
+ $order_entity_ids[] = $order['entity_id'];
652
+
653
+ $order_address_ids[] = $order['shipping_address_id'];
654
+ $order_address_ids[] = $order['billing_address_id'];
655
+ }
656
+
657
+ // Get lineitems for those order IDs
658
+ $order_lineitems_by_order_id = $this->_order_list_get_lineitems($order_entity_ids);
659
+
660
+ // Load addresses
661
+ $order_addresses_by_id = $this->_order_list_get_addresses($order_address_ids);
662
+
663
+ // Combine lineitems into orders
664
+ $result = array();
665
+ foreach($order_records as $order){
666
+ $order_id = $order['entity_id'];
667
+ $order['items'] = isset($order_lineitems_by_order_id[$order_id]) ? $order_lineitems_by_order_id[$order_id] : array();
668
+
669
+ $shipping_address_id = $order['shipping_address_id'];
670
+ $order['shipping_address'] =
671
+ isset($order_addresses_by_id[$shipping_address_id]) ? $order_addresses_by_id[$shipping_address_id] : array();
672
+
673
+ $billing_address_id = $order['billing_address_id'];
674
+ $order['billing_address'] =
675
+ isset($order_addresses_by_id[$billing_address_id]) ? $order_addresses_by_id[$billing_address_id] : array();
676
+
677
+
678
+ $order['order_id'] = $order['increment_id'];
679
+
680
+ $result[] = $order;
681
+ }
682
+
683
+ return $result;
684
+ }
685
+
686
+ private function _order_list_get_orders($filters, $page, $limit){
687
+ $db = $this->_getReadDb();
688
+
689
+ $orders_collection = Mage::getModel('sales/order')->getCollection();
690
+ //$this->_applyFiltersToCollection($orders_collection, $filters, $page, $limit);
691
+
692
+ $select = $orders_collection->getSelect();
693
+
694
+ // Filters
695
+ if (isset($filters['createdFrom'])) $select->where('created_at>=?', $filters['createdFrom']);
696
+ if (isset($filters['createdTo'])) $select->where('created_at<=?', $filters['createdTo']);
697
+ if (isset($filters['updatedFrom'])) $select->where('updated_at>=?', $filters['updatedFrom']);
698
+ if (isset($filters['updatedTo'])) $select->where('updated_at<=?', $filters['updatedTo']);
699
+
700
+ if (isset($filters['id']) && !is_array($filters['id'])) {
701
+ $select->where('increment_id=?', $filters['id']);
702
+ }
703
+ if (isset($filters['id']) && is_array($filters['id']) && $filters['id']) {
704
+ $select->where('increment_id IN (?)', $filters['id']);
705
+ }
706
+
707
+ if (isset($filters['websites']) && is_array($filters['websites']) && $filters['websites']) {
708
+ $store_ids = $this->_getStoreIdsForWebsites($filters['websites']);
709
+ $select->where('store_id IN (?)', $store_ids);
710
+ }
711
+
712
+ $select->limit($limit, ($page-1)*$limit)->order('entity_id');
713
+
714
+ return $db->fetchAll($select);
715
+ }
716
+
717
+ private function _order_list_get_addresses($order_address_ids){
718
+ if (!$order_address_ids) return array();
719
+
720
+ $db = $this->_getReadDb();
721
+ $core_resource = Mage::getSingleton('core/resource');
722
+
723
+ $select = $db->select()
724
+ ->from(
725
+ array(
726
+ 'i' => $core_resource->getTableName('sales_flat_order_address')
727
+ ),
728
+ array('*')
729
+ )
730
+ ->where('entity_id IN (?)', $order_address_ids);
731
+
732
+ $rows = $db->fetchAll($select);
733
+
734
+ $ret = array();
735
+ foreach($rows as $row){
736
+ $id = $row['entity_id'];
737
+ $ret[$id] = $row;
738
+ }
739
+
740
+ return $ret;
741
+ }
742
+
743
+ private function _order_list_get_lineitems($order_ids){
744
+ if (!$order_ids) return array();
745
+
746
+ $ometria_product_helper = Mage::helper('ometria/product');
747
+ $is_sku_mode = $ometria_product_helper->isSkuMode();
748
+
749
+ $db = $this->_getReadDb();
750
+ $core_resource = Mage::getSingleton('core/resource');
751
+
752
+ $select = $db->select()
753
+ ->from(
754
+ array(
755
+ 'i' => $core_resource->getTableName('sales/order_item')
756
+ ),
757
+ array(
758
+ '*',
759
+ 'variant_sku'=>'sku'
760
+ )
761
+ )
762
+ ->join(
763
+ array(
764
+ 'p' => $core_resource->getTableName('catalog/product')
765
+ ),
766
+ 'i.product_id = p.entity_id',
767
+ array(
768
+ 'sku'
769
+ )
770
+ )
771
+ //->where('i.parent_item_id IS NULL')
772
+ ->where('i.order_id IN (?)', $order_ids);
773
+
774
+ $_rows = $db->fetchAll($select);
775
+ $rows = array();
776
+ $groups = array();
777
+
778
+ foreach($_rows as $row){
779
+ $parent_item_id = $row['parent_item_id'];
780
+
781
+ if ($parent_item_id===null) {
782
+ $rows[] = $row;
783
+ } else {
784
+ if (!isset($groups[$parent_item_id])) $groups[$parent_item_id] = array();
785
+ $groups[$parent_item_id][] = $row;
786
+ }
787
+ }
788
+
789
+
790
+ $result = array();
791
+ foreach($rows as $row){
792
+ $item_id = $row['item_id'];
793
+ $order_id = $row['order_id'];
794
+ if (!isset($result[$order_id])) $result[$order_id] = array();
795
+ $row['product_options'] = unserialize($row['product_options']);
796
+ $children = isset($groups[$item_id]) ? $groups[$item_id] : array();
797
+
798
+ $row['variant_id'] = count($children)>0 ? $children[0]['product_id'] : null;
799
+ $row['children'] = $children;
800
+
801
+ if ($is_sku_mode) {
802
+ $row['_product_id'] = $row['product_id'];
803
+ $row['product_id'] = $row['sku'];
804
+
805
+ if ($row['variant_id']){
806
+ $row['variant_id'] = $row['variant_sku'];
807
+ $row['_variant_id'] = $row['variant_id'];
808
+ }
809
+ }
810
+
811
+ $result[$order_id][] = $row;
812
+ }
813
+
814
+ return $result;
815
+ }
816
+
817
+
818
+ public function carts_list($filters=array(), $page=1, $limit=100){
819
+
820
+ $ret = array();
821
+
822
+ // Load orders
823
+ $order_records = $this->_carts_list_get_carts($filters, $page, $limit);
824
+
825
+ // Collect order_ids
826
+ $order_entity_ids = array();
827
+ foreach($order_records as $order){
828
+ $order_entity_ids[] = $order['entity_id'];
829
+ }
830
+
831
+ // Get lineitems for those order IDs
832
+ $order_lineitems_by_order_id = $this->_carts_list_get_lineitems($order_entity_ids);
833
+
834
+ // Combine lineitems into orders
835
+ $result = array();
836
+ foreach($order_records as $order){
837
+ $token = md5($order['created_at'].$order['remote_ip']);
838
+
839
+ $order['token'] = $token;
840
+ $order['deeplink'] = Mage::getUrl('omcart/cartlink',
841
+ array('_query'=>array(
842
+ 'token'=>$token,
843
+ 'id'=>$order['entity_id']),
844
+ '_store' => $order['store_id'],
845
+ '_store_to_url'=>true
846
+ ));
847
+
848
+ $order['cart_id'] = $order['entity_id'];
849
+
850
+ $order_id = $order['entity_id'];
851
+ $order['items'] = isset($order_lineitems_by_order_id[$order_id]) ? $order_lineitems_by_order_id[$order_id] : array();
852
+ $result[] = $order;
853
+ }
854
+
855
+ return $result;
856
+ }
857
+
858
+
859
+ private function _carts_list_get_carts($filters, $page, $limit){
860
+ $db = $this->_getReadDb();
861
+ $core_resource = Mage::getSingleton('core/resource');
862
+
863
+ $offset = ($page-1) * $limit;
864
+
865
+ $select = $db->select()
866
+ ->from(
867
+ array(
868
+ 'q' => $core_resource->getTableName('sales/quote')
869
+ ),
870
+ array(
871
+ '*'
872
+ )
873
+ )
874
+ ->joinLeft(
875
+ array(
876
+ 'o' => $core_resource->getTableName('sales/order')
877
+ ),
878
+ 'q.entity_id = o.quote_id',
879
+ array(
880
+ 'order_increment_id'=>'increment_id',
881
+ 'ordered_at'=>'created_at',
882
+ )
883
+ )
884
+ ->limit($limit, $offset)
885
+ ->order('q.entity_id');
886
+
887
+ if (isset($filters['updatedFrom'])) $select->where('q.updated_at>=?', $filters['updatedFrom']);
888
+ if (isset($filters['updatedTo'])) $select->where('q.updated_at<=?', $filters['updatedTo']);
889
+ if (isset($filters['createdFrom'])) $select->where('q.created_at>=?', $filters['createdFrom']);
890
+ if (isset($filters['createdTo'])) $select->where('q.created_at<=?', $filters['createdTo']);
891
+
892
+ if (isset($filters['websites']) && is_array($filters['websites']) && $filters['websites']) {
893
+ $store_ids = $this->_getStoreIdsForWebsites($filters['websites']);
894
+ $select->where('q.store_id IN (?)', $store_ids);
895
+ }
896
+
897
+ return $db->fetchAll($select);
898
+ }
899
+
900
+ private function _carts_list_get_lineitems($order_ids){
901
+ if (!$order_ids) return array();
902
+
903
+ $db = $this->_getReadDb();
904
+ $core_resource = Mage::getSingleton('core/resource');
905
+
906
+ $ometria_product_helper = Mage::helper('ometria/product');
907
+ $is_sku_mode = $ometria_product_helper->isSkuMode();
908
+
909
+ $select = $db->select()
910
+ ->from(
911
+ array(
912
+ 'i' => $core_resource->getTableName('sales/quote_item')
913
+ ),
914
+ array(
915
+ '*',
916
+ 'variant_sku'=>'sku'
917
+ )
918
+ )
919
+ ->join(
920
+ array(
921
+ 'p' => $core_resource->getTableName('catalog/product')
922
+ ),
923
+ 'i.product_id = p.entity_id',
924
+ array(
925
+ 'sku'
926
+ )
927
+ )
928
+ ->where('i.parent_item_id IS NULL')
929
+ ->where('i.quote_id IN (?)', $order_ids);
930
+
931
+ $_rows = $db->fetchAll($select);
932
+ $rows = array();
933
+ $groups = array();
934
+
935
+ foreach($_rows as $row){
936
+ $parent_item_id = $row['parent_item_id'];
937
+
938
+ if ($parent_item_id===null) {
939
+ $rows[] = $row;
940
+ } else {
941
+ if (!isset($groups[$parent_item_id])) $groups[$parent_item_id] = array();
942
+ $groups[$parent_item_id][] = $row;
943
+ }
944
+ }
945
+
946
+
947
+ $result = array();
948
+ foreach($rows as $row){
949
+ $item_id = $row['item_id'];
950
+ $order_id = $row['quote_id'];
951
+ if (!isset($result[$order_id])) $result[$order_id] = array();
952
+ $row['product_options'] = unserialize($row['product_options']);
953
+ $children = isset($groups[$item_id]) ? $groups[$item_id] : array();
954
+
955
+ $row['variant_id'] = count($children)>0 ? $children[0]['product_id'] : null;
956
+ $row['children'] = $children;
957
+
958
+ if ($is_sku_mode) {
959
+ $row['_product_id'] = $row['product_id'];
960
+ $row['product_id'] = $row['sku'];
961
+
962
+ if ($row['variant_id']){
963
+ $row['variant_id'] = $row['variant_sku'];
964
+ $row['_variant_id'] = $row['variant_id'];
965
+ }
966
+ }
967
+
968
+ $result[$order_id][] = $row;
969
+ }
970
+
971
+ return $result;
972
+ }
973
+
974
+ public function get_magento_info(){
975
+ $unique_id = Mage::getStoreConfig('ometria/advanced/unique_id');
976
+ if (!$unique_id){
977
+ $unique_id = md5(uniqid().time());
978
+ $config_model = new Mage_Core_Model_Config();
979
+ $config_model->saveConfig('ometria/advanced/unique_id', $unique_id, 'default', 0);
980
+
981
+ Mage::app()->getCacheInstance()->cleanType('config');
982
+ }
983
+ $info = array();
984
+ $info['id'] = $unique_id;
985
+ $info['timezone'] = Mage::getStoreConfig('general/locale/timezone');
986
+ $info['php_timezone'] = date_default_timezone_get();
987
+ $info['php_version'] = phpversion();
988
+
989
+ return $info;
990
+ }
991
+
992
+ public function get_settings(){
993
+ $ret = array();
994
+ $ret['unique_id'] = Mage::getStoreConfig('ometria/advanced/unique_id');
995
+ $ret['productmode'] = Mage::getStoreConfig('ometria/advanced/productmode');
996
+ $ret['ping'] = Mage::getStoreConfig('ometria/advanced/ping');
997
+ return $ret;
998
+ }
999
+
1000
+ public function set_settings($settings){
1001
+ $keys = array('unique_id','productmode','ping');
1002
+ $config_model = new Mage_Core_Model_Config();
1003
+ foreach($keys as $key){
1004
+ if (isset($settings[$key]) && !empty($settings[$key])) {
1005
+ $config_model->saveConfig('ometria/advanced/'.$key, $settings[$key], 'default', 0);
1006
+ }
1007
+ }
1008
+ Mage::app()->getCacheInstance()->cleanType('config');
1009
+ return true;
1010
+ }
1011
+
1012
+ // Apply common filters to Collection
1013
+ private function _applyFiltersToCollection($collection, $filters, $page, $limit, $id_field='entity_id'){
1014
+
1015
+ if (isset($filters['updatedFrom']) && $filters['updatedFrom']){
1016
+ $collection->addAttributeToFilter('updated_at', array('gteq' => $filters['updatedFrom']));
1017
+ }
1018
+
1019
+ if (isset($filters['updatedTo']) && $filters['updatedTo']){
1020
+ $collection->addAttributeToFilter('updated_at', array('lteq' => $filters['updatedTo']));
1021
+ }
1022
+
1023
+ if (isset($filters['createdFrom']) && $filters['createdFrom']){
1024
+ $collection->addAttributeToFilter('created_at', array('gteq' => $filters['createdFrom']));
1025
+ }
1026
+
1027
+ if (isset($filters['createdTo']) && $filters['createdTo']){
1028
+ $collection->addAttributeToFilter('created_at', array('lteq' => $filters['createdTo']));
1029
+ }
1030
+
1031
+ if (isset($filters['id']) && $filters['id']){
1032
+ if (is_array($filters['id'])) {
1033
+ $collection->addAttributeToFilter($id_field, array('in'=>$filters['id']));
1034
+ } else {
1035
+ $collection->addAttributeToFilter($id_field, array('eq'=>$filters['id']));
1036
+ }
1037
+ }
1038
+
1039
+ $collection->setPage($page, $limit);
1040
+ }
1041
+
1042
+ private function _getReadDb(){
1043
+ return Mage::getSingleton('core/resource')->getConnection('core_read');
1044
+ }
1045
+
1046
+ private function _getEavEntityTypeId($type){
1047
+
1048
+ $db = $this->_getReadDb();
1049
+ $core_resource = Mage::getSingleton('core/resource');
1050
+
1051
+ $select = $db->select()
1052
+ ->from($core_resource->getTableName('eav_entity_type'), array('entity_type_id'))
1053
+ ->where('entity_type_code = ? ', $type);
1054
+
1055
+ return $db->fetchOne($select);
1056
+ }
1057
+
1058
+ private function _getStoreIdsForWebsites($website_ids){
1059
+
1060
+ if (!$website_ids) return array();
1061
+
1062
+ $db = Mage::getSingleton('core/resource')->getConnection('core_read');
1063
+ $core_resource = Mage::getSingleton('core/resource');
1064
+
1065
+ $select = $db->select()
1066
+ ->from(
1067
+ array(
1068
+ 's' => $core_resource->getTableName('core_store')
1069
+ ),
1070
+ array(
1071
+ 'store_id'
1072
+ )
1073
+ );
1074
+
1075
+ if (is_array($website_ids) && $website_ids){
1076
+ $select->where('website_id IN (?)', $website_ids);
1077
+ }
1078
+
1079
+ $rows = $db->fetchAll($select);
1080
+ $store_ids = array();
1081
+
1082
+ foreach($rows as $row){
1083
+ $store_ids[] = $row['store_id'];
1084
+ }
1085
+
1086
+ return $store_ids;
1087
+ }
1088
+ }
app/code/community/Ometria/Api/etc/api.xml ADDED
@@ -0,0 +1,193 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <config>
2
+ <api>
3
+ <resources>
4
+ <ometria_api translate="title" module="ometria_api">
5
+ <title>Ometria API version 1</title>
6
+ <model>ometria_api/api</model>
7
+ <methods>
8
+ <version translate="title" module="ometria_api">
9
+ <title>Get ometria API version info</title>
10
+ <acl>ometria_api/read</acl>
11
+ </version>
12
+ <get_stock_levels translate="title" module="ometria_api">
13
+ <title>Get stock levels</title>
14
+ <acl>ometria_api/read</acl>
15
+ </get_stock_levels>
16
+ <list_stores translate="title" module="ometria_api">
17
+ <title>Get list of stores</title>
18
+ <acl>ometria_api/read</acl>
19
+ </list_stores>
20
+ <list_categories translate="title" module="ometria_api">
21
+ <title>Get list of categories</title>
22
+ <acl>ometria_api/read</acl>
23
+ </list_categories>
24
+ <list_attributes translate="title" module="ometria_api">
25
+ <title>Get list of attributes</title>
26
+ <acl>ometria_api/read</acl>
27
+ </list_attributes>
28
+ <list_attribute_options translate="title" module="ometria_api">
29
+ <title>Get list of attribute options</title>
30
+ <acl>ometria_api/read</acl>
31
+ </list_attribute_options>
32
+ <list_subscribers translate="title" module="ometria_api">
33
+ <title>List newsletter subscribers</title>
34
+ <acl>ometria_api/read</acl>
35
+ </list_subscribers>
36
+ <list_products translate="title" module="ometria_api">
37
+ <title>Retrive all products IDs or all products IDs between two timestamps</title>
38
+ <acl>ometria_api/read</acl>
39
+ </list_products>
40
+ <list_transactions translate="title" module="ometria_api">
41
+ <title>Retrive all transaction IDs or all products IDs between two timestamps</title>
42
+ <acl>ometria_api/read</acl>
43
+ </list_transactions>
44
+ <list_customers translate="title" module="ometria_api">
45
+ <title>Retrive all customer IDs or all customer IDs between two timestamps</title>
46
+ <acl>ometria_api/read</acl>
47
+ </list_customers>
48
+ <get_products translate="title" module="ometria_api">
49
+ <title>Get multiple products by a list of IDs</title>
50
+ <acl>ometria_api/read</acl>
51
+ </get_products>
52
+ <get_transactions translate="title" module="ometria_api">
53
+ <title>Get multiple products by a list of IDs</title>
54
+ <acl>ometria_api/read</acl>
55
+ </get_transactions>
56
+ <get_customers translate="title" module="ometria_api">
57
+ <title>Get multiple customers by a list of IDs</title>
58
+ <acl>ometria_api/read</acl>
59
+ </get_customers>
60
+ <product_collection_size translate="title" module="ometria_api">
61
+ <title>Count all products between two timestamps</title>
62
+ <acl>ometria_api/read</acl>
63
+ </product_collection_size>
64
+ <transaction_collection_size translate="title" module="ometria_api">
65
+ <title>Count all transactions between two timestamps</title>
66
+ <acl>ometria_api/read</acl>
67
+ </transaction_collection_size>
68
+ <customer_collection_size translate="title" module="ometria_api">
69
+ <title>Count all customers between two timestamps</title>
70
+ <acl>ometria_api/read</acl>
71
+ </customer_collection_size>
72
+ </methods>
73
+ <faults module="ometria_api">
74
+ <data_invalid>
75
+ <code>1000</code>
76
+ <message>Invalid input data. Details in error message.</message>
77
+ </data_invalid>
78
+ </faults>
79
+ </ometria_api>
80
+ <ometria_api2 translate="title" module="ometria_api">
81
+ <title>Ometria API version 2</title>
82
+ <model>ometria_api/api2</model>
83
+ <methods>
84
+ <get_magento_info translate="title" module="ometria_api">
85
+ <title>Get Magento instance info</title>
86
+ <acl>ometria_api/read</acl>
87
+ </get_magento_info>
88
+ <get_settings translate="title" module="ometria_api">
89
+ <title>Get Ometria Magento extension settings</title>
90
+ <acl>ometria_api/read</acl>
91
+ </get_settings>
92
+ <set_settings translate="title" module="ometria_api">
93
+ <title>Set Ometria Magento extension settings</title>
94
+ <acl>ometria_api/read</acl>
95
+ </set_settings>
96
+
97
+
98
+ <customers_list translate="title" module="ometria_api">
99
+ <title>List customers</title>
100
+ <acl>ometria_api/read</acl>
101
+ </customers_list>
102
+ <products_list translate="title" module="ometria_api">
103
+ <title>List products</title>
104
+ <acl>ometria_api/read</acl>
105
+ </products_list>
106
+
107
+ <products_flat_list translate="title" module="ometria_api">
108
+ <title>Get flat product catalog</title>
109
+ <acl>ometria_api/read</acl>
110
+ </products_flat_list>
111
+ <product_attributes_list translate="title" module="ometria_api">
112
+ <title>List all product attributes</title>
113
+ <acl>ometria_api/read</acl>
114
+ </product_attributes_list>
115
+ <orders_list translate="title" module="ometria_api">
116
+ <title>List orders</title>
117
+ <acl>ometria_api/read</acl>
118
+ </orders_list>
119
+ <orders_count translate="title" module="ometria_api">
120
+ <title>Count orders</title>
121
+ <acl>ometria_api/read</acl>
122
+ </orders_count>
123
+ <orders_statuses_list translate="title" module="ometria_api">
124
+ <title>List order statuses</title>
125
+ <acl>ometria_api/read</acl>
126
+ </orders_statuses_list>
127
+ <stores_list translate="title" module="ometria_api">
128
+ <title>List stores / websites</title>
129
+ <acl>ometria_api/read</acl>
130
+ </stores_list>
131
+ <carts_list translate="title" module="ometria_api">
132
+ <title>List carts</title>
133
+ <acl>ometria_api/read</acl>
134
+ </carts_list>
135
+
136
+
137
+ <salesrules_list translate="title" module="ometria_api">
138
+ <title>List cart sales rules</title>
139
+ <acl>ometria_api/read</acl>
140
+ </salesrules_list>
141
+ <salesrules_list_coupons translate="title" module="ometria_api">
142
+ <title>List cart sales rule coupons</title>
143
+ <acl>ometria_api/read</acl>
144
+ </salesrules_list_coupons>
145
+ <salesrules_create_coupons translate="title" module="ometria_api">
146
+ <title>Create cart sales rule coupons</title>
147
+ <acl>ometria_api/create_coupon</acl>
148
+ </salesrules_create_coupons>
149
+
150
+ <subscribers_subscribe translate="title" module="ometria_api">
151
+ <title>Add subscribers</title>
152
+ <acl>ometria_api/change_subscribers</acl>
153
+ </subscribers_subscribe>
154
+ <subscribers_unsubscribe translate="title" module="ometria_api">
155
+ <title>Remove subscribers</title>
156
+ <acl>ometria_api/change_subscribers</acl>
157
+ </subscribers_unsubscribe>
158
+ <subscribers_list translate="title" module="ometria_api">
159
+ <title>List all subscribers</title>
160
+ <acl>ometria_api/read</acl>
161
+ </subscribers_list>
162
+ </methods>
163
+ <faults module="ometria_api">
164
+ <data_invalid>
165
+ <code>1000</code>
166
+ <message>Invalid input data. Details in error message.</message>
167
+ </data_invalid>
168
+ </faults>
169
+ </ometria_api2>
170
+ </resources>
171
+
172
+ <acl>
173
+ <resources>
174
+ <ometria_api translate="title" module="ometria_api">
175
+ <title>Ometria API</title>
176
+ <acl>ometria_api</acl>
177
+ <read translate="title" module="ometria_api">
178
+ <title>Read from Ometria API</title>
179
+ <acl>ometria_api/read</acl>
180
+ </read>
181
+ <create_coupon translate="title" module="ometria_api">
182
+ <title>Create coupons via Ometria API</title>
183
+ <acl>ometria_api/create_coupon</acl>
184
+ </create_coupon>
185
+ <change_subscribers translate="title" module="ometria_api">
186
+ <title>Add and alter subscribers via API</title>
187
+ <acl>ometria_api/change_subscribers</acl>
188
+ </change_subscribers>
189
+ </ometria_api>
190
+ </resources>
191
+ </acl>
192
+ </api>
193
+ </config>
app/code/community/Ometria/Api/etc/config.xml ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Ometria_Api>
5
+ <version>1.0.0</version>
6
+ </Ometria_Api>
7
+ </modules>
8
+
9
+ <global>
10
+ <blocks>
11
+ <ometria_api>
12
+ <class>Ometria_Api_Block</class>
13
+ </ometria_api>
14
+ </blocks>
15
+ <models>
16
+ <ometria_api>
17
+ <class>Ometria_Api_Model</class>
18
+ </ometria_api>
19
+ </models>
20
+ <helpers>
21
+ <ometria_api>
22
+ <class>Ometria_Api_Helper</class>
23
+ </ometria_api>
24
+ </helpers>
25
+ </global>
26
+
27
+ <phpunit>
28
+ <suite>
29
+ <modules>
30
+ <Ometria_Api />
31
+ </modules>
32
+ </suite>
33
+ </phpunit>
34
+ </config>
app/code/community/Ometria/Core/.DS_Store ADDED
Binary file
app/code/community/Ometria/Core/Block/Adminhtml/System/Config/Startwizard.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Ometria_Core_Block_Adminhtml_System_Config_Startwizard extends Mage_Adminhtml_Block_System_Config_Form_Field {
3
+
4
+ public function canOpenWizard() {
5
+ return Mage::helper('ometria/config')->getAPIKey();
6
+ }
7
+
8
+ protected function _prepareLayout() {
9
+ parent::_prepareLayout();
10
+ if (!$this->getTemplate()) {
11
+ $this->setTemplate('ometria/system/config/start_wizard.phtml');
12
+ }
13
+ return $this;
14
+ }
15
+
16
+ protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element) {
17
+ $originalData = $element->getOriginalData();
18
+
19
+ $this->addData(array(
20
+ 'button_label' => Mage::helper('ometria')->__($originalData['button_label']),
21
+ 'button_url' => Mage::helper('adminhtml')->getUrl($originalData['button_url']),
22
+ 'html_id' => $element->getHtmlId(),
23
+ ));
24
+
25
+ return $this->_toHtml();
26
+ }
27
+ }
app/code/community/Ometria/Core/Block/Adminhtml/Wizard/Finished.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Ometria_Core_Block_Adminhtml_Wizard_Finished extends Mage_Adminhtml_Block_Template {
3
+
4
+ public function getResults() {
5
+ if (!$result = $this->getData('result')) {
6
+ $result = Mage::getSingleton('adminhtml/session')->getData('ometria_wizard_result');
7
+ }
8
+ return $result;
9
+ }
10
+
11
+ /**
12
+ * Determine if the result was successful or not. We class it as unsuccessful if one of the entries has an 'error'
13
+ * status.
14
+ *
15
+ * @return bool
16
+ */
17
+ public function getWasSuccessful() {
18
+ $results = $this->getResults();
19
+ return array_reduce($results, array($this, '_checkForError'));
20
+ }
21
+
22
+ protected function _checkForError($result, $entry) {
23
+ if ($result === false) {
24
+ return false;
25
+ }
26
+
27
+ if ($entry['status'] == 'error') {
28
+ return false;
29
+ }
30
+
31
+ return true;
32
+ }
33
+ }
app/code/community/Ometria/Core/Block/Adminhtml/Wizard/Start.php ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Ometria_Core_Block_Adminhtml_Wizard_Start extends Mage_Adminhtml_Block_Widget_Form_Container {
3
+
4
+ public function __construct() {
5
+ parent::__construct();
6
+ $this->_blockGroup = 'ometria';
7
+ $this->_controller = 'adminhtml_wizard';
8
+ $this->_mode = 'start';
9
+
10
+ $this->_updateButton('save', 'label', Mage::helper('ometria')->__('Next'));
11
+ $this->_updateButton('save', 'onclick', 'if (editForm.submit()) { document.getElementById(\'loading-mask\').show(); }');
12
+ $this->_updateButton('back', 'label', Mage::helper('ometria')->__('Cancel'));
13
+ $this->_updateButton('back', 'onclick', 'window.close()');
14
+ $this->_removeButton('reset');
15
+ }
16
+
17
+ public function getHeaderText() {
18
+ return Mage::helper('ometria')->__('Ometria Setup Wizard');
19
+ }
20
+ }
app/code/community/Ometria/Core/Block/Adminhtml/Wizard/Start/Form.php ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Ometria_Core_Block_Adminhtml_Wizard_Start_Form extends Mage_Adminhtml_Block_Widget_Form {
3
+
4
+ protected function _prepareForm() {
5
+ $id = $this->getRequest()->getParam('id');
6
+
7
+ $form = new Varien_Data_Form(array(
8
+ 'id' => 'edit_form',
9
+ 'action' => $this->getUrl('*/*/process', array('id' => $id)),
10
+ 'method' => 'post',
11
+ ));
12
+
13
+ $fieldset = $form->addFieldset('base_fieldset', array(
14
+ 'legend' => Mage::helper('ometria')->__('Ometria Customer Details'),
15
+ 'class' => 'fieldset-wide',
16
+ ));
17
+
18
+ $fieldset->addField('api_key', 'text', array(
19
+ 'label' => 'Web Services User Password',
20
+ 'title' => 'Web Services User Password',
21
+ 'name' => 'api_key',
22
+ 'after_element_html' => '<p class="note"><span>This value will be provided to you by Ometria</span></p>',
23
+ 'required' => true
24
+ ));
25
+
26
+ $form->setValues(array());
27
+ $form->setUseContainer(true);
28
+ $this->setForm($form);
29
+ return parent::_prepareForm();
30
+ }
31
+ }
app/code/community/Ometria/Core/Block/Head.php ADDED
@@ -0,0 +1,252 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Ometria_Core_Block_Head extends Mage_Core_Block_Template {
4
+
5
+
6
+ const PAGE_TYPE_BASKET = 'basket';
7
+ const PAGE_TYPE_CHECKOUT = 'checkout';
8
+ const PAGE_TYPE_CMS = 'content';
9
+ const PAGE_TYPE_CATEGORY = 'listing';
10
+ const PAGE_TYPE_CONFIRMATION = 'confirmation';
11
+ const PAGE_TYPE_HOMEPAGE = 'homepage';
12
+ const PAGE_TYPE_PRODUCT = 'product';
13
+ const PAGE_TYPE_SEARCH = 'search';
14
+
15
+ const OM_QUERY = 'query';
16
+ const OM_SITE = 'store';
17
+ const OM_PAGE_TYPE = 'type';
18
+ const OM_PAGE_DATA = 'data';
19
+
20
+
21
+ public function getDataLayer() {
22
+ $category = 'null';
23
+ $page = array();
24
+ $page[self::OM_SITE] = $this->_getStore();
25
+ $page['store_url'] = Mage::getBaseUrl();
26
+
27
+ $page['route'] = $this->_getRouteName();
28
+ $page['controller'] = $this->_getControllerName();
29
+ $page['action'] = $this->_getActionName();
30
+
31
+ if ($this->_isHomepage()) {
32
+ $page[self::OM_PAGE_TYPE] = self::PAGE_TYPE_HOMEPAGE;
33
+
34
+ } elseif ($this->_isCMSPage()) {
35
+ $page[self::OM_PAGE_TYPE] = self::PAGE_TYPE_CMS;
36
+
37
+ } elseif ($this->_isCategory()) {
38
+ $page[self::OM_PAGE_TYPE] = self::PAGE_TYPE_CATEGORY;
39
+
40
+ } elseif ($this->_isSearch()) {
41
+ $page[self::OM_PAGE_TYPE] = self::PAGE_TYPE_SEARCH;
42
+
43
+ if($query = $this->_getSearchQuery()) $page[self::OM_QUERY] = $query;
44
+
45
+ } elseif ($this->_isProduct()) {
46
+ $page[self::OM_PAGE_TYPE] = self::PAGE_TYPE_PRODUCT;
47
+ $page[self::OM_PAGE_DATA] = $this->_getProductPageData();
48
+
49
+ } elseif ($this->_isBasket()) {
50
+ $page[self::OM_PAGE_TYPE] = self::PAGE_TYPE_BASKET;
51
+
52
+ } elseif ($this->_isCheckout()) {
53
+ $page[self::OM_PAGE_TYPE] = self::PAGE_TYPE_CHECKOUT;
54
+ if ($step = $this->_getCheckoutStep()) $page[self::OM_PAGE_DATA] = array('step'=>$step);
55
+
56
+ } elseif ($this->_isOrderConfirmation()) {
57
+ $page[self::OM_PAGE_TYPE] = self::PAGE_TYPE_CONFIRMATION;
58
+ $page[self::OM_PAGE_DATA] = $this->_getOrderData();
59
+ }
60
+
61
+ if ($category = Mage::registry("current_category")) {
62
+ $page['category'] = array(
63
+ 'id'=>$category->getId(),
64
+ 'path'=>$category->url_path
65
+ );
66
+ }
67
+
68
+ return $page;
69
+ }
70
+
71
+ protected function _getCheckoutStep() {
72
+ if(!$this->_isCheckout())
73
+ return false;
74
+
75
+ if($step = Mage::app()->getRequest()->getParam('step'))
76
+ return $step;
77
+
78
+ return false;
79
+ }
80
+
81
+ protected function _getOrderData() {
82
+ if (!$this->_isOrderConfirmation())
83
+ return false;
84
+
85
+ if ($orderId = $this->_getCheckoutSession()->getLastOrderId()) {
86
+ /** @var Mage_Sales_Model_Order $order */
87
+ $order = Mage::getModel('sales/order')->load($orderId);
88
+
89
+ return array(
90
+ 'id' => $order->getIncrementId()
91
+ );
92
+ }
93
+
94
+ return false;
95
+ }
96
+
97
+ protected function _getCheckoutSession() {
98
+ if ($this->_isBasket())
99
+ return Mage::getSingleton('checkout/cart');
100
+
101
+ return Mage::getSingleton('checkout/session');
102
+ }
103
+
104
+ protected function _getProductPageData(){
105
+
106
+ $product = Mage::registry("current_product");
107
+
108
+ if (!$product && $id = $this->getProductId()) {
109
+ $product = Mage::getModel("catalog/product")->load($id);
110
+ }
111
+
112
+ if ($product) {
113
+ return $this->_getProductInfo($product);
114
+ }
115
+
116
+ return false;
117
+ }
118
+
119
+ /**
120
+ * Get limited product info from product
121
+ * Used in listing, baskets, transactions
122
+ * @param Mage_Catalog_Model_Product $product
123
+ * @return array
124
+ */
125
+ protected function _getProductInfo($product) {
126
+ $ometria_product_helper = Mage::helper('ometria/product');
127
+
128
+ if($product instanceof Mage_Catalog_Model_Product) {
129
+ return array(
130
+ 'id' => $ometria_product_helper->getIdentifierForProduct($product),
131
+ 'sku' => $product->getSku(),
132
+ 'name' => $product->getName(),
133
+ 'url' => $product->getProductUrl()
134
+ );
135
+ }
136
+
137
+ return false;
138
+ }
139
+
140
+ /**
141
+ * Get Controller name
142
+ * @return string
143
+ */
144
+ protected function _getControllerName() {
145
+ return $this->getRequest()->getRequestedControllerName();
146
+ }
147
+
148
+ /**
149
+ * Get Action name
150
+ * @return string
151
+ */
152
+ protected function _getActionName() {
153
+ return $this->getRequest()->getRequestedActionName();
154
+ }
155
+
156
+ /**
157
+ * Get Route name
158
+ * @return string
159
+ */
160
+ protected function _getRouteName() {
161
+ return $this->getRequest()->getRequestedRouteName();
162
+ }
163
+
164
+ /**
165
+ * Check if home page
166
+ * @return bool
167
+ */
168
+ protected function _isHomepage() {
169
+ return $this->getUrl('') == $this->getUrl('*/*/*', array('_current'=>true, '_use_rewrite'=>true));
170
+ }
171
+
172
+ /**
173
+ * Check if cms page
174
+ * @return bool
175
+ */
176
+ protected function _isCMSPage() {
177
+ return $this->_getRouteName() == 'cms';
178
+ }
179
+
180
+ /**
181
+ * Check if category page
182
+ * @return bool
183
+ */
184
+ protected function _isCategory() {
185
+ return $this->_getRouteName() == 'catalog'
186
+ && $this->_getControllerName() == 'category';
187
+ }
188
+
189
+ /**
190
+ * Check if search page
191
+ * @return bool
192
+ */
193
+ protected function _isSearch() {
194
+ return $this->_getRouteName() == 'catalogsearch';
195
+ }
196
+
197
+ /**
198
+ * Check if product page
199
+ * @return bool
200
+ */
201
+ protected function _isProduct() {
202
+ return $this->_getRouteName() == 'catalog'
203
+ && $this->_getControllerName() == 'product';
204
+ }
205
+
206
+ /**
207
+ * Check if basket
208
+ * @return bool
209
+ */
210
+ protected function _isBasket() {
211
+ return $this->_getRouteName() == 'checkout'
212
+ && $this->_getControllerName() == 'cart'
213
+ && $this->_getActionName() == 'index';
214
+ }
215
+
216
+ /**
217
+ * Check if checkout
218
+ * @return bool
219
+ */
220
+ protected function _isCheckout() {
221
+ return strpos($this->_getRouteName(), 'checkout') !== false
222
+ && $this->_getActionName() != 'success';
223
+ }
224
+
225
+ /**
226
+ * Check if success page
227
+ * @return bool
228
+ */
229
+ protected function _isOrderConfirmation() {
230
+ return strpos($this->_getRouteName(), 'checkout') !== false
231
+ && $this->_getActionName() == 'success';
232
+ }
233
+
234
+ /**
235
+ * Get Store id
236
+ * @return string|int
237
+ */
238
+ protected function _getStore() {
239
+ return Mage::app()->getStore()->getStoreId();
240
+ }
241
+
242
+ /**
243
+ * Get search query text
244
+ * @return string
245
+ */
246
+ protected function _getSearchQuery() {
247
+ if(!$this->_isSearch())
248
+ return false;
249
+
250
+ return Mage::helper('catalogsearch')->getQueryText();
251
+ }
252
+ }
app/code/community/Ometria/Core/Helper/Config.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Ometria_Core_Helper_Config extends Mage_Core_Helper_Abstract {
4
+
5
+ public function isEnabled() {
6
+ return Mage::getStoreConfigFlag('ometria/general/enabled');
7
+ }
8
+
9
+ public function isDebugMode() {
10
+ return Mage::getStoreConfigFlag('ometria/advanced/debug');
11
+ }
12
+
13
+ // Is data layer configured?
14
+ public function isUnivarEnabled() {
15
+ return Mage::getStoreConfigFlag('ometria/advanced/univar');
16
+ }
17
+
18
+ public function isPingEnabled() {
19
+ return Mage::getStoreConfigFlag('ometria/advanced/ping');
20
+ }
21
+
22
+ public function isScriptDeferred() {
23
+ return Mage::getStoreConfigFlag('ometria/advanced/scriptload');
24
+ }
25
+
26
+ public function getAPIKey() {
27
+ return Mage::getStoreConfig('ometria/general/apikey');
28
+ }
29
+
30
+ public function isConfigured() {
31
+ return $this->isEnabled() && $this->getAPIKey() != "";
32
+ }
33
+
34
+ public function log($message, $level = Zend_Log::DEBUG) {
35
+ Mage::log($message, $level, "ometria.log");
36
+ }
37
+ }
app/code/community/Ometria/Core/Helper/Cookiechannel.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Ometria_Core_Helper_Cookiechannel extends Mage_Core_Helper_Abstract {
4
+
5
+ const COOKIE_NAME = 'ommage';
6
+ const SEPERATOR_BETWEEN_COMMANDS = ';';
7
+ const SEPERATOR_IN_COMMANDS = ':';
8
+
9
+ public function addCommand($command, $replace_if_exists=false){
10
+ if (!$command || !is_array($command)) return;
11
+
12
+ $ometria_config_helper = Mage::helper('ometria/config');
13
+ if (!$ometria_config_helper->isConfigured()) return;
14
+ if (!$ometria_config_helper->isUnivarEnabled()) return;
15
+
16
+ $str = implode(self::SEPERATOR_IN_COMMANDS, $command);
17
+
18
+ $this->appendCookieCommand($command[0], $str, $replace_if_exists);
19
+ }
20
+
21
+ private function appendCookieCommand($command_name, $str, $replace_if_exists=false){
22
+ $existing_cookie = isset($_COOKIE[self::COOKIE_NAME]) ? $_COOKIE[self::COOKIE_NAME] : '';
23
+ $new_cookie = '';
24
+
25
+ if ($replace_if_exists && $existing_cookie) {
26
+ $_commands = explode(self::SEPERATOR_BETWEEN_COMMANDS, $existing_cookie);
27
+ $commands = array();
28
+ foreach($_commands as $command){
29
+ if (strpos($command, $command_name.self::SEPERATOR_IN_COMMANDS)!==0) {
30
+ $commands[] = $command;
31
+ }
32
+ }
33
+ $commands = array_filter($commands);
34
+ $existing_cookie = implode(self::SEPERATOR_BETWEEN_COMMANDS, $commands);
35
+ }
36
+
37
+ if ($existing_cookie){
38
+
39
+ $new_cookie = $existing_cookie.self::SEPERATOR_BETWEEN_COMMANDS.$str;
40
+ } else {
41
+ $new_cookie = $str;
42
+ }
43
+
44
+ $_COOKIE[self::COOKIE_NAME] = $new_cookie;
45
+ setcookie(self::COOKIE_NAME, $new_cookie, 0, '/');
46
+ }
47
+ }
app/code/community/Ometria/Core/Helper/Data.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Ometria_Core_Helper_Data extends Mage_Core_Helper_Abstract {
4
+
5
+ /**
6
+ * Get extension version
7
+ * @return string
8
+ */
9
+ public function getExtensionVersion() {
10
+ return Mage::getConfig()->getModuleConfig('Ometria_Core')->version;
11
+ }
12
+ }
app/code/community/Ometria/Core/Helper/Ping.php ADDED
@@ -0,0 +1,99 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Ometria_Core_Helper_Ping extends Mage_Core_Helper_Abstract {
4
+
5
+ const API_HOST = 'trk.ometria.com';
6
+ const API_SOCKET_SCHEMA = 'ssl://';
7
+ const API_PATH = '/ping.php';
8
+ const API_SOCKET_TIMEOUT = 2;
9
+
10
+ public function sendPing($type, $ids, $extra=array()){
11
+ $ometriaConfigHelper = Mage::helper('ometria/config');
12
+
13
+ if (!$ometriaConfigHelper->isConfigured()) {
14
+ return false;
15
+ }
16
+
17
+ if (!$ometriaConfigHelper->isPingEnabled()) {
18
+ return true;
19
+ }
20
+
21
+ if($ometriaConfigHelper->isDebugMode()) {
22
+ if(is_array($ids)) {
23
+ $ometriaConfigHelper->log("Sending ping. Type: ".$type." " . implode(',', $ids));
24
+ } else {
25
+ $ometriaConfigHelper->log("Sending ping. Type: ".$type." " . $ids);
26
+ }
27
+ }
28
+
29
+ $extra['account'] = $ometriaConfigHelper->getAPIKey();
30
+ $extra['type'] = $type;
31
+ $extra['id'] = $ids;
32
+
33
+ return $this->_ping($extra);
34
+ }
35
+
36
+ /**
37
+ * Helper function to ping ometria. Manually doing an fsockopen
38
+ * so that we don't have to wait for a response. Unless debugging
39
+ * when we do wait and log the content body.
40
+ *
41
+ * @param array $parameters
42
+ *
43
+ * @return bool
44
+ */
45
+ protected function _ping($parameters = array()) {
46
+
47
+ //file_put_contents('/tmp/ping', json_encode($parameters)."\n", FILE_APPEND);
48
+ //return true;
49
+
50
+ $ometriaConfigHelper = Mage::helper('ometria/config');
51
+
52
+ $content = http_build_query($parameters);
53
+ $path = self::API_PATH;
54
+
55
+
56
+ try {
57
+
58
+ $fp = fsockopen(self::API_SOCKET_SCHEMA . self::API_HOST, 443, $errorNum, $errorStr, self::API_SOCKET_TIMEOUT);
59
+
60
+ if($fp !== false) {
61
+
62
+ $out = "POST $path HTTP/1.1\r\n";
63
+ $out .= "Host: " . self::API_HOST. "\r\n";
64
+ $out .= "Content-type: application/x-www-form-urlencoded\r\n";
65
+ $out .= "Content-Length: " . strlen($content) . "\r\n";
66
+ $out .= "Connection: Close\r\n\r\n";
67
+ $out .= $content;
68
+
69
+ fwrite($fp, $out);
70
+
71
+ // If debug mode, wait for response and log
72
+ if($ometriaConfigHelper->isDebugMode()) {
73
+
74
+ $responseHeader = "";
75
+ do {
76
+ $responseHeader .= fgets($fp, 1024);
77
+ } while(strpos($responseHeader, "\r\n\r\n") === false);
78
+
79
+ $response = "";
80
+ while (!feof($fp)) {
81
+ $response .= fgets($fp, 1024);
82
+ }
83
+
84
+ $ometriaConfigHelper->log($response);
85
+ }
86
+
87
+ fclose($fp);
88
+ } else {
89
+ $ometriaConfigHelper->log("Ping failed: Error $errorNum - $errorStr", Zend_Log::ERR);
90
+ return false;
91
+ }
92
+ } catch (Exception $e) {
93
+ $ometriaConfigHelper->log($e->getMessage());
94
+ return false;
95
+ }
96
+
97
+ return true;
98
+ }
99
+ }
app/code/community/Ometria/Core/Helper/Product.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Ometria_Core_Helper_Product extends Mage_Core_Helper_Abstract {
4
+
5
+ public function isSkuMode(){
6
+ return Mage::getStoreConfig('ometria/advanced/productmode')=='sku';
7
+ }
8
+
9
+ public function getIdentifierForProduct($product) {
10
+ if (!$product) return null;
11
+
12
+
13
+ if ($this->isSkuMode()) {
14
+ return $product->getSku();
15
+ } else {
16
+ return $product->getId();
17
+ }
18
+ }
19
+
20
+ public function getIdentifiersForProducts($products) {
21
+
22
+ $is_sku_mode = $this->isSkuMode();
23
+
24
+ $ret = array();
25
+ foreach($products as $product){
26
+ if ($is_sku_mode) {
27
+ $ret[] = $product->getSku();
28
+ } else {
29
+ $ret[] = $product->getId();
30
+ }
31
+ }
32
+
33
+ return $ret;
34
+
35
+ }
36
+
37
+ public function convertProductIdsIfNeeded($ids){
38
+
39
+ if (!$this->isSkuMode()) {
40
+ return $ids;
41
+ }
42
+
43
+ if (!$ids) return $ids;
44
+
45
+ $was_array = is_array($ids);
46
+ if (!is_array($ids)) $ids = array($ids);
47
+
48
+ $products_collection = Mage::getModel('catalog/product')
49
+ ->getCollection()
50
+ ->addAttributeToFilter('entity_id', array('in' => $ids));
51
+
52
+ $skus = array();
53
+ foreach($products_collection as $product) {
54
+ $skus[] = $product->getSku();
55
+ $product->clearInstance();
56
+ }
57
+
58
+ if (!$was_array) {
59
+ return count($skus)>0 ? $skus[0] : null;
60
+ } else {
61
+ return $skus;
62
+ }
63
+ }
64
+
65
+ public function getProductByIdentifier($id){
66
+ $product_model = Mage::getModel('catalog/product');
67
+
68
+ if ($this->isSkuMode()){
69
+ return $product_model->load($product_model->getIdBySku($id));
70
+ } else {
71
+ return $product_model->load($id);
72
+ }
73
+ }
74
+ }
app/code/community/Ometria/Core/Helper/Session.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Ometria_Core_Helper_Session extends Mage_Core_Helper_Abstract {
4
+
5
+ public function getSessionID() {
6
+ $cookie = isset($_COOKIE['ometria']) ? $_COOKIE['ometria'] : '';
7
+ $session_id = null;
8
+
9
+ if ($cookie){
10
+ $data = array();
11
+ parse_str($cookie, $data);
12
+ if (isset($data['sid'])) $session_id = $data['sid'];
13
+ }
14
+
15
+ return $session_id;
16
+ }
17
+ }
app/code/community/Ometria/Core/Model/.DS_Store ADDED
Binary file
app/code/community/Ometria/Core/Model/Config/Source/Productmode.php ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Ometria_Core_Model_Config_Source_Productmode
4
+ {
5
+ public function toOptionArray()
6
+ {
7
+ return array(
8
+ array('value' => 'id', 'label' => 'Product ID'),
9
+ array('value' => 'sku', 'label' => 'Product SKU')
10
+ );
11
+ }
12
+ }
app/code/community/Ometria/Core/Model/Observer/Cart.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Ometria_Core_Model_Observer_Cart {
4
+
5
+ public function basketUpdated(Varien_Event_Observer $observer){
6
+ $this->updateBasketCookie();
7
+ }
8
+
9
+ public function updateBasketCookie() {
10
+
11
+ $ometria_product_helper = Mage::helper('ometria/product');
12
+ $ometria_cookiechannel_helper = Mage::helper('ometria/cookiechannel');
13
+ $cart = Mage::getModel('checkout/cart')->getQuote();
14
+
15
+ $cart_token = md5($cart->created_at.$cart->remote_ip);
16
+
17
+ $command = array(
18
+ 'basket',
19
+ $cart->getId(),
20
+ $cart->getGrandTotal(),
21
+ Mage::app()->getStore()->getCurrentCurrencyCode(),
22
+ $cart_token
23
+ );
24
+
25
+ $count = 0;
26
+ foreach($cart->getAllVisibleItems() as $item){
27
+
28
+ $product = Mage::getModel('catalog/product')->load($item->getProductId());
29
+ $buffer = array(
30
+ 'i'=>$ometria_product_helper->getIdentifierForProduct($product),
31
+ //'s'=>$product->getSku(),
32
+ //'v'=>$item->getSku(),
33
+ 'q'=>$item->getQty(),
34
+ );
35
+ $command_part = http_build_query($buffer);
36
+ $command[] = $command_part;
37
+
38
+ $count++;
39
+ if ($count>30) break; // Prevent overly long cookies
40
+ }
41
+
42
+ $ometria_cookiechannel_helper->addCommand($command, true);
43
+
44
+ return $this;
45
+ }
46
+
47
+ public function orderPlaced(Varien_Event_Observer $observer){
48
+
49
+ $ometria_session_helper = Mage::helper('ometria/session');
50
+ $ometria_cookiechannel_helper = Mage::helper('ometria/cookiechannel');
51
+
52
+ try{
53
+ $ometria_ping_helper = Mage::helper('ometria/ping');
54
+ $order = $observer->getEvent()->getOrder();
55
+ $session_id = $ometria_session_helper->getSessionId();
56
+ if ($session_id) {
57
+ $ometria_ping_helper->sendPing('transaction', $order->getIncrementId(), array('session'=>$session_id));
58
+ }
59
+
60
+ $ometria_cookiechannel_helper->addCommand(array('trans', $order->getIncrementId()));
61
+ } catch(Exception $e){
62
+ //pass
63
+ }
64
+ }
65
+ }
app/code/community/Ometria/Core/Model/Observer/Customer.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Ometria_Core_Model_Observer_Customer {
4
+
5
+ var $did_register = false;
6
+
7
+ public function customerSaveAfter(Varien_Event_Observer $observer) {
8
+
9
+ $ometria_ping_helper = Mage::helper('ometria/ping');
10
+ $order = $observer->getEvent()->getCustomer();
11
+ $ometria_ping_helper->sendPing('customer', $order->getId());
12
+
13
+ return $this;
14
+ }
15
+
16
+ public function loggedOut(Varien_Event_Observer $observer){
17
+ $this->identify('logout');
18
+ }
19
+
20
+ public function loggedIn(Varien_Event_Observer $observer){
21
+ $this->identify('login');
22
+ }
23
+
24
+ public function registered(Varien_Event_Observer $observer){
25
+ $this->did_register = true;
26
+ $this->identify('register');
27
+ }
28
+
29
+ protected function identify($event){
30
+ $ometria_cookiechannel_helper = Mage::helper('ometria/cookiechannel');
31
+
32
+ if ($this->did_register && $event=='login') {
33
+ $event = 'register';
34
+ }
35
+
36
+ $customer = Mage::getSingleton('customer/session')->getCustomer();
37
+ //if (!$customer) return;
38
+ $data = array('e'=>$customer->getEmail(),'i'=>$customer->getId());
39
+ $command = array('identify', $event, http_build_query($data));
40
+
41
+ $ometria_cookiechannel_helper->addCommand($command, true);
42
+ }
43
+ }
app/code/community/Ometria/Core/Model/Observer/Newsletter.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Ometria_Core_Model_Observer_Newsletter {
4
+ public function handleSubscriberUpdate(Varien_Event_Observer $observer){
5
+ $ometria_ping_helper = Mage::helper('ometria/ping');
6
+
7
+ $subscriber = $observer->getEvent()->getSubscriber();
8
+
9
+ $data = $subscriber->getData();
10
+ $status_change = $subscriber->getIsStatusChanged();
11
+
12
+ // Only if status has changed
13
+ if ($status_change) {
14
+ $event = null;
15
+ if ($data['subscriber_status']==1) $event = 'newsletter_subscribed';
16
+ if ($data['subscriber_status']==3) $event = 'newsletter_unsubscribed';
17
+ if ($event) $ometria_ping_helper->sendPing($event, $subscriber->getEmail());
18
+
19
+ // Update timestamp column
20
+ $subscriber->change_status_at = time();
21
+ }
22
+ }
23
+
24
+ public function handleSubscriberDeletion(Varien_Event_Observer $observer){
25
+ $ometria_ping_helper = Mage::helper('ometria/ping');
26
+
27
+ $subscriber = $observer->getEvent()->getSubscriber();
28
+ $ometria_ping_helper->sendPing('newsletter_unsubscribed', $subscriber->getEmail());
29
+ }
30
+ }
app/code/community/Ometria/Core/Model/Observer/Order.php ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Ometria_Core_Model_Observer_Order {
4
+
5
+ /**
6
+ * Sales Order After Save
7
+ *
8
+ * @param Varien_Event_Observer $observer
9
+ * @return Ometria_Core_Model_Observer_Order
10
+ */
11
+ public function salesOrderSaveAfter(Varien_Event_Observer $observer) {
12
+
13
+ $ometria_ping_helper = Mage::helper('ometria/ping');
14
+ $order = $observer->getEvent()->getOrder();
15
+ $ometria_ping_helper->sendPing('transaction', $order->getIncrementId());
16
+
17
+ return $this;
18
+ }
19
+ }
app/code/community/Ometria/Core/Model/Observer/Product.php ADDED
@@ -0,0 +1,91 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Class Ometria_Core_Model_Observer_Product
4
+ */
5
+ class Ometria_Core_Model_Observer_Product {
6
+
7
+ /**
8
+ * Catalog Product Delete After
9
+ *
10
+ * @param Varien_Event_Observer $observer
11
+ * @return Ometria_Core_Model_Observer_Product
12
+ */
13
+ public function catalogProductDeleteAfter(Varien_Event_Observer $observer) {
14
+ Varien_Profiler::start("Ometria::" . __METHOD__);
15
+
16
+ $product = $observer->getEvent()->getProduct();
17
+ $this->updateProducts($product->getId());
18
+
19
+ Varien_Profiler::stop("Ometria::" . __METHOD__);
20
+
21
+ return $this;
22
+ }
23
+
24
+ /**
25
+ * Catalog Product Save After
26
+ *
27
+ * @param Varien_Event_Observer $observer
28
+ * @return Ometria_Core_Model_Observer_Product
29
+ */
30
+ public function catalogProductSaveAfter(Varien_Event_Observer $observer) {
31
+ Varien_Profiler::start("Ometria::" . __METHOD__);
32
+
33
+ $product = $observer->getEvent()->getProduct();
34
+ $this->updateProducts($product->getId());
35
+
36
+ Varien_Profiler::stop("Ometria::" . __METHOD__);
37
+
38
+ return $this;
39
+ }
40
+
41
+ /**
42
+ * Product Mass Action - Update Attributes
43
+ *
44
+ * @param Varien_Event_Observer $observer
45
+ * @return Ometria_Core_Model_Observer_Product
46
+ */
47
+ public function catalogProductUpdateAttributes(Varien_Event_Observer $observer) {
48
+ Varien_Profiler::start("Ometria::" . __METHOD__);
49
+
50
+ $productIds = Mage::helper('adminhtml/catalog_product_edit_action_attribute')->getProductIds();
51
+ $this->updateProducts($productIds);
52
+
53
+ Varien_Profiler::stop("Ometria::" . __METHOD__);
54
+
55
+ return $this;
56
+ }
57
+
58
+ /**
59
+ * Product Mass Action - Update Status
60
+ *
61
+ * @param Varien_Event_Observer $observer
62
+ * @return Ometria_Core_Model_Observer_Product
63
+ */
64
+ public function catalogProductUpdateStatus(Varien_Event_Observer $observer) {
65
+ Varien_Profiler::start("Ometria::" . __METHOD__);
66
+
67
+ $productIds = Mage::app()->getFrontController()->getRequest()->getParam('product');
68
+ $this->updateProducts($productIds);
69
+
70
+ Varien_Profiler::stop("Ometria::" . __METHOD__);
71
+
72
+ return $this;
73
+ }
74
+
75
+
76
+ /**
77
+ * Pass product ids to Ometria API model
78
+ *
79
+ * @param $ids
80
+ * @return bool
81
+ *
82
+ */
83
+ protected function updateProducts($ids) {
84
+ $ometria_ping_helper = Mage::helper('ometria/ping');
85
+ $ometria_product_helper = Mage::helper('ometria/product');
86
+
87
+ $ids = $ometria_product_helper->convertProductIdsIfNeeded($ids);
88
+
89
+ $ometria_ping_helper->sendPing('product', $ids);
90
+ }
91
+ }
app/code/community/Ometria/Core/Test/Config/Base.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Ometria_Core_Test_Config_Base extends EcomDev_PHPUnit_Test_Case_Config {
3
+ public function testBlockAlias() {
4
+ $this->assertBlockAlias('ometria/test', 'Ometria_Core_Block_Test');
5
+ }
6
+
7
+ public function testModelAlias() {
8
+ $this->assertModelAlias('ometria/test', 'Ometria_Core_Model_Test');
9
+ }
10
+
11
+ public function testHelperAlias() {
12
+ $this->assertHelperAlias('ometria/test', 'Ometria_Core_Helper_Test');
13
+ }
14
+
15
+ public function testCodePool() {
16
+ $this->assertModuleCodePool('community');
17
+ }
18
+
19
+ public function testDepends() {
20
+ $this->assertModuleDepends('Mage_Catalog');
21
+ $this->assertModuleDepends('Mage_Customer');
22
+ $this->assertModuleDepends('Mage_Sales');
23
+
24
+ }
25
+
26
+ public function testLayoutFile() {
27
+ $this->assertLayoutFileDefined('frontend', 'ometria/core.xml');
28
+ $this->assertLayoutFileExistsInTheme('frontend', 'ometria/core.xml', 'default', 'base');
29
+ }
30
+ }
app/code/community/Ometria/Core/Test/Model/Observer/Order.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Ometria_Core_Test_Model_Observer_Order extends EcomDev_PHPUnit_Test_Case {
4
+
5
+ /**
6
+ * @test
7
+ */
8
+ public function testSalesOrderSaveAfter() {
9
+
10
+ $order = $this->getModelMock('sales/order', array('getId'));
11
+ $order->expects($this->any())
12
+ ->method('getId')
13
+ ->will($this->returnValue(1));
14
+
15
+ $mock = $this->getModelMock('ometria/api', array('notifyOrderUpdates'));
16
+ $mock->expects($this->once())
17
+ ->method('notifyOrderUpdates');
18
+
19
+ $this->replaceByMock('model', 'ometria/api', $mock);
20
+
21
+ Mage::dispatchEvent("sales_order_save_after", array('order' => $order));
22
+ }
23
+ }
app/code/community/Ometria/Core/Test/Model/Observer/Product.php ADDED
@@ -0,0 +1,42 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Ometria_Core_Test_Model_Observer_Product extends EcomDev_PHPUnit_Test_Case {
4
+
5
+ /**
6
+ * @test
7
+ */
8
+ public function testCatalogProductDeleteAfter() {
9
+
10
+ $product = $this->getModelMock('catalog/product', array('getId'));
11
+ $product->expects($this->any())
12
+ ->method('getId')
13
+ ->will($this->returnValue(1));
14
+
15
+ $mock = $this->getModelMock('ometria/api', array('notifyProductUpdates'));
16
+ $mock->expects($this->once())
17
+ ->method('notifyProductUpdates');
18
+
19
+ $this->replaceByMock('model', 'ometria/api', $mock);
20
+
21
+ Mage::dispatchEvent("catalog_product_delete_after", array('data_object' => $product, 'product' => $product));
22
+ }
23
+
24
+ /**
25
+ * @test
26
+ */
27
+ public function testCatalogProductSaveAfter() {
28
+
29
+ $product = $this->getModelMock('catalog/product', array('getId'));
30
+ $product->expects($this->any())
31
+ ->method('getId')
32
+ ->will($this->returnValue(1));
33
+
34
+ $mock = $this->getModelMock('ometria/api', array('notifyProductUpdates'));
35
+ $mock->expects($this->once())
36
+ ->method('notifyProductUpdates');
37
+
38
+ $this->replaceByMock('model', 'ometria/api', $mock);
39
+
40
+ Mage::dispatchEvent("catalog_product_save_after", array('data_object' => $product, 'product' => $product));
41
+ }
42
+ }
app/code/community/Ometria/Core/controllers/WizardController.php ADDED
@@ -0,0 +1,134 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Ometria_Core_WizardController extends Mage_Adminhtml_Controller_Action {
3
+
4
+ const OMETRIA_API_ROLE_NAME = 'Ometria';
5
+ const OMETRIA_API_USERNAME = 'ometria';
6
+ const OMETRIA_API_USER_FIRSTNAME = 'Ometria';
7
+ const OMETRIA_API_USER_LASTNAME = 'Ometria';
8
+ const OMETRIA_API_USER_EMAIL = 'ometria@ometria.com';
9
+ const OMETRIA_API_TEST_URL = 'https://console.ometria.com/setup/test-importer/magento';
10
+
11
+ public function indexAction() {
12
+ $this->loadLayout();
13
+ $this->renderLayout();
14
+ }
15
+
16
+ public function processAction() {
17
+ // We'll collect some parameters to pass to the success / fail page and place them in the $result array()
18
+ $result = array();
19
+
20
+ // Clear the session, incase there is something there already.
21
+ Mage::getSingleton('adminhtml/session')->unsetData('ometria_wizard_result');
22
+
23
+ $siteId = Mage::helper('ometria/config')->getAPIKey();
24
+ $apiKey = $this->getRequest()->getParam('api_key');
25
+
26
+ // Create the role.
27
+ $role = $this->_createRole($result);
28
+
29
+ // If the role was created successfully, create the user.
30
+ if ($role) {
31
+ $user = $this->_createUser($role, $apiKey, $result);
32
+ }
33
+
34
+ if ($role && $user) {
35
+ $this->_testConnection($siteId, $result);
36
+ }
37
+
38
+ Mage::getSingleton('adminhtml/session')->setData('ometria_wizard_result', $result);
39
+ $this->_redirect('*/*/finished');
40
+ }
41
+
42
+ public function finishedAction() {
43
+ $this->loadLayout();
44
+ $this->renderLayout();
45
+ }
46
+
47
+ protected function _createRole(&$result) {
48
+ // Only make the new role if we don't have one called 'Ometria'
49
+ $role = Mage::getModel('api/roles')->load(self::OMETRIA_API_ROLE_NAME, 'role_name');
50
+ if (!$role->getId()) {
51
+ try {
52
+ $resource = array('all');
53
+ $role = $role
54
+ ->setName(self::OMETRIA_API_ROLE_NAME)
55
+ ->setPid(0)
56
+ ->setRoleType('G')
57
+ ->save();
58
+
59
+ Mage::getModel("api/rules")
60
+ ->setRoleId($role->getId())
61
+ ->setResources($resource)
62
+ ->saveRel();
63
+
64
+ $result []= array('status' => 'success', 'message' => 'Successfully created WebServices Role.');
65
+ } catch (Exception $e) {
66
+ $role = false;
67
+ $result []= array('status' => 'error', 'message' => 'Failed to create WebServices Role. Reason: ' . $e->getMessage());
68
+ }
69
+ } else {
70
+ $result []= array('status' => 'warning', 'message' => 'Unable to create WebServices Role, one already exists. Proceeding.');
71
+ }
72
+ return $role;
73
+ }
74
+
75
+ protected function _createUser($role, $apiKey, &$result) {
76
+ // Make a user and attach it to the $role if one doesn't exist.
77
+ $user = Mage::getModel('api/user')->load(self::OMETRIA_API_USERNAME, 'username');
78
+ if (!$user->getId()) {
79
+ $user->setData(array(
80
+ 'username' => self::OMETRIA_API_USERNAME,
81
+ 'firstname' => self::OMETRIA_API_USER_FIRSTNAME,
82
+ 'lastname' => self::OMETRIA_API_USER_LASTNAME,
83
+ 'email' => self::OMETRIA_API_USER_EMAIL,
84
+ 'api_key' => $apiKey,
85
+ 'api_key_confirmation' => $apiKey,
86
+ 'is_active' => 1,
87
+ 'roles' => array($role->getId())
88
+ ));
89
+
90
+ try {
91
+ $user->save();
92
+ $user->setRoleIds(array($role->getId()))
93
+ ->setRoleUserId($user->getUserId())
94
+ ->saveRelations();
95
+
96
+ $result []= array('status' => 'success', 'message' => 'Successfully created WebServices User.');
97
+ } catch (Exception $e) {
98
+ $user = false;
99
+ $result []= array('status' => 'error', 'message' => 'Failed to create WebServices User. Reason: ' . $e->getMessage());
100
+ }
101
+
102
+ } else {
103
+ $result []= array('status' => 'warning', 'message' => 'Unable to create WebServices User, one already exists. Proceeding.');
104
+ }
105
+
106
+ return $user;
107
+ }
108
+
109
+ protected function _testConnection($siteId, &$result) {
110
+ $fields = array(
111
+ 'acc' => urlencode($siteId)
112
+ );
113
+
114
+ $fieldsString = http_build_query($fields);
115
+
116
+ // Here's how I think the implementation will look - Will have to wait until it's been implemented however before
117
+ // we can be sure.
118
+ $ch = curl_init();
119
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, true);
120
+ curl_setopt($ch, CURLOPT_URL, self::OMETRIA_API_TEST_URL);
121
+ curl_setopt($ch, CURLOPT_POST, 2);
122
+ curl_setopt($ch, CURLOPT_POSTFIELDS, $fieldsString);
123
+
124
+ $rawResponse = curl_exec($ch);
125
+
126
+ $response = Mage::helper('core')->jsonDecode($rawResponse);
127
+
128
+ if ($response['status'] == 'OK') {
129
+ $result []= array('status' => 'success', 'message' => 'Successfully tested connection with Ometria.');
130
+ } else {
131
+ $result []= array('status' => 'error', 'message' => 'Failed when testing connection with Ometria. Reason: ' . $response['error']);
132
+ }
133
+ }
134
+ }
app/code/community/Ometria/Core/etc/config.xml ADDED
@@ -0,0 +1,243 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Ometria_Core>
5
+ <version>1.0.0</version>
6
+ </Ometria_Core>
7
+ </modules>
8
+
9
+ <global>
10
+ <blocks>
11
+ <ometria>
12
+ <class>Ometria_Core_Block</class>
13
+ </ometria>
14
+ </blocks>
15
+ <models>
16
+ <ometria>
17
+ <class>Ometria_Core_Model</class>
18
+ </ometria>
19
+ </models>
20
+ <helpers>
21
+ <ometria>
22
+ <class>Ometria_Core_Helper</class>
23
+ </ometria>
24
+ </helpers>
25
+ <events>
26
+ <catalog_product_delete_after>
27
+ <observers>
28
+ <ometria_catalog_product_delete>
29
+ <type>singleton</type>
30
+ <class>ometria/observer_product</class>
31
+ <method>catalogProductDeleteAfter</method>
32
+ </ometria_catalog_product_delete>
33
+ </observers>
34
+ </catalog_product_delete_after>
35
+ <catalog_product_save_after>
36
+ <observers>
37
+ <ometria_catalog_product_save>
38
+ <type>singleton</type>
39
+ <class>ometria/observer_product</class>
40
+ <method>catalogProductSaveAfter</method>
41
+ </ometria_catalog_product_save>
42
+ </observers>
43
+ </catalog_product_save_after>
44
+ <controller_action_predispatch_adminhtml_catalog_product_action_attribute_save>
45
+ <observers>
46
+ <ometria_catalog_product_mass_action_update_attributes>
47
+ <type>singleton</type>
48
+ <class>ometria/observer_product</class>
49
+ <method>catalogProductUpdateAttributes</method>
50
+ </ometria_catalog_product_mass_action_update_attributes>
51
+ </observers>
52
+ </controller_action_predispatch_adminhtml_catalog_product_action_attribute_save>
53
+ <controller_action_postdispatch_adminhtml_catalog_product_massStatus>
54
+ <observers>
55
+ <ometria_catalog_product_mass_action_update_status>
56
+ <type>singleton</type>
57
+ <class>ometria/observer_product</class>
58
+ <method>catalogProductUpdateStatus</method>
59
+ </ometria_catalog_product_mass_action_update_status>
60
+ </observers>
61
+ </controller_action_postdispatch_adminhtml_catalog_product_massStatus>
62
+ <sales_order_save_after>
63
+ <observers>
64
+ <ometria_sales_order_save_after>
65
+ <type>singleton</type>
66
+ <class>ometria/observer_order</class>
67
+ <method>salesOrderSaveAfter</method>
68
+ </ometria_sales_order_save_after>
69
+ </observers>
70
+ </sales_order_save_after>
71
+ <customer_save_after>
72
+ <observers>
73
+ <ometria_customer_save_after>
74
+ <type>singleton</type>
75
+ <class>ometria/observer_customer</class>
76
+ <method>customerSaveAfter</method>
77
+ </ometria_customer_save_after>
78
+ </observers>
79
+ </customer_save_after>
80
+ <checkout_cart_add_product_complete>
81
+ <observers>
82
+ <checkout_cart_update_item_complete>
83
+ <type>singleton</type>
84
+ <class>ometria/observer_cart</class>
85
+ <method>basketUpdated</method>
86
+ </checkout_cart_update_item_complete>
87
+ </observers>
88
+ </checkout_cart_add_product_complete>
89
+ <sales_quote_remove_item>
90
+ <observers>
91
+ <ometria_sales_quote_remove_item>
92
+ <type>singleton</type>
93
+ <class>ometria/observer_cart</class>
94
+ <method>basketUpdated</method>
95
+ </ometria_sales_quote_remove_item>
96
+ </observers>
97
+ </sales_quote_remove_item>
98
+
99
+ <customer_login>
100
+ <observers>
101
+ <ometria_customer_login>
102
+ <type>singleton</type>
103
+ <class>ometria/observer_customer</class>
104
+ <method>loggedIn</method>
105
+ </ometria_customer_login>
106
+ </observers>
107
+ </customer_login>
108
+
109
+ <customer_logout>
110
+ <observers>
111
+ <ometria_customer_logout>
112
+ <type>singleton</type>
113
+ <class>ometria/observer_customer</class>
114
+ <method>loggedOut</method>
115
+ </ometria_customer_logout>
116
+ </observers>
117
+ </customer_logout>
118
+
119
+ <customer_register_success>
120
+ <observers>
121
+ <ometria_customer_register_success>
122
+ <type>singleton</type>
123
+ <class>ometria/observer_customer</class>
124
+ <method>registered</method>
125
+ </ometria_customer_register_success>
126
+ </observers>
127
+ </customer_register_success>
128
+
129
+ <sales_order_place_after>
130
+ <observers>
131
+ <ometria_sales_order_place_after>
132
+ <type>singleton</type>
133
+ <class>ometria/observer_cart</class>
134
+ <method>orderPlaced</method>
135
+ </ometria_sales_order_place_after>
136
+ </observers>
137
+ </sales_order_place_after>
138
+
139
+ <newsletter_subscriber_save_before>
140
+ <observers>
141
+ <ometria_newsletter_subscriber_save_before>
142
+ <class>ometria/observer_newsletter</class>
143
+ <method>handleSubscriberUpdate</method>
144
+ </ometria_newsletter_subscriber_save_before>
145
+ </observers>
146
+ </newsletter_subscriber_save_before>
147
+ <newsletter_subscriber_delete_after>
148
+ <observers>
149
+ <ometria_newsletter_subscriber_delete_after>
150
+ <class>ometria/observer_newsletter</class>
151
+ <method>handleSubscriberDeletion</method>
152
+ </ometria_newsletter_subscriber_delete_after>
153
+ </observers>
154
+ </newsletter_subscriber_delete_after>
155
+
156
+ </events>
157
+ </global>
158
+
159
+ <frontend>
160
+ <layout>
161
+ <updates>
162
+ <ometria>
163
+ <file>ometria/core.xml</file>
164
+ </ometria>
165
+ </updates>
166
+ </layout>
167
+ <routers>
168
+ <ometria>
169
+ <use>standard</use>
170
+ <args>
171
+ <module>Ometria_Core</module>
172
+ <frontName>ometria</frontName>
173
+ </args>
174
+ </ometria>
175
+ </routers>
176
+ </frontend>
177
+
178
+ <admin>
179
+ <routers>
180
+ <adminhtml>
181
+ <args>
182
+ <modules>
183
+ <ometria before="Mage_Adminhtml">Ometria_Core</ometria>
184
+ </modules>
185
+ </args>
186
+ </adminhtml>
187
+ </routers>
188
+ </admin>
189
+
190
+ <adminhtml>
191
+ <layout>
192
+ <updates>
193
+ <ometria>
194
+ <file>ometria/core.xml</file>
195
+ </ometria>
196
+ </updates>
197
+ </layout>
198
+ <acl>
199
+ <resources>
200
+ <admin>
201
+ <children>
202
+ <system>
203
+ <children>
204
+ <config>
205
+ <children>
206
+ <ometria>
207
+ <title>Ometria Settings</title>
208
+ </ometria>
209
+ </children>
210
+ </config>
211
+ </children>
212
+ </system>
213
+ </children>
214
+ </admin>
215
+ </resources>
216
+ </acl>
217
+ </adminhtml>
218
+
219
+ <default>
220
+ <ometria>
221
+ <general>
222
+ <enabled>0</enabled>
223
+ <apikey></apikey>
224
+ </general>
225
+ <advanced>
226
+ <univar>1</univar>
227
+ <ping>1</ping>
228
+ <scriptload>0</scriptload>
229
+ <debug>0</debug>
230
+ <productmode>id</productmode>
231
+ </advanced>
232
+ </ometria>
233
+ </default>
234
+
235
+
236
+ <phpunit>
237
+ <suite>
238
+ <modules>
239
+ <Ometria_Core />
240
+ </modules>
241
+ </suite>
242
+ </phpunit>
243
+ </config>
app/code/community/Ometria/Core/etc/system.xml ADDED
@@ -0,0 +1,130 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <config>
3
+ <tabs>
4
+ <ometria translate="label" module="ometria">
5
+ <label>Ometria</label>
6
+ <sort_order>450</sort_order>
7
+ </ometria>
8
+ </tabs>
9
+ <sections>
10
+ <ometria translate="label" module="ometria">
11
+ <label>Analytics Settings</label>
12
+ <tab>ometria</tab>
13
+ <frontend_type>text</frontend_type>
14
+ <sort_order>1</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
+ <general translate="label" module="ometria">
20
+ <label>General</label>
21
+ <frontend_type>text</frontend_type>
22
+ <sort_order>10</sort_order>
23
+ <show_in_default>1</show_in_default>
24
+ <show_in_website>1</show_in_website>
25
+ <show_in_store>1</show_in_store>
26
+ <fields>
27
+ <enabled translate="label" module="ometria">
28
+ <label>Enabled</label>
29
+ <frontend_type>select</frontend_type>
30
+ <source_model>adminhtml/system_config_source_yesno</source_model>
31
+ <sort_order>10</sort_order>
32
+ <show_in_default>1</show_in_default>
33
+ <show_in_website>0</show_in_website>
34
+ <show_in_store>0</show_in_store>
35
+ </enabled>
36
+ <apikey translate="label" module="ometria">
37
+ <label>Ometria Site Identifier</label>
38
+ <frontend_type>text</frontend_type>
39
+ <sort_order>20</sort_order>
40
+ <show_in_default>1</show_in_default>
41
+ <show_in_website>0</show_in_website>
42
+ <show_in_store>0</show_in_store>
43
+ <comment>
44
+ <![CDATA[Sign up for an account at <a href="http://www.ometria.com/" target="_blank">Ometria.com</a>]]>
45
+ </comment>
46
+ </apikey>
47
+
48
+             <start_wizard translate="label">
49
+ <label></label>
50
+ <button_label>Start Setup Wizard</button_label>
51
+ <button_url><![CDATA[ometria/wizard/index]]></button_url>
52
+ <frontend_model>ometria/adminhtml_system_config_startwizard</frontend_model>
53
+ <sort_order>30</sort_order>
54
+ <show_in_default>1</show_in_default>
55
+ <show_in_website>0</show_in_website>
56
+ <show_in_store>0</show_in_store>
57
+ <comment><![CDATA[Click the above to easily setup your connection details between Magento and Ometria.]]></comment>
58
+             </start_wizard>
59
+ </fields>
60
+ </general>
61
+ <advanced translate="label" module="ometria">
62
+ <label>Advanced</label>
63
+ <frontend_type>text</frontend_type>
64
+ <sort_order>30</sort_order>
65
+ <show_in_default>1</show_in_default>
66
+ <show_in_website>0</show_in_website>
67
+ <show_in_store>0</show_in_store>
68
+ <fields>
69
+ <univar translate="label" module="ometria">
70
+ <label>Include Data Layer</label>
71
+ <frontend_type>select</frontend_type>
72
+ <source_model>adminhtml/system_config_source_yesno</source_model>
73
+ <sort_order>10</sort_order>
74
+ <show_in_default>1</show_in_default>
75
+ <show_in_website>0</show_in_website>
76
+ <show_in_store>0</show_in_store>
77
+ </univar>
78
+ <ping translate="label" module="ometria">
79
+ <label>Ping Ometria on record update</label>
80
+ <frontend_type>select</frontend_type>
81
+ <source_model>adminhtml/system_config_source_yesno</source_model>
82
+ <sort_order>11</sort_order>
83
+ <show_in_default>1</show_in_default>
84
+ <show_in_website>0</show_in_website>
85
+ <show_in_store>0</show_in_store>
86
+ </ping>
87
+ <scriptload translate="label" module="ometria">
88
+ <label>Defer script load</label>
89
+ <frontend_type>select</frontend_type>
90
+ <source_model>adminhtml/system_config_source_yesno</source_model>
91
+ <sort_order>12</sort_order>
92
+ <show_in_default>1</show_in_default>
93
+ <show_in_website>0</show_in_website>
94
+ <show_in_store>0</show_in_store>
95
+ </scriptload>
96
+ <debug translate="label" module="ometria">
97
+ <label>Debug Mode</label>
98
+ <frontend_type>select</frontend_type>
99
+ <source_model>adminhtml/system_config_source_yesno</source_model>
100
+ <sort_order>13</sort_order>
101
+ <show_in_default>1</show_in_default>
102
+ <show_in_website>0</show_in_website>
103
+ <show_in_store>0</show_in_store>
104
+ </debug>
105
+ <productmode translate="label" module="ometria">
106
+ <label>Product Identifier Mode</label>
107
+ <frontend_type>select</frontend_type>
108
+ <source_model>ometria/config_source_productmode</source_model>
109
+ <sort_order>14</sort_order>
110
+ <show_in_default>1</show_in_default>
111
+ <show_in_website>0</show_in_website>
112
+ <show_in_store>0</show_in_store>
113
+ </productmode>
114
+ <unique_id translate="label" module="ometria">
115
+ <label>Unique Magento ID</label>
116
+ <frontend_type>text</frontend_type>
117
+ <sort_order>20</sort_order>
118
+ <show_in_default>1</show_in_default>
119
+ <show_in_website>0</show_in_website>
120
+ <show_in_store>0</show_in_store>
121
+ <comment>
122
+ <![CDATA[This will be auto-generated by the extension. Do not change.]]>
123
+ </comment>
124
+ </unique_id>
125
+ </fields>
126
+ </advanced>
127
+ </groups>
128
+ </ometria>
129
+ </sections>
130
+ </config>
app/design/adminhtml/default/default/layout/ometria/core.xml ADDED
@@ -0,0 +1,16 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <layout>
3
+ <ometria_wizard_index>
4
+ <update handle="popup"/>
5
+ <reference name="content">
6
+ <block name="ometria.core.wizard.start" type="ometria/adminhtml_wizard_start"></block>
7
+ </reference>
8
+ </ometria_wizard_index>
9
+
10
+ <ometria_wizard_finished>
11
+ <update handle="popup"/>
12
+ <reference name="content">
13
+ <block name="ometria.core.wizard.start" type="ometria/adminhtml_wizard_finished" template="ometria/wizard/finished.phtml"></block>
14
+ </reference>
15
+ </ometria_wizard_finished>
16
+ </layout>
app/design/adminhtml/default/default/template/ometria/system/config/start_wizard.phtml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <button class="scalable" type="button" id="ometria-start-wizard">
2
+ <span><?php echo $this->getButtonLabel() ?></span>
3
+ </button>
4
+
5
+ <script type="text/javascript">
6
+ $('ometria-start-wizard').observe('click', function(e) {
7
+ <?php if ($this->canOpenWizard()): ?>
8
+ var url = "<?php echo $this->getButtonUrl(); ?>";
9
+ popWin(url, 'ometria_wizard','toolbar=no, location=no, directories=no, status=no, menubar=no, scrollbars=yes, resizable=no, left=200, top=100, width=1000, height=900');
10
+ <?php else: ?>
11
+ alert('Unable to open wizard. Please make sure you have a valid Ometria Site Identifier inserted above and have clicked "Save Config".')
12
+ <?php endif; ?>
13
+ });
14
+ </script>
app/design/adminhtml/default/default/template/ometria/wizard/finished.phtml ADDED
@@ -0,0 +1,19 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <div class="content-header">
2
+ <h3 class="icon-head head-adminhtml-wizard">Ometria Setup Wizard</h3>
3
+ <p class="form-buttons"><button title="<?php echo $this->__('Finished') ?>" type="button" class="scalable save" onclick="window.close()" style=""><span><span><span><?php echo $this->__('Finished') ?></span></span></span></button></p>
4
+ </div>
5
+ <?php /** @var $this Ometria_Core_Block_Adminhtml_Wizard_Finished */ ?>
6
+ <?php $_results = $this->getResults(); ?>
7
+ <?php $_wasSuccessful = $this->getWasSuccessful(); ?>
8
+
9
+ <?php if ($_wasSuccessful): ?>
10
+ <h1>Success!</h1>
11
+ <?php else: ?>
12
+ <h1>Failure</h1>
13
+ <?php endif; ?>
14
+ <h4>Details</h4>
15
+ <ul>
16
+ <?php foreach ($_results as $_result): ?>
17
+ <li><strong><?php echo strtoupper($_result['status']) ?></strong> <?php echo $_result['message'] ?></li>
18
+ <?php endforeach; ?>
19
+ </ul>
app/design/frontend/base/default/layout/ometria/core.xml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <layout>
3
+ <default>
4
+ <reference name="head">
5
+ <block type="ometria/head" name="ometria.head" as="ometria.head" template="ometria/head.phtml" ifconfig="ometria/general/enabled"/>
6
+ </reference>
7
+ </default>
8
+
9
+ <checkout_onepage_index>
10
+ <reference name="head">
11
+ <action method="addJs"><script>ometria/checkout.js</script></action>
12
+ </reference>
13
+ </checkout_onepage_index>
14
+ </layout>
app/design/frontend/base/default/template/ometria/head.phtml ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /** @var Ometria_Core_Helper_Config $_helper */
3
+ $_helper = Mage::helper('ometria/config');
4
+ /** @var Ometria_Core_Block_Head $this */
5
+ ?>
6
+ <?php if ($_helper->isConfigured()) :?>
7
+ <script type="text/javascript">
8
+ <?php if ($_helper->isUnivarEnabled()) :?>
9
+
10
+ window.ometria = window.ometria || {};
11
+ window.ometria.raw_data = <?php echo json_encode($this->getDataLayer()) ?>;
12
+
13
+ <?php endif; ?>
14
+ <?php if ($_helper->isScriptDeferred()) :?>
15
+ document.observe("dom:loaded", function(){
16
+ var url=window.location.protocol+"//cdn.ometria.com/tags/<?php echo $_helper->getAPIKey() ?>.js";
17
+ var sc=document.createElement('script');sc.src=url;sc.setAttribute('async','true');
18
+ document.getElementsByTagName("head")[0].appendChild(sc);
19
+ });
20
+ <?php else: ?>
21
+ (function(){
22
+ var url=window.location.protocol+"//cdn.ometria.com/tags/<?php echo $_helper->getAPIKey() ?>.js";
23
+ setTimeout(function(){var sc=document.createElement('script');sc.src=url;sc.setAttribute('async','true');
24
+ document.getElementsByTagName("head")[0].appendChild(sc);},50);
25
+ })();
26
+ <?php endif; ?>
27
+ </script>
28
+ <?php endif; ?>
app/etc/modules/Ometria_AbandonedCarts.xml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Ometria_AbandonedCarts>
5
+ <active>true</active>
6
+ <codePool>community</codePool>
7
+ </Ometria_AbandonedCarts>
8
+ </modules>
9
+ </config>
app/etc/modules/Ometria_Api.xml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Ometria_Api>
5
+ <active>true</active>
6
+ <codePool>community</codePool>
7
+ </Ometria_Api>
8
+ </modules>
9
+ </config>
app/etc/modules/Ometria_Core.xml ADDED
@@ -0,0 +1,14 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Ometria_Core>
5
+ <active>true</active>
6
+ <codePool>community</codePool>
7
+ <depends>
8
+ <Mage_Catalog />
9
+ <Mage_Customer />
10
+ <Mage_Sales />
11
+ </depends>
12
+ </Ometria_Core>
13
+ </modules>
14
+ </config>
js/ometria/checkout.js ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ document.observe("dom:loaded", function () {
2
+ // We want to know when the checkout step changes
3
+ // Overwrite the original gotoSection function in opcheckout.js and update our variable
4
+ if (typeof Checkout != 'undefined'){
5
+ var originalCheckout = Checkout.prototype.gotoSection
6
+ Checkout.prototype.gotoSection = function () {
7
+ try{
8
+ if (window.ometria) ometria.trackCheckout(arguments[0]);
9
+ } catch(e){}
10
+ originalCheckout.apply(this, arguments);
11
+ };
12
+ }
13
+ });
package.xml ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>Ometria_Magento_Extension</name>
4
+ <version>1.0.0</version>
5
+ <stability>stable</stability>
6
+ <license uri="http://opensource.org/licenses/osl-3.0.php">Open Source License (OSL)</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>Radically simple ecommerce analytics&#xD;
10
+ </summary>
11
+ <description>The official Ometria Magento extension.&#xD;
12
+ &#xD;
13
+ Helping you win at E-commerce&#xD;
14
+ &#xD;
15
+ Tailored to the needs of the online retailer, the Ometria dashboards have been designed by e-commerce specialists from the ground up. Product and customer centric, we hook up website tracking with back end data for 360 degree visibility, and allow retailers to add targets, margins and costs. No unnecessary 'deep dive' analysis, no more bootstrapped report building, no more data overload. Download reports and graphs instantly for presentations or email to relevant stakeholders.&#xD;
16
+ &#xD;
17
+ We'll not only help e-commerce managers look good, we'll help them feel in control, with the data they need, all in one place.&#xD;
18
+ &#xD;
19
+ Enough Data already. Tell me what to do!&#xD;
20
+ &#xD;
21
+ We don't just pull the right data together in one place, we also create insights. Our team of data scientists have created a set of algorithms to spot weaknesses, under-performance and opportunities, so every time a retailer logs into their dashboards we present a short list of top revenue wins.&#xD;
22
+ &#xD;
23
+ Whether it's with our multi-dimension funnel analysis which flags up specific channels that may be under-performing, or our customer dashboard which spots channels that deliver customers with the best CLV, our 'actionable insights' come ready to go.</description>
24
+ <notes>Release of new extension.</notes>
25
+ <authors><author><name>Alastair James</name><user>aljames1981</user><email>al.james@gmail.com</email></author></authors>
26
+ <date>2015-05-19</date>
27
+ <time>12:47:49</time>
28
+ <contents><target name="magecommunity"><dir name="Ometria"><dir name="AbandonedCarts"><dir name="Helper"><file name="Config.php" hash="4ea2f9de193a510a1438a1911f6e9a8d"/><file name="Data.php" hash="1348c35f00b49b2b30034f0d9a819ae8"/></dir><dir name="controllers"><file name="CartlinkController.php" hash="d1cd8ca0cd5d40f1fbfcd53408d9ee05"/></dir><dir name="etc"><file name="config.xml" hash="c750ffe30696d51f7f7c0a9f5544093a"/><file name="system.xml" hash="11db59f5c2f864525e4c1cdd06283ac1"/></dir></dir><dir name="Api"><dir name="Helper"><file name="Data.php" hash="8a19a3bf39de93fab7d2e1333c3c0806"/></dir><dir name="Model"><file name="Api.php" hash="3cc250c379ef7a1e1eaf9baa927f4160"/><file name="Api2.php" hash="78cdf93358b28283e3aeb9e6760add24"/></dir><dir name="etc"><file name="api.xml" hash="aa0983d987856273a6f1482dea45984e"/><file name="config.xml" hash="33cf63ddeefdf62bd9d8c7a0e0c44040"/></dir></dir><dir name="Core"><dir name="Block"><dir name="Adminhtml"><dir name="System"><dir name="Config"><file name="Startwizard.php" hash="48c0cc3736f8a7fbd871d92d1aed9a81"/></dir></dir><dir name="Wizard"><file name="Finished.php" hash="3325319ce22b23c3661a15b7ab6cbb83"/><dir name="Start"><file name="Form.php" hash="e5d6f86a9718da044104245b46230674"/></dir><file name="Start.php" hash="befc4575e361b7a9916f929e2fc58c45"/></dir></dir><file name="Head.php" hash="1b00336f0bd24d46c56b6ced4c0515a6"/></dir><dir name="Helper"><file name="Config.php" hash="1a9c4653ff34de123dbab505687265a7"/><file name="Cookiechannel.php" hash="309ff2e6d5cb721d1bbc04f18156f35e"/><file name="Data.php" hash="26c20107047db9e3911118efbf083135"/><file name="Ping.php" hash="0eba99b10b71c666cecd95ddaef69df3"/><file name="Product.php" hash="60e3b6bcb43884af7e4a4ed48c3e3411"/><file name="Session.php" hash="798245d7d20c523b3c386c8bf25979d2"/></dir><dir name="Model"><dir name="Config"><dir name="Source"><file name="Productmode.php" hash="3b37b999e8d49fc23af6229bcae86bb9"/></dir></dir><dir name="Observer"><file name="Cart.php" hash="5fb4a3a7d8cf7e162fdfda0b183f8426"/><file name="Customer.php" hash="3e36530a774e2f9af9adbbb581f52380"/><file name="Newsletter.php" hash="a262a42d8a6d4d07ad475cca5fdf6c76"/><file name="Order.php" hash="fdcbad1124492f520b9edb72e0d88463"/><file name="Product.php" hash="e988fbf3dcf5ef6ea898b2668f2c4f55"/></dir><file name=".DS_Store" hash="194577a7e20bdcc7afbb718f502c134c"/></dir><dir name="Test"><dir name="Config"><file name="Base.php" hash="997583679f0981fbd2f0560cf40855d1"/></dir><dir name="Model"><dir name="Observer"><file name="Order.php" hash="d4655e7789a87b3fe8093355e862bfc4"/><file name="Product.php" hash="b9d3920d0d489c39245f747f15187085"/></dir></dir></dir><dir name="controllers"><file name="WizardController.php" hash="558e829a66e2ad9a7b7c1ad9d7d4a530"/></dir><dir name="etc"><file name="config.xml" hash="74856c866f046115fcf56c5c076d5e8b"/><file name="system.xml" hash="5e4286f048a66333776441737bf5b54b"/></dir><file name=".DS_Store" hash="d8b910e9c4677fce43c430c2bb123061"/></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><dir name="ometria"><file name="core.xml" hash="d8d696fec5b40262b9307a0bb89bcede"/></dir></dir><dir name="template"><dir name="ometria"><file name="head.phtml" hash="1ef17e826431c85e14532d7660b38ee8"/></dir></dir></dir></dir></dir><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><dir name="ometria"><file name="core.xml" hash="4fd702d8159187002eebb40c9b3ebe1b"/></dir></dir><dir name="template"><dir name="ometria"><dir name="system"><dir name="config"><file name="start_wizard.phtml" hash="d4a4e6d6ab16048f1e436793cb24a668"/></dir></dir><dir name="wizard"><file name="finished.phtml" hash="e475e0a7fb28b2b054a1b26cae5fd9b8"/></dir></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Ometria_Core.xml" hash="f8ec0ef46b669bf0070d9064300fc0fd"/><file name="Ometria_Api.xml" hash="e9309a378992b51f710a9fca17a3055e"/><file name="Ometria_AbandonedCarts.xml" hash="a69a03804840e784362410c2596c0a08"/></dir></target><target name="mageweb"><dir name="js"><dir name="ometria"><file name="checkout.js" hash="78b5fed53276d65a42c5cad4bf92a35f"/></dir></dir></target></contents>
29
+ <compatible/>
30
+ <dependencies><required><php><min>5.1.0</min><max>6.0.0</max></php></required></dependencies>
31
+ </package>