LoyaltyLion - Version 1.1.2

Version Notes

This release improves the configuration process.

Download this release

Release Info

Developer Dave Clark
Extension LoyaltyLion
Version 1.1.2
Comparing to
See all releases


Version 1.1.2

app/code/local/LoyaltyLion/Core/Block/Sdk.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class LoyaltyLion_Core_Block_Sdk extends Mage_Core_Block_Template {
4
+
5
+ public function isEnabled() {
6
+ $token = $this->getToken();
7
+ $secret = $this->getSecret();
8
+
9
+ if (empty($token) || empty($secret)) return false;
10
+ return true;
11
+ }
12
+
13
+ public function getToken() {
14
+ return Mage::getStoreConfig('loyaltylion/configuration/loyaltylion_token');
15
+ }
16
+
17
+ public function getSecret() {
18
+ return Mage::getStoreConfig('loyaltylion/configuration/loyaltylion_secret');
19
+ }
20
+
21
+ public function getSDKUrl() {
22
+ return isset($_SERVER['LOYALTYLION_SDK_URL']) ? $_SERVER['LOYALTYLION_SDK_URL'] : 'dg1f2pfrgjxdq.cloudfront.net/libs/ll.sdk-1.1.js';
23
+ }
24
+
25
+ public function getPlatformHost() {
26
+ return isset($_SERVER['LOYALTYLION_PLATFORM_HOST']) ? $_SERVER['LOYALTYLION_PLATFORM_HOST'] : 'platform.loyaltylion.com';
27
+ }
28
+ }
app/code/local/LoyaltyLion/Core/Helper/Data.php ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ <?php
2
+
3
+ class LoyaltyLion_Core_Helper_Data extends Mage_Core_Helper_Abstract {
4
+
5
+ }
app/code/local/LoyaltyLion/Core/Model/Observer.php ADDED
@@ -0,0 +1,314 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class LoyaltyLion_Core_Model_Observer {
4
+
5
+ private $client;
6
+ private $session;
7
+
8
+ public function __construct() {
9
+ $this->token = Mage::getStoreConfig('loyaltylion/configuration/loyaltylion_token');
10
+ $this->secret = Mage::getStoreConfig('loyaltylion/configuration/loyaltylion_secret');
11
+
12
+ if (!$this->isEnabled()) return;
13
+
14
+ require( Mage::getModuleDir('', 'LoyaltyLion_Core') . DS . 'lib' . DS . 'loyaltylion-client' . DS . 'main.php' );
15
+
16
+ $options = array();
17
+
18
+ if (isset($_SERVER['LOYALTYLION_API_BASE'])) {
19
+ $options['base_uri'] = $_SERVER['LOYALTYLION_API_BASE'];
20
+ }
21
+
22
+ $this->client = new LoyaltyLion_Client($this->token, $this->secret, $options);
23
+
24
+ $this->session = Mage::getSingleton('core/session');
25
+ }
26
+
27
+ private function isEnabled() {
28
+ if (empty($this->token) || empty($this->secret)) return false;
29
+ return true;
30
+ }
31
+
32
+ private function getItems($orderId) {
33
+ $collection = Mage::getResourceModel('sales/order_item_collection');
34
+ $collection->addAttributeToFilter('order_id', array($orderId));
35
+ $items = array();
36
+ foreach ($collection->getItems() as $item) {
37
+ $items[] = $item->toArray();
38
+ }
39
+ return $items;
40
+ }
41
+
42
+ private function getAddresses($orderId) {
43
+ $addresses = array();
44
+ $collection = Mage::getResourceModel('sales/order_address_collection');
45
+ $collection->addAttributeToFilter('parent_id', array($orderId));
46
+ foreach ($collection->getItems() as $item) {
47
+ $addresses[] = $item->toArray();
48
+ }
49
+ return $addresses;
50
+ }
51
+
52
+ private function getComments($orderId) {
53
+ $comments = array();
54
+ $collection = Mage::getResourceModel('sales/order_status_history_collection');
55
+ $collection->setOrderFilter(array($orderId));
56
+ foreach ($collection->getItems() as $item) {
57
+ $comments[] = $item->toArray();
58
+ }
59
+ return $comments;
60
+
61
+ }
62
+
63
+ public function handleOrderCreate(Varien_Event_Observer $observer) {
64
+ if (!$this->isEnabled()) return;
65
+
66
+ $order = $observer->getEvent()->getOrder();
67
+
68
+ $data = array(
69
+ 'merchant_id' => $order->getId(),
70
+ 'customer_id' => $order->getCustomerId(),
71
+ 'customer_email' => $order->getCustomerEmail(),
72
+ 'total' => (string) $order->getBaseGrandTotal(),
73
+ 'total_shipping' => (string) $order->getBaseShippingAmount(),
74
+ 'number' => (string) $order->getIncrementId(),
75
+ 'guest' => (bool) $order->getCustomerIsGuest(),
76
+ 'ip_address' => Mage::helper('core/http')->getRemoteAddr(),
77
+ 'user_agent' => $_SERVER['HTTP_USER_AGENT'],
78
+ '$magento_payload' => $order->toArray()
79
+ );
80
+
81
+ $data['$magento_payload']['order_items'] = $this->getItems($order->getId());
82
+ $data['$magento_payload']['order_comments'] = $this->getComments($order->getId());
83
+ $data['$magento_payload']['addresses'] = $this->getAddresses($order->getId());
84
+ $data['$magento_version'] = Mage::getVersion();
85
+ $data['$magento_platform'] = Mage::getEdition();
86
+ $data['$magento_module_version'] = (string) Mage::getConfig()->getModuleConfig("LoyaltyLion_Core")->version;
87
+
88
+ if ($order->getBaseTotalDue() == $order->getBaseGrandTotal()) {
89
+ $data['payment_status'] = 'not_paid';
90
+ } else if ($order->getBaseTotalDue() == 0) {
91
+ $data['payment_status'] = 'paid';
92
+ } else {
93
+ $data['payment_status'] = 'partially_paid';
94
+ $data['total_paid'] = $order->getBaseTotalPaid();
95
+ }
96
+
97
+ if ($order->getCouponCode()) {
98
+ $data['discount_codes'] = array(
99
+ array(
100
+ 'code' => $order->getCouponCode(),
101
+ 'amount' => abs($order->getDiscountAmount()),
102
+ ),
103
+ );
104
+ }
105
+
106
+ if ($this->session->getLoyaltyLionReferralId())
107
+ $data['referral_id'] = $this->session->getLoyaltyLionReferralId();
108
+
109
+ $tracking_id = $this->getTrackingIdFromSession();
110
+
111
+ if ($tracking_id)
112
+ $data['tracking_id'] = $tracking_id;
113
+
114
+ $response = $this->client->orders->create($data);
115
+
116
+ if ($response->success) {
117
+ Mage::log('[LoyaltyLion] Tracked order OK');
118
+ } else {
119
+ Mage::log('[LoyaltyLion] Failed to track order - status: ' . $response->status . ', error: ' . $response->error,
120
+ Zend_Log::ERR);
121
+ }
122
+ }
123
+
124
+ public function handleOrderUpdate(Varien_Event_Observer $observer) {
125
+ if (!$this->isEnabled()) return;
126
+
127
+ $this->sendOrderUpdate($observer->getEvent()->getOrder());
128
+ }
129
+
130
+ public function handleCustomerRegistration(Varien_Event_Observer $observer) {
131
+ if (!$this->isEnabled()) return;
132
+
133
+ $customer = $observer->getEvent()->getCustomer();
134
+
135
+ $this->trackSignup($customer);
136
+ }
137
+
138
+ public function handleCustomerRegistrationOnepage(Varien_Event_Observer $observer) {
139
+ if (!$this->isEnabled()) return;
140
+
141
+ $customer = $observer->getEvent()->getSource();
142
+
143
+ // this event is fired at multiple times during checkout before the customer has actually been saved,
144
+ // so we'll ignore most of those events
145
+ if (!$customer->getId()) return;
146
+
147
+ // this event is also fired all over the place, even after the customer has been created. alas, this is
148
+ // the only reliable way to find out if a new account has been created during checkout, so...
149
+ //
150
+ // we'll check the created_at time of the customer. if it's more than a minute in the past we'll assume
151
+ // this is not a new customer. in theory, this event should never fire more than a few seconds after a
152
+ // NEW account has been created, so this check ought to do what we want...
153
+
154
+ if ($customer->getCreatedAtTimestamp() < (time() - 60)) return;
155
+
156
+ $this->trackSignup($customer);
157
+ }
158
+
159
+ /**
160
+ * If a referral id is present (?ll_ref_id=xyz), save it to the session so it can be sent off with
161
+ * tracked event calls later
162
+ *
163
+ * This will also check for an `ll_eid` parameter (a tracking id) and save that, if it exists
164
+ *
165
+ * @param Varien_Event_Observer $observer [description]
166
+ * @return [type] [description]
167
+ */
168
+ public function saveReferralAndTrackingId(Varien_Event_Observer $observer) {
169
+ if (!$this->isEnabled()) return;
170
+
171
+ $referral_id = Mage::app()->getRequest()->getParam('ll_ref_id');
172
+
173
+ // don't overwrite an existing referral_id in the session, if one exists
174
+ if ($referral_id && !$this->session->getLoyaltyLionReferralId()) {
175
+ $this->session->setLoyaltyLionReferralId($referral_id);
176
+ }
177
+
178
+ // check and set tracking_id by ll_eid param
179
+
180
+ $tracking_id = Mage::app()->getRequest()->getParam('ll_eid');
181
+ if (!$tracking_id) return;
182
+
183
+ // I can't determine the expiration mechanics behind `$this->session`, so we'll do the same thing
184
+ // we did for PrestaShop and attach a timestamp to the tracking_id, so we can ignore it if it's
185
+ // too old when we track an event later
186
+
187
+ $value = time() . ':::' . $tracking_id;
188
+ $this->session->setLoyaltyLionTrackingId($value);
189
+ }
190
+
191
+ /**
192
+ * Send an updated order to the Orders API
193
+ *
194
+ * Because the update endpoint is idempotent, this can be called as many times as needed to catch all
195
+ * updates to an order without worrying about missing any order updates, as we send it all off here
196
+ *
197
+ * @param [type] $order [description]
198
+ * @return [type] [description]
199
+ */
200
+ private function sendOrderUpdate($order) {
201
+ if (!$order || !$order->getId()) return;
202
+
203
+ $data = array(
204
+ 'refund_status' => 'not_refunded',
205
+ 'total_refunded' => 0,
206
+ 'ip_address' => Mage::helper('core/http')->getRemoteAddr(),
207
+ 'user_agent' => $_SERVER['HTTP_USER_AGENT']
208
+ );
209
+
210
+ if ($order->getBaseTotalDue() == $order->getBaseGrandTotal()) {
211
+ $data['payment_status'] = 'not_paid';
212
+ $data['total_paid'] = 0;
213
+ } else if ($order->getBaseTotalDue() == 0) {
214
+ $data['payment_status'] = 'paid';
215
+ $data['total_paid'] = $order->getBaseGrandTotal();
216
+ } else {
217
+ $data['payment_status'] = 'partially_paid';
218
+ $data['total_paid'] = $order->getBaseTotalPaid();
219
+ }
220
+
221
+ $data['cancellation_status'] = $order->getState() == 'canceled' ? 'cancelled' : 'not_cancelled';
222
+
223
+ $total_refunded = $order->getBaseTotalRefunded();
224
+
225
+ if ($total_refunded > 0) {
226
+ if ($total_refunded < $order->getBaseGrandTotal()) {
227
+ $data['refund_status'] = 'partially_refunded';
228
+ $data['total_refunded'] = $total_refunded;
229
+ } else {
230
+ // assume full refund. this should be fine as magento appears to only allow refunding up to
231
+ // the amount paid
232
+ $data['refund_status'] = 'refunded';
233
+ $data['total_refunded'] = $order->getBaseGrandTotal();
234
+ }
235
+ }
236
+
237
+ $data['$magento_payload'] = $order->toArray();
238
+ $data['$magento_payload']['order_items'] = $this->getItems($order->getId());
239
+ $data['$magento_payload']['order_comments'] = $this->getComments($order->getId());
240
+ $data['$magento_payload']['addresses'] = $this->getAddresses($order->getId());
241
+ $data['$magento_version'] = Mage::getVersion();
242
+ $data['$magento_platform'] = Mage::getEdition();
243
+ $data['$magento_module_version'] = (string) Mage::getConfig()->getModuleConfig("LoyaltyLion_Core")->version;
244
+
245
+ $response = $this->client->orders->update($order->getId(), $data);
246
+
247
+ if ($response->success) {
248
+ Mage::log('[LoyaltyLion] Updated order OK');
249
+ } else if ($response->status != 404) {
250
+ // sometimes this will get fired before the order has been created, so we'll get a 404 back - no reason to
251
+ // error, because this is expected behaviour
252
+ Mage::log('[LoyaltyLion] Failed to update order - status: ' . $response->status . ', error: ' . $response->error,
253
+ Zend_Log::ERR);
254
+ }
255
+ }
256
+
257
+ /**
258
+ * Track a signup event for the given customer
259
+ *
260
+ * @param [type] $customer [description]
261
+ * @return [type] [description]
262
+ */
263
+ private function trackSignup($customer) {
264
+
265
+ $data = array(
266
+ 'customer_id' => $customer->getId(),
267
+ 'customer_email' => $customer->getEmail(),
268
+ 'date' => date('c'),
269
+ 'ip_address' => Mage::helper('core/http')->getRemoteAddr(),
270
+ 'user_agent' => $_SERVER['HTTP_USER_AGENT']
271
+ );
272
+
273
+ if ($this->session->getLoyaltyLionReferralId())
274
+ $data['referral_id'] = $this->session->getLoyaltyLionReferralId();
275
+
276
+ $tracking_id = $this->getTrackingIdFromSession();
277
+
278
+ if ($tracking_id)
279
+ $data['tracking_id'] = $tracking_id;
280
+
281
+ $response = $this->client->events->track('signup', $data);
282
+
283
+ if ($response->success) {
284
+ Mage::log('[LoyaltyLion] Tracked event [signup] OK');
285
+ } else {
286
+ Mage::log('[LoyaltyLion] Failed to track event - status: ' . $response->status . ', error: ' . $response->error,
287
+ Zend_Log::ERR);
288
+ }
289
+ }
290
+
291
+ /**
292
+ * Check the session for a `tracking_id`, and return it unless it has expired
293
+ *
294
+ * @return [type] Tracking id or null if it doesn't exist or has expired
295
+ */
296
+ private function getTrackingIdFromSession() {
297
+ if (!$this->session->getLoyaltyLionTrackingId())
298
+ return null;
299
+
300
+ $values = explode(':::', $this->session->getLoyaltyLionTrackingId());
301
+
302
+ if (empty($values))
303
+ return null;
304
+
305
+ if (count($values) != 2)
306
+ return $values[0];
307
+
308
+ // for now, let's have a 24 hour expiration time on the timestamp
309
+ if (time() - (int)$values[0] > 86400)
310
+ return null;
311
+
312
+ return $values[1];
313
+ }
314
+ }
app/code/local/LoyaltyLion/Core/etc/config.xml ADDED
@@ -0,0 +1,115 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version='1.0' encoding='UTF-8' ?>
2
+ <config>
3
+ <modules>
4
+ <LoyaltyLion_Core>
5
+ <version>0.0.3</version>
6
+ </LoyaltyLion_Core>
7
+ </modules>
8
+ <global>
9
+ <blocks>
10
+ <loyaltylion>
11
+ <class>LoyaltyLion_Core_Block</class>
12
+ </loyaltylion>
13
+ </blocks>
14
+ <helpers>
15
+ <loyaltylion>
16
+ <class>LoyaltyLion_Core_Helper</class>
17
+ </loyaltylion>
18
+ </helpers>
19
+ <models>
20
+ <loyaltylion>
21
+ <class>LoyaltyLion_Core_Model</class>
22
+ </loyaltylion>
23
+ </models>
24
+ <events>
25
+ <sales_order_place_after>
26
+ <observers>
27
+ <loyaltylion_order_placed>
28
+ <class>loyaltylion/observer</class>
29
+ <method>handleOrderCreate</method>
30
+ </loyaltylion_order_placed>
31
+ </observers>
32
+ </sales_order_place_after>
33
+ <!-- <order_cancel_after>
34
+ <observers>
35
+ <loyaltylion_order_cancelled>
36
+ <class>loyaltylion/observer</class>
37
+ <method>handleOrderCancellation</method>
38
+ </loyaltylion_order_cancelled>
39
+ </observers>
40
+ </order_cancel_after> -->
41
+ <!-- <sales_order_payment_pay>
42
+ <observers>
43
+ <sales_order_payment_save_after>
44
+ <class>loyaltylion/observer</class>
45
+ <method>handleOrderPayment</method>
46
+ </sales_order_payment_save_after>
47
+ </observers>
48
+ </sales_order_payment_pay> -->
49
+ <sales_order_save_after>
50
+ <observers>
51
+ <sales_order_save_after>
52
+ <class>loyaltylion/observer</class>
53
+ <method>handleOrderUpdate</method>
54
+ </sales_order_save_after>
55
+ </observers>
56
+ </sales_order_save_after>
57
+ <customer_register_success>
58
+ <observers>
59
+ <loyaltylion_customer_registration>
60
+ <class>loyaltylion/observer</class>
61
+ <method>handleCustomerRegistration</method>
62
+ </loyaltylion_customer_registration>
63
+ </observers>
64
+ </customer_register_success>
65
+ <core_copy_fieldset_customer_account_to_quote>
66
+ <observers>
67
+ <loyaltylion_customer_registration_onepage>
68
+ <class>loyaltylion/observer</class>
69
+ <method>handleCustomerRegistrationOnepage</method>
70
+ </loyaltylion_customer_registration_onepage>
71
+ </observers>
72
+ </core_copy_fieldset_customer_account_to_quote>
73
+ </events>
74
+ </global>
75
+ <frontend>
76
+ <layout>
77
+ <updates>
78
+ <loyaltylion>
79
+ <file>loyaltylion.xml</file>
80
+ </loyaltylion>
81
+ </updates>
82
+ </layout>
83
+ <events>
84
+ <controller_action_predispatch>
85
+ <observers>
86
+ <loyaltylion_predispatch>
87
+ <class>loyaltylion/observer</class>
88
+ <method>saveReferralAndTrackingId</method>
89
+ </loyaltylion_predispatch>
90
+ </observers>
91
+ </controller_action_predispatch>
92
+ </events>
93
+ </frontend>
94
+ <adminhtml>
95
+ <acl>
96
+ <resources>
97
+ <admin>
98
+ <children>
99
+ <system>
100
+ <children>
101
+ <config>
102
+ <children>
103
+ <loyaltylion>
104
+ <title>LoyaltyLion configuration</title>
105
+ </loyaltylion>
106
+ </children>
107
+ </config>
108
+ </children>
109
+ </system>
110
+ </children>
111
+ </admin>
112
+ </resources>
113
+ </acl>
114
+ </adminhtml>
115
+ </config>
app/code/local/LoyaltyLion/Core/etc/system.xml ADDED
@@ -0,0 +1,57 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version='1.0'?>
2
+ <config>
3
+ <tabs>
4
+ <loyaltylion_tab translate='label' module='loyaltylion'>
5
+ <label>LoyaltyLion</label>
6
+ <sort_order>20000</sort_order>
7
+ </loyaltylion_tab>
8
+ </tabs>
9
+ <sections>
10
+ <loyaltylion translate='label content' module='loyaltylion'>
11
+ <tab>customer</tab>
12
+ <label>LoyaltyLion</label>
13
+ <frontend_type>text</frontend_type>
14
+ <sort_order>9999</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
+ <configuration translate='label comment' module='loyaltylion'>
20
+ <label>LoyaltyLion configuration</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
+ <loyaltylion_token translate='label'>
28
+ <label>Token</label>
29
+ <frontend_type>text</frontend_type>
30
+ <sort_order>10</sort_order>
31
+ <show_in_default>1</show_in_default>
32
+ <show_in_website>1</show_in_website>
33
+ <show_in_store>1</show_in_store>
34
+ </loyaltylion_token>
35
+ <loyaltylion_secret translate='label'>
36
+ <label>Secret</label>
37
+ <frontend_type>text</frontend_type>
38
+ <sort_order>20</sort_order>
39
+ <show_in_default>1</show_in_default>
40
+ <show_in_website>1</show_in_website>
41
+ <show_in_store>1</show_in_store>
42
+ </loyaltylion_secret>
43
+ <initapi translate='label'>
44
+ <label>Quick-Setup API access</label>
45
+ <frontend_type>button</frontend_type>
46
+ <frontend_model>couponimport/adminhtml_button</frontend_model>
47
+ <sort_order>30</sort_order>
48
+ <show_in_default>1</show_in_default>
49
+ <show_in_website>1</show_in_website>
50
+ <show_in_store>1</show_in_store>
51
+ </initapi>
52
+ </fields>
53
+ </configuration>
54
+ </groups>
55
+ </loyaltylion>
56
+ </sections>
57
+ </config>
app/code/local/LoyaltyLion/Core/lib/loyaltylion-client/lib/connection.php ADDED
@@ -0,0 +1,84 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class LoyaltyLion_Connection {
4
+
5
+ private $token;
6
+ private $secret;
7
+ private $auth;
8
+ private $base_uri;
9
+ private $timeout = 5;
10
+
11
+ public function __construct($token, $secret, $base_uri) {
12
+ $this->token = $token;
13
+ $this->secret = $secret;
14
+ $this->base_uri = $base_uri;
15
+ }
16
+
17
+ public function post($path, $data = array()) {
18
+ return $this->request('POST', $path, $data);
19
+ }
20
+
21
+ public function put($path, $data = array()) {
22
+ return $this->request('PUT', $path, $data);
23
+ }
24
+
25
+ private function request($method, $path, $data) {
26
+
27
+ $options = array(
28
+ CURLOPT_URL => $this->base_uri . $path,
29
+ CURLOPT_USERAGENT => 'loyaltylion-php-client-v2.0.0',
30
+ CURLOPT_RETURNTRANSFER => true,
31
+ CURLOPT_TIMEOUT => $this->timeout,
32
+ // CURLOPT_HEADER => false,
33
+ CURLOPT_USERPWD => $this->token . ':' . $this->secret,
34
+ );
35
+
36
+ switch ($method) {
37
+ case 'POST':
38
+ $options += array(
39
+ CURLOPT_POST => true,
40
+ );
41
+ break;
42
+ case 'PUT':
43
+ $options += array(
44
+ CURLOPT_CUSTOMREQUEST => 'PUT',
45
+ );
46
+ }
47
+
48
+ if (!empty($data)) {
49
+ $body = json_encode($data);
50
+
51
+ $options += array(
52
+ CURLOPT_POSTFIELDS => $body,
53
+ CURLOPT_HTTPHEADER => array(
54
+ 'Content-Type: application/json',
55
+ 'Content-Length: ' . strlen($body),
56
+ ),
57
+ );
58
+ }
59
+
60
+ // now make the request
61
+ $curl = curl_init();
62
+ curl_setopt_array($curl, $options);
63
+
64
+ $body = curl_exec($curl);
65
+ $headers = curl_getinfo($curl);
66
+ $error_code = curl_errno($curl);
67
+ $error_msg = curl_error($curl);
68
+
69
+ if ($error_code !== 0) {
70
+ $response = array(
71
+ 'status' => $headers['http_code'],
72
+ 'error' => $error_msg,
73
+ );
74
+ } else {
75
+ $response = array(
76
+ 'status' => $headers['http_code'],
77
+ 'headers' => $headers,
78
+ 'body' => $body,
79
+ );
80
+ }
81
+
82
+ return (object) $response;
83
+ }
84
+ }
app/code/local/LoyaltyLion/Core/lib/loyaltylion-client/main.php ADDED
@@ -0,0 +1,193 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require('lib/connection.php');
4
+
5
+ class LoyaltyLion_Client {
6
+
7
+ private $token;
8
+ private $secret;
9
+ private $connection;
10
+ private $base_uri = 'https://api.loyaltylion.com/v2';
11
+
12
+ public function __construct($token, $secret, $extra = array()) {
13
+ $this->token = $token;
14
+ $this->secret = $secret;
15
+
16
+ if (empty($this->token) || empty($this->secret)) {
17
+ throw new Exception("Please provide a valid token and secret (token: ${token}, secret: ${secret})");
18
+ }
19
+
20
+ if (isset($extra['base_uri'])) $this->base_uri = $extra['base_uri'];
21
+
22
+ $this->connection = new LoyaltyLion_Connection($this->token, $this->secret, $this->base_uri);
23
+
24
+ $this->activities = $this->events = new LoyaltyLion_Activities($this->connection);
25
+ $this->orders = new LoyaltyLion_Orders($this->connection);
26
+ }
27
+
28
+ /**
29
+ * Get a customer auth token from LoyaltyLion
30
+ *
31
+ * @deprecated Use JavaScript MAC authentication instead
32
+ *
33
+ * @param [type] $customer_id [description]
34
+ * @return [type] [description]
35
+ */
36
+ public function getCustomerAuthToken($customer_id) {
37
+ $params = array(
38
+ 'customer_id' => $customer_id,
39
+ );
40
+
41
+ $response = $this->connection->post('/customers/authenticate', $params);
42
+
43
+ if (isset($response->error)) {
44
+ echo "LoyaltyLion client error: " . $response->error;
45
+ }
46
+
47
+ // should have got json back
48
+ if (empty($response->body)) return null;
49
+
50
+ $json = json_decode($response->body);
51
+
52
+ if ($json && $json->auth_token) {
53
+ return $json->auth_token;
54
+ } else {
55
+ return null;
56
+ }
57
+ }
58
+
59
+ protected function parseResponse($response) {
60
+ if (isset($response->error)) {
61
+ // this kind of error is from curl itself, e.g. a request timeout, so just return that error
62
+ return (object) array(
63
+ 'success' => false,
64
+ 'status' => $response->status,
65
+ 'error' => $response->error,
66
+ );
67
+ }
68
+
69
+ $result = array(
70
+ 'success' => (int) $response->status >= 200 && (int) $response->status <= 204
71
+ );
72
+
73
+ if (!$result['success']) {
74
+ // even if curl succeeded, it can still fail if the request was invalid - we
75
+ // usually have the error as the body so just stick that in
76
+ $result['error'] = $response->body;
77
+ $result['status'] = $response->status;
78
+ }
79
+
80
+ return (object) $result;
81
+ }
82
+ }
83
+
84
+ class LoyaltyLion_Activities extends LoyaltyLion_Client {
85
+
86
+ public function __construct($connection) {
87
+ $this->connection = $connection;
88
+ }
89
+
90
+ /**
91
+ * Track an activity
92
+ *
93
+ * @param [type] $name The activity name, e.g. "signup"
94
+ * @param array $properties Activity data
95
+ *
96
+ * @return object An object with information about the request. If the track
97
+ * was successful, object->success will be true.
98
+ */
99
+ public function track($name, $data) {
100
+
101
+ if (!is_array($data)) throw new Exception('Activity data must be an array');
102
+
103
+ $data['name'] = $name;
104
+
105
+ if (empty($data['name'])) throw new Exception('Activity name is required');
106
+ if (empty($data['customer_id'])) throw new Exception('customer_id is required');
107
+ if (empty($data['customer_email'])) throw new Exception('customer_email is required');
108
+
109
+ if (empty($data['date'])) $data['date'] = date('c');
110
+
111
+ $response = $this->connection->post('/activities', $data);
112
+
113
+ return $this->parseResponse($response);
114
+ }
115
+
116
+ /**
117
+ * Update an activity using its merchant_id
118
+ *
119
+ * @param [type] $name [description]
120
+ * @param [type] $id [description]
121
+ * @param [type] $data [description]
122
+ * @return [type] [description]
123
+ */
124
+ public function update($name, $id, $data) {
125
+ $response = $this->connection->put('/activities/' . $name . '/' . $id, $data);
126
+
127
+ return $this->parseResponse($response);
128
+ }
129
+ }
130
+
131
+ class LoyaltyLion_Orders extends LoyaltyLion_Client {
132
+
133
+ public function __construct($connection) {
134
+ $this->connection = $connection;
135
+ }
136
+
137
+ /**
138
+ * Create an order in LoyaltyLion
139
+ *
140
+ * @param [type] $data [description]
141
+ * @return [type] [description]
142
+ */
143
+ public function create($data) {
144
+ $response = $this->connection->post('/orders', $data);
145
+
146
+ return $this->parseResponse($response);
147
+ }
148
+
149
+ /**
150
+ * Update an order by its merchant_id in LoyaltyLion
151
+ *
152
+ * This is an idempotent update which is safe to call everytime an order is updated
153
+ *
154
+ * @param [type] $id [description]
155
+ * @param [type] $data [description]
156
+ * @return [type] [description]
157
+ */
158
+ public function update($id, $data) {
159
+ $response = $this->connection->put('/orders/' . $id, $data);
160
+
161
+ return $this->parseResponse($response);
162
+ }
163
+
164
+ public function setCancelled($id) {
165
+ $response = $this->connection->put('/orders/' . $id . '/cancelled');
166
+
167
+ return $this->parseResponse($response);
168
+ }
169
+
170
+ public function setPaid($id) {
171
+ $response = $this->connection->put('/orders/' . $id . '/paid');
172
+
173
+ return $this->parseResponse($response);
174
+ }
175
+
176
+ public function setRefunded($id) {
177
+ $response = $this->connection->put('/orders/' . $id . '/refunded');
178
+
179
+ return $this->parseResponse($response);
180
+ }
181
+
182
+ public function addPayment($id, $data) {
183
+ $response = $this->connection->post('/orders/' . $id . '/payments', $data);
184
+
185
+ return $this->parseResponse($response);
186
+ }
187
+
188
+ public function addRefund($id, $data) {
189
+ $response = $this->connection->post('/orders/' . $id . '/refunds', $data);
190
+
191
+ return $this->parseResponse($response);
192
+ }
193
+ }
app/code/local/LoyaltyLion/CouponImport/Block/Adminhtml/Button.php ADDED
@@ -0,0 +1,54 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class LoyaltyLion_CouponImport_Block_Adminhtml_Button extends Mage_Adminhtml_Block_System_Config_Form_Field
3
+ {
4
+ /*
5
+ * Set template
6
+ */
7
+ protected function _construct()
8
+ {
9
+ parent::_construct();
10
+ $this->setTemplate('loyaltylion/system/config/button.phtml');
11
+ }
12
+
13
+ /**
14
+ * Return element html
15
+ *
16
+ * @param Varien_Data_Form_Element_Abstract $element
17
+ * @return string
18
+ */
19
+ protected function _getElementHtml(Varien_Data_Form_Element_Abstract $element)
20
+ {
21
+ return $this->_toHtml();
22
+ }
23
+
24
+ /**
25
+ * Return ajax url for button
26
+ *
27
+ * @return string
28
+ */
29
+ public function getAjaxSetupUrl()
30
+ {
31
+ return Mage::helper('adminhtml')->getUrl('adminhtml/quicksetup/setup');
32
+ }
33
+
34
+ /**
35
+ * Generate button html
36
+ *
37
+ * @return string
38
+ */
39
+ public function getButtonHtml()
40
+ {
41
+ $configured = Mage::getStoreConfig('loyaltylion/internals/has_submitted_oauth');
42
+ $text = $configured ? "API access is already configured" : "Configure API access";
43
+ $class = $configured ? "success" : "";
44
+ $button = $this->getLayout()->createBlock('adminhtml/widget_button')
45
+ ->setData(array(
46
+ 'id' => 'loyaltylion_setup_button',
47
+ 'label' => $this->helper('adminhtml')->__($text),
48
+ 'onclick' => 'javascript:doSetup(); return false;',
49
+ 'class' => $class
50
+ ));
51
+
52
+ return $button->toHtml();
53
+ }
54
+ }
app/code/local/LoyaltyLion/CouponImport/Model/Api2/Coupon.php ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ <?php
2
+ class LoyaltyLion_CouponImport_Model_Api2_Coupon extends Mage_Api2_Model_Resource
3
+ {
4
+ }
app/code/local/LoyaltyLion/CouponImport/Model/Api2/Coupon/Rest/Admin/V1.php ADDED
@@ -0,0 +1,73 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* LoyaltyLion Coupon Import API
3
+ *
4
+ * @category LoyaltyLion
5
+ * @package LoyaltyLion_CouponImport
6
+ * @author Patrick Molgaard
7
+ */
8
+ class LoyaltyLion_CouponImport_Model_Api2_Coupon_Rest_Admin_V1 extends LoyaltyLion_CouponImport_Model_Api2_Coupon
9
+ {
10
+ /**
11
+ * Import LoyaltyLion coupons
12
+ *
13
+ * @param array $coupons
14
+ * @return string|void
15
+ */
16
+ protected function _multiCreate($coupons)
17
+ {
18
+ $ruleId = $this->getRequest()->getParam('rule_id');
19
+ $rule = $this->_loadSalesRule($ruleId);
20
+
21
+ $coupon = Mage::getModel('salesrule/coupon');
22
+ $now = $rule->getResource()->formatDate(
23
+ Mage::getSingleton('core/date')->gmtTimestamp()
24
+ );
25
+ $expirationDate = $rule->to_date;
26
+ foreach ($coupons as $cpn) {
27
+ $coupon->setId(null)
28
+ ->setRuleId($ruleId)
29
+ ->setUsageLimit(1)
30
+ ->setUsagePerCustomer(1)
31
+ ->setExpirationDate($expirationDate)
32
+ ->setCreatedAt($now)
33
+ ->setType(Mage_SalesRule_Helper_Coupon::COUPON_TYPE_SPECIFIC_AUTOGENERATED)
34
+ ->setCode($cpn['code'])
35
+ ->save();
36
+ }
37
+ }
38
+ /**
39
+ * Retrieve list of coupon codes.
40
+ *
41
+ * @return array
42
+ */
43
+ protected function _retrieveCollection()
44
+ {
45
+ $ruleId = $this->getRequest()->getParam('rule_id');
46
+ $rule = $this->_loadSalesRule($ruleId);
47
+ /** @var Mage_SalesRule_Model_Resource_Coupon_Collection $collection */
48
+ $collection = Mage::getResourceModel('salesrule/coupon_collection');
49
+ $collection->addRuleToFilter($rule);
50
+ $this->_applyCollectionModifiers($collection);
51
+ $data = $collection->load()->toArray();
52
+ return $data['items'];
53
+ }
54
+ /**
55
+ * Load sales rule by ID.
56
+ *
57
+ * @param int $ruleId
58
+ * @return Mage_SalesRule_Model_Rule
59
+ */
60
+ protected function _loadSalesRule($ruleId)
61
+ {
62
+ if (!$ruleId) {
63
+ $this->_critical(Mage::helper('salesrule')
64
+ ->__('Rule ID not specified.'), Mage_Api2_Model_Server::HTTP_BAD_REQUEST);
65
+ }
66
+ $rule = Mage::getModel('salesrule/rule')->load($ruleId);
67
+ if (!$rule->getId()) {
68
+ $this->_critical(Mage::helper('salesrule')
69
+ ->__('Rule was not found.'), Mage_Api2_Model_Server::HTTP_NOT_FOUND);
70
+ }
71
+ return $rule;
72
+ }
73
+ }
app/code/local/LoyaltyLion/CouponImport/Model/Api2/PriceRule.php ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ <?php
2
+ class LoyaltyLion_CouponImport_Model_Api2_PriceRule extends Mage_Api2_Model_Resource
3
+ {
4
+ }
app/code/local/LoyaltyLion/CouponImport/Model/Api2/PriceRule/Rest/Admin/V1.php ADDED
@@ -0,0 +1,65 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /* LoyaltyLion Coupon Import API
3
+ *
4
+ * @category LoyaltyLion
5
+ * @package LoyaltyLion_CouponImport
6
+ * @author Patrick Molgaard
7
+ */
8
+ class LoyaltyLion_CouponImport_Model_Api2_PriceRule_Rest_Admin_V1 extends LoyaltyLion_CouponImport_Model_Api2_PriceRule
9
+ {
10
+ /**
11
+ * Create shopping cart price rule
12
+ *
13
+ * @param array $coupons
14
+ * @return string|void
15
+ */
16
+ protected function _create($priceRule)
17
+ {
18
+ $model = Mage::getModel('salesrule/rule');
19
+ $model->loadPost($priceRule);
20
+ $model->setUseAutoGeneration($priceRule["use_auto_generation"]);
21
+ $model->save();
22
+ $data = $model->getData();
23
+ $id = $data['rule_id'];
24
+ return "/api/rest/loyaltylion/rules/{$id}";
25
+ }
26
+ /**
27
+ * Retrieve price rule
28
+ *
29
+ * @return array
30
+ */
31
+ protected function _retrieve()
32
+ {
33
+ $ruleId = $this->getRequest()->getParam('rule_id');
34
+ $rule = $this->_loadSalesRule($ruleId);
35
+ $data = $rule->toArray();
36
+ return $data;
37
+ }
38
+ protected function _retrieveCollection()
39
+ {
40
+ $collection = Mage::getModel('salesrule/rule')
41
+ ->getResourceCollection();
42
+ $this->_applyCollectionModifiers($collection);
43
+ $data = $collection->load()->toArray();
44
+ return $data['items'];
45
+ }
46
+ /**
47
+ * Load sales rule by ID.
48
+ *
49
+ * @param int $ruleId
50
+ * @return Mage_SalesRule_Model_Rule
51
+ */
52
+ protected function _loadSalesRule($ruleId)
53
+ {
54
+ if (!$ruleId) {
55
+ $this->_critical(Mage::helper('salesrule')
56
+ ->__('Rule ID not specified.'), Mage_Api2_Model_Server::HTTP_BAD_REQUEST);
57
+ }
58
+ $rule = Mage::getModel('salesrule/rule')->load($ruleId);
59
+ if (!$rule->getId()) {
60
+ $this->_critical(Mage::helper('salesrule')
61
+ ->__('Rule was not found.'), Mage_Api2_Model_Server::HTTP_NOT_FOUND);
62
+ }
63
+ return $rule;
64
+ }
65
+ }
app/code/local/LoyaltyLion/CouponImport/controllers/Adminhtml/QuickSetupController.php ADDED
@@ -0,0 +1,223 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require( Mage::getModuleDir('', 'LoyaltyLion_Core') . DS . 'lib' . DS . 'loyaltylion-client' . DS . 'lib' . DS . 'connection.php' );
4
+
5
+ class LoyaltyLion_CouponImport_Adminhtml_QuickSetupController extends Mage_Adminhtml_Controller_Action
6
+ {
7
+ private $loyaltyLionURL = 'https://loyaltylion.com';
8
+
9
+ public function generateRestRole($name) {
10
+ Mage::log("[LoyaltyLion] creating REST role");
11
+ //check "rest role created" flag
12
+ //if not set, create the role w/ all resources & return ID
13
+ $role = Mage::getModel('api2/acl_global_role');
14
+ $role->setRoleName($name)->save();
15
+ $roleId = $role->getId();
16
+
17
+ $rule = Mage::getModel('api2/acl_global_rule');
18
+ if ($roleId) {
19
+ //Purge existing rules for this role
20
+ $collection = $rule->getCollection();
21
+ $collection->addFilterByRoleId($role->getId());
22
+
23
+ /** @var $model Mage_Api2_Model_Acl_Global_Rule */
24
+ foreach ($collection as $model) {
25
+ $model->delete();
26
+ }
27
+ }
28
+ $ruleTree = Mage::getSingleton(
29
+ 'api2/acl_global_rule_tree',
30
+ array('type' => Mage_Api2_Model_Acl_Global_Rule_Tree::TYPE_PRIVILEGE)
31
+ );
32
+ //Allow everything
33
+ $resources = array(
34
+ Mage_Api2_Model_Acl_Global_Rule::RESOURCE_ALL => array(
35
+ null => Mage_Api2_Model_Acl_Global_Rule_Permission::TYPE_ALLOW
36
+ )
37
+ );
38
+
39
+ $id = $role->getId();
40
+ foreach ($resources as $resourceId => $privileges) {
41
+ foreach ($privileges as $privilege => $allow) {
42
+ if (!$allow) {
43
+ continue;
44
+ }
45
+
46
+ $rule->setId(null)
47
+ ->isObjectNew(true);
48
+
49
+ $rule->setRoleId($id)
50
+ ->setResourceId($resourceId)
51
+ ->setPrivilege($privilege)
52
+ ->save();
53
+ }
54
+ }
55
+
56
+ return $roleId;
57
+ }
58
+
59
+ public function assignToRole($userId, $roleId) {
60
+ Mage::log("[LoyaltyLion] Assigning current admin user to LoyaltyLion REST role");
61
+ $model = Mage::getResourceModel('api2/acl_global_role');
62
+ $model->saveAdminToRoleRelation($userId, $roleId);
63
+ }
64
+
65
+ public function enableAllAttributes() {
66
+ Mage::log("[LoyaltyLion] Enabling attribute access for this REST role");
67
+ $type = 'admin';
68
+ $ruleTree = Mage::getSingleton(
69
+ 'api2/acl_global_rule_tree',
70
+ array('type' => Mage_Api2_Model_Acl_Global_Rule_Tree::TYPE_ATTRIBUTE)
71
+ );
72
+ /** @var $attribute Mage_Api2_Model_Acl_Filter_Attribute */
73
+ $attribute = Mage::getModel('api2/acl_filter_attribute');
74
+ /** @var $collection Mage_Api2_Model_Resource_Acl_Filter_Attribute_Collection */
75
+ $collection = $attribute->getCollection();
76
+ $collection->addFilterByUserType($type);
77
+ /** @var $model Mage_Api2_Model_Acl_Filter_Attribute */
78
+ foreach ($collection as $model) {
79
+ $model->delete();
80
+ }
81
+ $resources = array(
82
+ Mage_Api2_Model_Acl_Global_Rule::RESOURCE_ALL => array(
83
+ null => Mage_Api2_Model_Acl_Global_Rule_Permission::TYPE_ALLOW
84
+ )
85
+ );
86
+ foreach ($resources as $resourceId => $operations) {
87
+ if (Mage_Api2_Model_Acl_Global_Rule::RESOURCE_ALL === $resourceId) {
88
+ $attribute->setUserType($type)
89
+ ->setResourceId($resourceId)
90
+ ->save();
91
+ } else {
92
+ foreach ($operations as $operation => $attributes) {
93
+ $attribute->setId(null)
94
+ ->isObjectNew(true);
95
+ $attribute->setUserType($type)
96
+ ->setResourceId($resourceId)
97
+ ->setOperation($operation)
98
+ ->setAllowedAttributes(implode(',', array_keys($attributes)))
99
+ ->save();
100
+ }
101
+ }
102
+ }
103
+ }
104
+
105
+ public function generateOAuthCredentials($name, $userID) {
106
+ Mage::log("[LoyaltyLion] Generating OAuth credentials");
107
+ $model = Mage::getModel('oauth/consumer');
108
+ $helper = Mage::helper('oauth');
109
+ $data['key'] = $helper->generateConsumerKey();
110
+ $data['secret'] = $helper->generateConsumerSecret();
111
+ $model->addData($data);
112
+ $model->setName($name);
113
+ $model->save();
114
+ $consumer_id = $model->getId();
115
+ $accessToken = $this->getAccessToken($consumer_id, $userID);
116
+
117
+ return array_merge(array('consumer_key' => $data['key'], 'consumer_secret' => $data['secret'], 'id' => $consumer_id), $accessToken);
118
+ }
119
+
120
+ public function getAccessToken($consumer_id, $userID) {
121
+ $requestToken = Mage::getModel('oauth/token')->createRequestToken($consumer_id, "https://loyaltylion.com/");
122
+ $requestToken->authorize($userID, 'admin');
123
+ $accessToken = $requestToken->convertToAccess();
124
+ $accessData = $accessToken->getData();
125
+ return array('access_token' => $accessData['token'], 'access_secret' => $accessData['secret']);
126
+ }
127
+
128
+ public function getOAuthCredentials($id, $userID) {
129
+ Mage::log("[LoyaltyLion] Retrieving OAuth credentials");
130
+ $model = Mage::getModel('oauth/consumer');
131
+ $model->load($id);
132
+ $oauth = $model->getData();
133
+ $accessToken = $this->getAccessToken($id, $userID);
134
+ return array_merge(array('consumer_key' => $oauth['key'], 'consumer_secret' => $oauth['secret']), $accessToken);
135
+ }
136
+
137
+ public function submitOAuthCredentials($credentials) {
138
+ if (isset($_SERVER['LOYALTYLION_WEBSITE_BASE'])) {
139
+ $loyaltyLionURL = $_SERVER['LOYALTYLION_WEBSITE_BASE'];
140
+ }
141
+ Mage::log("[LoyaltyLion] Submitting OAuth credentials to LoyaltyLion site");
142
+
143
+ $token = Mage::getStoreConfig('loyaltylion/configuration/loyaltylion_token');
144
+ $secret = Mage::getStoreConfig('loyaltylion/configuration/loyaltylion_secret');
145
+
146
+ $connection = new LoyaltyLion_Connection($token, $secret, $loyaltyLionURL);
147
+ $setup_uri = '/magento/oauth_credentials';
148
+ $base_url = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);
149
+ $credentials['base_url'] = $base_url;
150
+ $credentials['extension_version'] = (string) Mage::getConfig()->getModuleConfig("LoyaltyLion_Core")->version;
151
+ $resp = $connection->post($setup_uri, $credentials);
152
+ if (isset($resp->error)) {
153
+ Mage::log("[LoyaltyLion] Error submitting credentials:" .' '. $resp->error);
154
+ return "network-error";
155
+ } elseif ((int) $resp->status >= 200 && (int) $resp->status <= 204) {
156
+ return "ok";
157
+ } elseif ((int) $resp->status == 422) {
158
+ mage::log("[loyaltylion] error submitting credentials:" .' '. $resp->status .' '. $resp->body);
159
+ return "credentials-error";
160
+ } else {
161
+ mage::log("[loyaltylion] error submitting credentials:" .' '. $resp->status .' '. $resp->body);
162
+ return "unknown-error";
163
+ }
164
+ }
165
+
166
+ public function LLAPISetup() {
167
+ Mage::log("[LoyaltyLion] Setting up API access");
168
+ $currentUser = Mage::getSingleton('admin/session')->getUser()->getId();
169
+ $roleName = 'LoyaltyLion';
170
+ $AppName = 'LoyaltyLion';
171
+
172
+ $token = $this->getRequest()->getParam('token');
173
+ $secret = $this->getRequest()->getParam('secret');
174
+
175
+ if (!empty($token) && !empty($secret)) {
176
+ Mage::log("[LoyaltyLion] Saving new LoyaltyLion credentials");
177
+ Mage::getModel('core/config')->saveConfig('loyaltylion/configuration/loyaltylion_token', $token);
178
+ Mage::getModel('core/config')->saveConfig('loyaltylion/configuration/loyaltylion_secret', $secret);
179
+ } else {
180
+ $token = Mage::getStoreConfig('loyaltylion/configuration/loyaltylion_token');
181
+ $secret = Mage::getStoreConfig('loyaltylion/configuration/loyaltylion_secret');
182
+ }
183
+
184
+ $roleID = Mage::getStoreConfig('loyaltylion/internals/rest_role_id');
185
+ if (!$roleID) {
186
+ $roleID = $this->generateRestRole($roleName);
187
+ Mage::getModel('core/config')->saveConfig('loyaltylion/internals/rest_role_id', $roleID);
188
+ } else {
189
+ Mage::log("[LoyaltyLion] Already created REST role, skipping");
190
+ }
191
+
192
+ //assigning just overwrites old permissions with "all", so doing it twice is harmless
193
+ $assigned = $this->assignToRole($currentUser, $roleID);
194
+ //As with the role assignment, we can do this twice and it's okay.
195
+ $this->enableAllAttributes();
196
+
197
+ if (empty($token) || empty($secret)) {
198
+ Mage::log("[LoyaltyLion] Could not generate OAuth credentials because token and/or secret not set.");
199
+ return "not-configured-yet";
200
+ }
201
+
202
+ $OAuthConsumerID = Mage::getStoreConfig('loyaltylion/internals/oauth_consumer_id');
203
+ if (!$OAuthConsumerID) {
204
+ $credentials = $this->generateOAuthCredentials($AppName, $currentUser);
205
+ $OAuthConsumerID = $credentials['id'];
206
+ Mage::getModel('core/config')->saveConfig('loyaltylion/internals/oauth_consumer_id', $OAuthConsumerID);
207
+ } else {
208
+ Mage::log("[LoyaltyLion] OAuth is already configured, skipping...");
209
+ $credentials = $this->getOAuthCredentials($OAuthConsumerID, $currentUser);
210
+ }
211
+
212
+ $result = $this->submitOAuthCredentials($credentials);
213
+ if ($result == "ok") {
214
+ Mage::getModel('core/config')->saveConfig('loyaltylion/internals/has_submitted_oauth', 1);
215
+ }
216
+ return $result;
217
+ }
218
+
219
+ public function setupAction() {
220
+ $result = $this->LLAPISetup();
221
+ Mage::app()->getResponse()->setBody($result);
222
+ }
223
+ }
app/code/local/LoyaltyLion/CouponImport/etc/api2.xml ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <config>
2
+ <api2>
3
+ <resource_groups>
4
+ <couponimport translate="title" module="LoyaltyLion_CouponImport">
5
+ <title>Coupon Import API</title>
6
+ <sort_order>10</sort_order>
7
+ <children>
8
+ <couponimport_coupon translate="title" module="LoyaltyLion_CouponImport">
9
+ <title>Coupon</title>
10
+ <sort_order>10</sort_order>
11
+ </couponimport_coupon>
12
+ <couponimport_pricerule translate="title" module="LoyaltyLion_CouponImport">
13
+ <title>Price Rule</title>
14
+ <sort_order>10</sort_order>
15
+ </couponimport_pricerule>
16
+ </children>
17
+ </couponimport>
18
+ </resource_groups>
19
+ <resources>
20
+ <couponimport_coupon translate="title" module="LoyaltyLion_CouponImport">
21
+ <group>couponimport</group>
22
+ <model>couponimport/api2_coupon</model>
23
+ <title>Coupons</title>
24
+ <sort_order>10</sort_order>
25
+ <privileges>
26
+ <admin>
27
+ <create>1</create>
28
+ <retrieve>1</retrieve>
29
+ </admin>
30
+ </privileges>
31
+ <attributes>
32
+ <coupon_id>Coupon ID</coupon_id>
33
+ <code>Code</code>
34
+ </attributes>
35
+ <routes>
36
+ <route>
37
+ <route>/loyaltylion/rules/:rule_id/codes</route>
38
+ <action_type>collection</action_type>
39
+ </route>
40
+ </routes>
41
+ <versions>1</versions>
42
+ </couponimport_coupon>
43
+ <couponimport_pricerule translate="title" module="LoyaltyLion_CouponImport">
44
+ <group>couponimport</group>
45
+ <model>couponimport/api2_pricerule</model>
46
+ <title>Price Rules</title>
47
+ <sort_order>10</sort_order>
48
+ <privileges>
49
+ <admin>
50
+ <create>1</create>
51
+ <retrieve>1</retrieve>
52
+ <update>1</update>
53
+ </admin>
54
+ </privileges>
55
+ <attributes>
56
+ <rule_id>Rule ID</rule_id>
57
+ <name>Name</name>
58
+ <description>Description</description>
59
+ <simple_action>Simple Action</simple_action>
60
+ <discount_amount>discount_amount</discount_amount>
61
+ <from_date>From Date</from_date>
62
+ <to_date>To Date</to_date>
63
+ <is_active>Is Active</is_active>
64
+ <use_auto_generation>Use Auto Generation</use_auto_generation>
65
+ <website_ids>Website IDs</website_ids>
66
+ <customer_group_ids>Customer group IDs</customer_group_ids>
67
+ <coupon_type>Coupon Type</coupon_type>
68
+ <uses_per_coupon>Uses per coupon</uses_per_coupon>
69
+ <uses_per_customer>Uses per customer</uses_per_customer>
70
+ <actions>Actions</actions>
71
+ <conditions>Conditions</conditions>
72
+ <is_rss>Is RSS?</is_rss>
73
+ <discount_qty>Discount Quantity</discount_qty>
74
+ <discount_step>Discount Step</discount_step>
75
+ <apply_to_shipping>Apply to Shipping?</apply_to_shipping>
76
+ <simple_free_shipping>Simple free shipping?</simple_free_shipping>
77
+ <stop_rules_processing>Stop rules processing?</stop_rules_processing>
78
+ <store_labels>Store labels</store_labels>
79
+ <product_ids>Product IDs</product_ids>
80
+ <use_auto_generation>Use Auto Generation</use_auto_generation>
81
+ </attributes>
82
+ <routes>
83
+ <route_entity>
84
+ <route>/loyaltylion/rules/:rule_id</route>
85
+ <action_type>entity</action_type>
86
+ </route_entity>
87
+ <route_collection>
88
+ <route>/loyaltylion/rules</route>
89
+ <action_type>collection</action_type>
90
+ </route_collection>
91
+ </routes>
92
+ <versions>1</versions>
93
+ </couponimport_pricerule>
94
+ </resources>
95
+ </api2>
96
+ </config>
app/code/local/LoyaltyLion/CouponImport/etc/config.xml ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <LoyaltyLion_CouponImport>
5
+ <version>0.1.1</version>
6
+ </LoyaltyLion_CouponImport>
7
+ </modules>
8
+ <global>
9
+ <models>
10
+ <couponimport>
11
+ <class>LoyaltyLion_CouponImport_Model</class>
12
+ </couponimport>
13
+ </models>
14
+ <blocks>
15
+ <couponimport>
16
+ <class>LoyaltyLion_CouponImport_Block</class>
17
+ </couponimport>
18
+ </blocks>
19
+ </global>
20
+ <admin>
21
+ <routers>
22
+ <adminhtml>
23
+ <args>
24
+ <modules>
25
+ <LoyaltyLion_CouponImport after="Mage_Adminhtml">LoyaltyLion_CouponImport_Adminhtml</LoyaltyLion_CouponImport>
26
+ </modules>
27
+ </args>
28
+ </adminhtml>
29
+ </routers>
30
+ </admin>
31
+ </config>
app/design/adminhtml/default/default/template/loyaltylion/system/config/button.phtml ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <script type="text/javascript">
2
+ //<![CDATA[
3
+ function doSetup() {
4
+ button = $('loyaltylion_setup_button');
5
+ token = $('loyaltylion_configuration_loyaltylion_token').value
6
+ secret = $('loyaltylion_configuration_loyaltylion_secret').value
7
+ new Ajax.Request('<?php echo $this->getAjaxSetupUrl() ?>', {
8
+ method: 'get',
9
+ parameters: { 'token':token, 'secret': secret },
10
+ onSuccess: function(transport){
11
+ switch (transport.responseText) {
12
+ case "ok":
13
+ button.removeClassName('fail').addClassName('success');
14
+ button.update("Success");
15
+ break;
16
+ case "not-configured-yet":
17
+ button.removeClassName('fail').removeClassName('success');
18
+ button.update("Please enter your Token / Secret first");
19
+ break;
20
+ default:
21
+ button.removeClassName('success').addClassName('fail');
22
+ button.update("Error - are you sure you entered the right Token / Secret?");
23
+ }
24
+ },
25
+ onError: function(transport){
26
+ button.removeClassName('success').addClassName('fail');
27
+ button.update("Error");
28
+ }
29
+ });
30
+ }
31
+ //]]>
32
+ </script>
33
+
34
+ <?php echo $this->getButtonHtml() ?>
app/design/frontend/base/default/layout/loyaltylion.xml ADDED
@@ -0,0 +1,8 @@
 
 
 
 
 
 
 
 
1
+ <?xml version='1.0'?>
2
+ <layout version='0.0.1'>
3
+ <default>
4
+ <reference name='head'>
5
+ <block type='loyaltylion/sdk' name='loyaltylion_sdk' template='loyaltylion/core/sdk.phtml' />
6
+ </reference>
7
+ </default>
8
+ </layout>
app/design/frontend/base/default/template/loyaltylion/core/sdk.phtml ADDED
@@ -0,0 +1,15 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php if ($this->isEnabled()): ?>
2
+ <script>(function(t,e){window.lion=e;var n,i=t.getElementsByTagName("script")[0];n=t.createElement("script"),n.type="text/javascript",n.async=!0,n.src="//<?php echo $this->getSDKUrl() ?>",i.parentNode.insertBefore(n,i),e.init=function(n){function i(t,e){var n=e.split(".");2===n.length&&(t=t[n[0]],e=n[1]),t[e]=function(){t.push([e].concat(Array.prototype.slice.call(arguments,0)))}}var r,o=t.getElementsByTagName("script")[0];r=t.createElement("script"),r.type="text/javascript",r.async=!0,r.src="//<?php echo $this->getPlatformHost() ?>/sdk/configuration/"+n+".js",o.parentNode.insertBefore(r,o),e.ui=e.ui||[];for(var a="_push configure track_pageview identify_customer auth_customer identify_product on off ui.refresh".split(" "),c=0;a.length>c;c++)i(e,a[c]);e._token=n}})(document,window.lion||[]);
3
+
4
+ lion.init("<?php echo $this->getToken() ?>"); lion.configure({ platform: 'magento' });
5
+ <?php if (Mage::getSingleton('customer/session')->isLoggedIn()): ?>
6
+ <?php
7
+ $customer = Mage::getSingleton('customer/session')->getCustomer();
8
+ $now = date('c');
9
+ $auth_src = $customer->getId() . $now . $this->getSecret();
10
+ ?>
11
+ lion.identify_customer({ id: "<?php echo $customer->getId() ?>", email: "<?php echo $customer->getEmail() ?>", name: "<?php echo $customer->getName() ?>" });
12
+ lion.auth_customer({ date: "<?php echo $now ?>", auth_token: "<?php echo sha1($auth_src) ?>" });
13
+ <?php endif ?>
14
+ </script>
15
+ <?php endif ?>
app/etc/modules/LoyaltyLion_Core.xml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version='1.0' encoding='UTF-8' ?>
2
+ <config>
3
+ <modules>
4
+ <LoyaltyLion_Core>
5
+ <active>true</active>
6
+ <codePool>local</codePool>
7
+ </LoyaltyLion_Core>
8
+ </modules>
9
+ </config>
app/etc/modules/LoyaltyLion_CouponImport.xml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <LoyaltyLion_CouponImport>
5
+ <active>true</active>
6
+ <codePool>local</codePool>
7
+ </LoyaltyLion_CouponImport>
8
+ </modules>
9
+ </config>
package.xml ADDED
@@ -0,0 +1,18 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>LoyaltyLion</name>
4
+ <version>1.1.2</version>
5
+ <stability>stable</stability>
6
+ <license>MIT</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>Use LoyaltyLion to add your own loyalty program in minutes and gain valuable customer insights. </summary>
10
+ <description>Increase activity and customer happiness by offering points for signups, purchases, visits and referrals. Your customers will collect points and redeem them for rewards to use at your store, which encourages repeat visits and long term loyalty.</description>
11
+ <notes>This release improves the configuration process.</notes>
12
+ <authors><author><name>Dave Clark</name><user>clarkdave_ll</user><email>dave@loyaltylion.com</email></author><author><name>Patrick Molgaard</name><user>draaglom</user><email>patrick@loyaltylion.com</email></author></authors>
13
+ <date>2015-12-29</date>
14
+ <time>16:55:53</time>
15
+ <contents><target name="magelocal"><dir name="LoyaltyLion"><dir name="Core"><dir name="Block"><file name="Sdk.php" hash="0f1269720db26f76acf791b3e944567b"/></dir><dir name="Helper"><file name="Data.php" hash="3ac59332d4eb3469869d84a07f949d17"/></dir><dir name="Model"><file name="Observer.php" hash="339cc2da60b70b8a81823a76709b1343"/></dir><dir name="etc"><file name="config.xml" hash="13edb1a712803c4bce2a63124f7bb76e"/><file name="system.xml" hash="d9f693debd08ea703404cb3e0d4dec1d"/></dir><dir name="lib"><dir name="loyaltylion-client"><dir name="lib"><file name="connection.php" hash="56f73205995ca0925a1b4cb6b2deb56c"/></dir><file name="main.php" hash="e8646ebd8aabb904b5163fc2a04f7e30"/></dir></dir></dir><dir name="CouponImport"><dir name="Block"><dir name="Adminhtml"><file name="Button.php" hash="3fe32ef718f21cdbed71bd023158960a"/></dir></dir><dir name="Model"><dir name="Api2"><dir name="Coupon"><dir name="Rest"><dir name="Admin"><file name="V1.php" hash="ed9a42c0d8945b69c7dc3436609911d1"/></dir></dir></dir><file name="Coupon.php" hash="bbaf6c59b4b132eb54a72e0688f3fab1"/><dir name="PriceRule"><dir name="Rest"><dir name="Admin"><file name="V1.php" hash="72c2f66b0de2996a612c7509cbbd82f2"/></dir></dir></dir><file name="PriceRule.php" hash="4b8d85f224fd5f121727977066c50cd1"/></dir></dir><dir name="controllers"><dir name="Adminhtml"><file name="QuickSetupController.php" hash="b27c4245cc9ad906b42befeb96f58814"/></dir></dir><dir name="etc"><file name="api2.xml" hash="e8ec47daccbb43584239fe3aeac9c122"/><file name="config.xml" hash="1e88c72e11bee8311e26c581ea858da5"/></dir></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="template"><dir name="loyaltylion"><dir name="core"><file name="sdk.phtml" hash="5e159702c28c50236887eb31b488539a"/></dir></dir></dir><dir name="layout"><file name="loyaltylion.xml" hash="f2c14ac8327d4eea6d8da6dfd61ede4c"/></dir></dir></dir></dir><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="template"><dir name="loyaltylion"><dir><dir name="system"><dir name="config"><file name="button.phtml" hash="1a41889f5d0159be59eedb32fb8beb77"/></dir></dir></dir></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="LoyaltyLion_Core.xml" hash="33446455fb634c28776a0fe45095a459"/><file name="LoyaltyLion_CouponImport.xml" hash="ff6ba2c149886ab7ee7de418619bb734"/></dir></target></contents>
16
+ <compatible/>
17
+ <dependencies><required><php><min>5.3.0</min><max>7.0.0</max></php></required></dependencies>
18
+ </package>