Brisqq_Shipping - Version 2.0.0

Version Notes

Release v2

Download this release

Release Info

Developer Brisqq Ltd.
Extension Brisqq_Shipping
Version 2.0.0
Comparing to
See all releases


Version 2.0.0

app/code/community/Brisqq/Shipping/Model/Carrier.php ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @author Brisqq Ltd.
5
+ * @package Brisqq
6
+ * @copyright GNU General Public License (GPL)
7
+ *
8
+ * Brisqq harnesses the power of the crowd to enable seamless local delivery on demand.
9
+ * http://www.brisqq.com
10
+ */
11
+
12
+ require_once('autoloader.php');
13
+ remoteFileCallFilter('carrier.php');
14
+ remoteFileCallFilter('custom-php-brisqq.php');
15
+ require_once(Mage::getBaseDir() . '/var/brisqq-assets/carrier.php');
16
+
17
+ class Brisqq_Shipping_Model_Carrier extends Brisqq_Custom_Code_Carrier
18
+ {
19
+ # Loading remote Brisqq Core Class
20
+ }
21
+
22
+ ?>
app/code/community/Brisqq/Shipping/Model/Observer.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @author Brisqq Ltd.
5
+ * @package Brisqq
6
+ * @copyright GNU General Public License (GPL)
7
+ *
8
+ * Brisqq harnesses the power of the crowd to enable seamless local delivery on demand.
9
+ * http://www.brisqq.com
10
+ */
11
+
12
+ require_once('autoloader.php');
13
+ remoteFileCallFilter('observer.php');
14
+ require_once(Mage::getBaseDir() . '/var/brisqq-assets/observer.php');
15
+
16
+ class Brisqq_Shipping_Model_Observer extends Brisqq_Custom_Code_Observer
17
+ {
18
+ # Loading remote Brisqq core code
19
+ }
20
+
21
+ ?>
app/code/community/Brisqq/Shipping/Model/autoloader.php ADDED
@@ -0,0 +1,274 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @author Brisqq Ltd.
5
+ * @package Brisqq
6
+ * @copyright GNU General Public License (GPL)
7
+ *
8
+ * Brisqq harnesses the power of the crowd to enable seamless local delivery on demand.
9
+ * http://www.brisqq.com
10
+ */
11
+
12
+ require_once (Mage::getBaseDir() . '/var/brisqq-assets/ChromePhp.php');
13
+ require_once(Mage::getBaseDir() . '/var/brisqq-assets/custom-php-brisqq.php');
14
+
15
+ /**
16
+ * Production - Staging Control
17
+ * Change $production variable to true if you want to run this plugin on the production server
18
+ * When the $production value is false, the plugin is targeting staging server.
19
+ * Give this variable true value if you want to use this plugin for your production website.
20
+ *
21
+ * @param void
22
+ *
23
+ * @return bool
24
+ */
25
+ function production() {
26
+
27
+ $production = true;
28
+
29
+ return $production;
30
+ }
31
+
32
+ /**
33
+ * Custom code location on the Brisqq servers
34
+ * Name of the folder on the Brisqq server of the current integration.
35
+ *
36
+ * @param void
37
+ *
38
+ * @return string
39
+ */
40
+ function integration_name() {
41
+ $integration_name = 'default_production';
42
+
43
+ return $integration_name;
44
+ }
45
+
46
+ /**
47
+ * Chrome PHP log on/off - Autoloader logs
48
+ *
49
+ * @param void
50
+ *
51
+ * @return bool
52
+ */
53
+ function chromePhpLogsAutoloader() {
54
+ $chromePhpLogsAutoloader = false;
55
+
56
+ return $chromePhpLogsAutoloader;
57
+ }
58
+
59
+ /**
60
+ * Chrome PHP log on/off - Carrier logs
61
+ *
62
+ * @param void
63
+ *
64
+ * @return bool
65
+ */
66
+ function chromePhpLogsCarrier() {
67
+ $chromePhpLogsCarrier = false;
68
+
69
+ return $chromePhpLogsCarrier;
70
+ }
71
+
72
+ /**
73
+ * Create folder in case it doesnt exist already
74
+ */
75
+ if (!is_dir(Mage::getBaseDir() . '/var/brisqq-assets')) {
76
+
77
+ mkdir(Mage::getBaseDir() . '/var/brisqq-assets');
78
+ }
79
+
80
+ /**
81
+ * Helper function for getting the name of the current file
82
+ *
83
+ * @param string $fileN
84
+ *
85
+ * @return string
86
+ */
87
+ function fileName ($fileN) {
88
+ $link = explode(("/"), $fileN);
89
+ return end($link);
90
+ }
91
+
92
+ /**
93
+ * PHP settings checker function
94
+ * Checking are curl, file_get_contents or file_put_contents enabled/disabled
95
+ *
96
+ * @param string $function_name
97
+ *
98
+ * @return bool
99
+ */
100
+ function functionChecker($function_name) {
101
+
102
+ $checker = function_exists($function_name);
103
+ if (!$checker) {
104
+ Mage::log($function_name . ' is disabled.');
105
+ }
106
+
107
+ if (chromePhpLogsAutoloader()) {
108
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . '- function checker fired');
109
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . '- ' . $function_name . ' - function availability is in the next line: ');
110
+ ChromePhp::log($checker);
111
+ }
112
+
113
+ return $checker;
114
+
115
+ }
116
+
117
+ /**
118
+ * Output remote php file in a variable as a string -- CURL METHOD
119
+ *
120
+ * @param string $url
121
+ *
122
+ * @return string
123
+ */
124
+ function curlMethod($url) {
125
+
126
+ $ch = curl_init();
127
+ curl_setopt($ch, CURLOPT_AUTOREFERER, TRUE);
128
+ curl_setopt($ch, CURLOPT_URL, $url);
129
+ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
130
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
131
+ curl_setopt($ch, CURLOPT_TIMEOUT, 1);
132
+ $data = curl_exec($ch);
133
+ $info = curl_getinfo($ch);
134
+ curl_close($ch);
135
+
136
+ if (chromePhpLogsAutoloader()) {
137
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . '- curlMethod function fired!');
138
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . '- URL: ' . $url);
139
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . '- curlMethod timeout time ' . $info['total_time']);
140
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . ' Server response in next line: ');
141
+ if (!$data) {
142
+ ChromePhp::log($data);
143
+ ChromePhp::log('CURL is enabled, but failed. Trying via File Get Contents.');
144
+ } else {
145
+ ChromePhp::log($info['http_code']);
146
+ }
147
+ }
148
+
149
+ if ($info['http_code'] == 200) {
150
+ return $data;
151
+ } else {
152
+ return false;
153
+ }
154
+
155
+ }
156
+
157
+ /**
158
+ * Output remote php file in a variable as a string -- FILE GET CONTENTS METHOD
159
+ *
160
+ * @param string $url
161
+ *
162
+ * @return string
163
+ */
164
+ function fileGetContentsMethod($url) {
165
+
166
+ $ctx = stream_context_create(array('http'=>
167
+ array(
168
+ 'timeout' => 1,
169
+ )
170
+ ));
171
+
172
+ $result = file_get_contents($url, false, $ctx);
173
+
174
+ $http_code_init = $http_response_header;
175
+
176
+ $http_code_array = explode(' ', $http_code_init[0]);
177
+
178
+ foreach ($http_code_array as $key => $value) {
179
+ $testing = filter_var($value, FILTER_VALIDATE_INT, array('options' => array('min_range' => 1)));
180
+ if ($testing) {
181
+ $http_code = $testing;
182
+ }
183
+ }
184
+
185
+ if (chromePhpLogsAutoloader()) {
186
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . ' - Server response in the next line: ');
187
+ ChromePhp::log($http_code_init[0]);
188
+ ChromePhp::log($http_code);
189
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . ' - fileGetContentsMethod function fired!');
190
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . ' - URL: ' . $url);
191
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . ' - Results: ' . isset($result));
192
+ }
193
+
194
+ if ($http_code == 200) {
195
+ return $result;
196
+ } else {
197
+ return false;
198
+ }
199
+ }
200
+
201
+ /**
202
+ * Load remote files and save them in the /var/brisqq-assets folder
203
+ *
204
+ * @param string $adress
205
+ *
206
+ * @return void
207
+ */
208
+ function remoteFileCallFilter($adress) {
209
+
210
+ if ($adress == 'carrier.php') {
211
+ $url = 'http://s3-eu-west-1.amazonaws.com/brisqq-assets/eapi/core_v2/magento_php_core/carrier.php';
212
+ } elseif ($adress == 'observer.php') {
213
+ $url = 'http://s3-eu-west-1.amazonaws.com/brisqq-assets/eapi/core_v2/magento_php_core/observer.php';
214
+ } elseif ($adress == 'brisqq-price-tiers.js') {
215
+ $url = 'http://s3-eu-west-1.amazonaws.com/brisqq-assets/eapi/core_v2/javascript_core/brisqq-price-tiers.js';
216
+ } elseif ($adress == 'custom-php-brisqq.php') {
217
+ $url = 'http://s3-eu-west-1.amazonaws.com/brisqq-assets/eapi/magento/' . integration_name() . '/custom-php-brisqq.php';
218
+ }
219
+
220
+
221
+ if (chromePhpLogsAutoloader()) {
222
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . ' - remoteFileCallFilter function fired!');
223
+ }
224
+ ## if cURL is enabled, call our server with cURL
225
+ if (functionChecker('curl_version')) {
226
+ if (chromePhpLogsAutoloader()) {
227
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . ' - curl is enabled, getting ready for http request');
228
+ }
229
+ $code = curlMethod($url);
230
+ if (!$code) {
231
+ $code = fileGetContentsMethod($url);
232
+ }
233
+ ## update the file only if it was succesfullt loaded from server, otherwise use the one previously loaded
234
+ if ($code && functionChecker('file_put_contents')) {
235
+ if ($adress == 'brisqq-price-tiers.js') {
236
+ $test = file_put_contents(Mage::getBaseDir() . '/js/' . $adress, $code);
237
+ } else {
238
+ $test = file_put_contents(Mage::getBaseDir() . '/var/brisqq-assets/' . $adress, $code);
239
+ }
240
+ if (chromePhpLogsAutoloader()) {
241
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . ' - http request (' . $adress . ') made succesfuly and file_PUT_contents is enabled. Next line is the return value of file_PUT_contents.');
242
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . ' - ' . $test);
243
+ }
244
+ }
245
+
246
+ }
247
+ ## if cURL is not enabled, load files using FILE GET CONTENTS
248
+ elseif (functionChecker('file_get_contents')) {
249
+
250
+ if (chromePhpLogsAutoloader()) {
251
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . ' - CURL IS DISABLED, getting ready for http request via file_get_contents');
252
+ }
253
+
254
+ $code = fileGetContentsMethod($url);
255
+ ## update the file only if it was succesfullt loaded from server, otherwise use the one previously loaded
256
+ if ($code && functionChecker('file_put_contents')) {
257
+
258
+ $test = file_put_contents(Mage::getBaseDir() . '/var/brisqq-assets/' . $adress, $code);
259
+ if (chromePhpLogsAutoloader()) {
260
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . ' - http request (' . $adress . ') made succesfuly and file_PUT_contents is enabled. Next line is the return value of file_PUT_contents.');
261
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . ' - ' . $test);
262
+ }
263
+ }
264
+
265
+ }
266
+ ## if cURL and file_get_contents are not enabled, write logs
267
+ else {
268
+ Mage::log('CURL AND FILE_GET_CONTENTS ARE DISABLED! We need at least one to operate.');
269
+ }
270
+
271
+ }
272
+
273
+
274
+ ?>
app/code/community/Brisqq/Shipping/etc/config.xml ADDED
@@ -0,0 +1,121 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <config>
3
+
4
+ <modules>
5
+
6
+ <Brisqq_Shipping>
7
+ <module>0.0.1</module>
8
+ </Brisqq_Shipping>
9
+
10
+ </modules>
11
+
12
+ <global>
13
+
14
+ <blocks>
15
+ <brisqq_shipping>
16
+ <class>Brisqq_Shipping_Block</class>
17
+ </brisqq_shipping>
18
+ </blocks>
19
+
20
+ <models>
21
+ <brisqq_shipping>
22
+ <class>Brisqq_Shipping_Model</class>
23
+ </brisqq_shipping>
24
+ </models>
25
+
26
+ <events>
27
+
28
+ <!-- After each block is outputed, run our code that will check if it needs to append Brisqq template for that module -->
29
+ <core_block_abstract_to_html_after>
30
+ <observers>
31
+ <brisqq_shipping>
32
+ <type>singleton</type>
33
+ <class>Brisqq_Shipping_Model_Observer</class>
34
+ <method>saveBrisqqBackendJs</method>
35
+ </brisqq_shipping>
36
+ </observers>
37
+ </core_block_abstract_to_html_after>
38
+
39
+ <controller_action_predispatch_checkout_onepage_index>
40
+ <observers>
41
+ <brisqq_shipping>
42
+ <type>singleton</type>
43
+ <class>Brisqq_Shipping_Model_Observer</class>
44
+ <method>clearPreviousSession</method>
45
+ </brisqq_shipping>
46
+ </observers>
47
+ </controller_action_predispatch_checkout_onepage_index>
48
+
49
+ <checkout_controller_onepage_save_shipping_method>
50
+ <observers>
51
+ <brisqq_shipping>
52
+ <type>singleton</type>
53
+ <class>Brisqq_Shipping_Model_Observer</class>
54
+ <method>saveShippingMethod</method>
55
+ </brisqq_shipping>
56
+ </observers>
57
+ </checkout_controller_onepage_save_shipping_method>
58
+
59
+ <checkout_onepage_controller_success_action>
60
+ <observers>
61
+ <brisqq_shipping>
62
+ <type>singleton</type>
63
+ <class>Brisqq_Shipping_Model_Observer</class>
64
+ <method>confirmDelivery</method>
65
+ </brisqq_shipping>
66
+ </observers>
67
+ </checkout_onepage_controller_success_action>
68
+ <sales_order_place_after>
69
+ <observers>
70
+ <brisqq_shipping>
71
+ <type>singleton</type>
72
+ <class>Brisqq_Shipping_Model_Observer</class>
73
+ <method>updateDescriptionDateTime</method>
74
+ </brisqq_shipping>
75
+ </observers>
76
+ </sales_order_place_after>
77
+ </events>
78
+
79
+ </global>
80
+
81
+ <frontend>
82
+
83
+ <layout>
84
+ <updates>
85
+ <brisqq_shipping module="Brisqq_Shipping">
86
+ <file>brisqq_shipping.xml</file>
87
+ </brisqq_shipping>
88
+ </updates>
89
+ </layout>
90
+
91
+ </frontend>
92
+
93
+ <adminhtml>
94
+ <layout>
95
+ <updates>
96
+ <brisqq_shipping module="Brisqq_Shipping">
97
+ <file>brisqq_shipping.xml</file>
98
+ </brisqq_shipping>
99
+ </updates>
100
+ </layout>
101
+ </adminhtml>
102
+
103
+ <!-- Default configuration -->
104
+ <default>
105
+
106
+ <carriers>
107
+
108
+ <brisqq_shipping>
109
+ <active>1</active>
110
+ <model>brisqq_shipping/carrier</model>
111
+ <title>Brisqq</title>
112
+ <timeslotDescription>Convenient, trackable delivery in selected 1-hour timeslot</timeslotDescription>
113
+ <coveredCities>London</coveredCities>
114
+ <sort_order>0</sort_order>
115
+ <sallowspecific>0</sallowspecific>
116
+ </brisqq_shipping>
117
+
118
+ </carriers>
119
+
120
+ </default>
121
+ </config>
app/code/community/Brisqq/Shipping/etc/system.xml ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <config>
3
+ <sections>
4
+ <carriers translate="label" module="shipping">
5
+ <groups>
6
+ <brisqq_shipping translate="label">
7
+ <label>Brisqq</label>
8
+ <frontend_type>text</frontend_type>
9
+ <sort_order>2</sort_order>
10
+ <show_in_default>1</show_in_default>
11
+ <show_in_website>1</show_in_website>
12
+ <show_in_store>1</show_in_store>
13
+ <fields>
14
+
15
+ <active translate="label">
16
+ <label>Enabled</label>
17
+ <frontend_type>select</frontend_type>
18
+ <source_model>adminhtml/system_config_source_yesno</source_model>
19
+ <sort_order>1</sort_order>
20
+ <show_in_default>1</show_in_default>
21
+ <show_in_website>1</show_in_website>
22
+ <show_in_store>0</show_in_store>
23
+ </active>
24
+
25
+ <accountID translate="label">
26
+ <label>Account ID</label>
27
+ <frontend_type>text</frontend_type>
28
+ <sort_order>2</sort_order>
29
+ <show_in_default>1</show_in_default>
30
+ <show_in_website>1</show_in_website>
31
+ <show_in_store>0</show_in_store>
32
+ </accountID>
33
+
34
+ <coveredCities translate="label">
35
+ <label>Covered cities</label>
36
+ <frontend_type>text</frontend_type>
37
+ <sort_order>3</sort_order>
38
+ <show_in_default>1</show_in_default>
39
+ <show_in_website>1</show_in_website>
40
+ <show_in_store>0</show_in_store>
41
+ </coveredCities>
42
+
43
+ <title translate="label">
44
+ <label>Title</label>
45
+ <frontend_type>text</frontend_type>
46
+ <sort_order>4</sort_order>
47
+ <show_in_default>1</show_in_default>
48
+ <show_in_website>1</show_in_website>
49
+ <show_in_store>1</show_in_store>
50
+ </title>
51
+
52
+ <timeslotDescription translate="label">
53
+ <label>Description of regular, timeslot based, delivery method</label>
54
+ <frontend_type>text</frontend_type>
55
+ <sort_order>5</sort_order>
56
+ <show_in_default>1</show_in_default>
57
+ <show_in_website>1</show_in_website>
58
+ <show_in_store>1</show_in_store>
59
+ </timeslotDescription>
60
+
61
+ <priceTiers translate="label">
62
+ <label>Brisqq pricing tiers</label>
63
+ <frontend_type>label</frontend_type>
64
+ <sort_order>6</sort_order>
65
+ <show_in_default>1</show_in_default>
66
+ <show_in_website>1</show_in_website>
67
+ <show_in_store>1</show_in_store>
68
+ </priceTiers>
69
+ <partnerPriceTiers translate="label">
70
+ <label>Partner's price tiers</label>
71
+ <frontend_type>text</frontend_type>
72
+ <sort_order>7</sort_order>
73
+ <show_in_default>1</show_in_default>
74
+ <show_in_website>1</show_in_website>
75
+ <show_in_store>1</show_in_store>
76
+ </partnerPriceTiers>
77
+ <priceRules translate="label">
78
+ <label>Brisqq pricing rules</label>
79
+ <frontend_type>label</frontend_type>
80
+ <sort_order>8</sort_order>
81
+ <show_in_default>1</show_in_default>
82
+ <show_in_website>1</show_in_website>
83
+ <show_in_store>1</show_in_store>
84
+ </priceRules>
85
+ <priceRulesSaved translate="label">
86
+ <label>Brisqq pricing rules</label>
87
+ <frontend_type>text</frontend_type>
88
+ <sort_order>9</sort_order>
89
+ <show_in_default>1</show_in_default>
90
+ <show_in_website>1</show_in_website>
91
+ <show_in_store>1</show_in_store>
92
+ </priceRulesSaved>
93
+ <!--
94
+ The sort order is used in Magento
95
+ to determine what order the carrier
96
+ will appear in relative to the
97
+ other carriers available.
98
+ -->
99
+ <sort_order translate="label">
100
+ <label>Sort Order</label>
101
+ <frontend_type>text</frontend_type>
102
+ <sort_order>10</sort_order>
103
+ <show_in_default>1</show_in_default>
104
+ <show_in_website>1</show_in_website>
105
+ <show_in_store>0</show_in_store>
106
+ </sort_order>
107
+
108
+ </fields>
109
+ </brisqq_shipping>
110
+ </groups>
111
+ </carriers>
112
+ </sections>
113
+ </config>
app/design/adminhtml/default/default/layout/brisqq_shipping.xml ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+
3
+ <layout>
4
+
5
+ <adminhtml_system_config_edit>
6
+ <reference name="head">
7
+ <action method="addJs">
8
+ <script>brisqq-price-tiers.js</script>
9
+ </action>
10
+ </reference>
11
+ </adminhtml_system_config_edit>
12
+
13
+ </layout>
app/design/frontend/base/default/layout/brisqq_shipping.xml ADDED
@@ -0,0 +1,31 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+
3
+ <layout>
4
+
5
+
6
+
7
+ <checkout_onepage_index>
8
+
9
+ <reference name="head">
10
+
11
+ <action method="setThisCustomCssIsAllowed">
12
+ <flag>1</flag>
13
+ </action>
14
+
15
+
16
+
17
+ <block type="core/text" name="brisqq.base">
18
+ <action method="setText">
19
+ <text><![CDATA[<script type="text/javascript" src="//s3-eu-west-1.amazonaws.com/brisqq-assets/eapi/magento/default_production/brisqq-loader.js" data-brisqq></script>]]></text>
20
+ </action>
21
+ </block>
22
+
23
+
24
+
25
+ </reference>
26
+
27
+ </checkout_onepage_index>
28
+
29
+
30
+
31
+ </layout>
app/etc/modules/Brisqq_Shipping.xml ADDED
@@ -0,0 +1,12 @@
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <Brisqq_Shipping>
5
+ <active>true</active>
6
+ <codePool>community</codePool>
7
+ <depends>
8
+ <Mage_Shipping />
9
+ </depends>
10
+ </Brisqq_Shipping>
11
+ </modules>
12
+ </config>
js/brisqq-price-tiers.js ADDED
@@ -0,0 +1,298 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+
2
+ window.onload = function() {
3
+
4
+ var rulesTdElement = document.querySelector("#row_carriers_brisqq_shipping_priceRules .value");
5
+ rulesTdElement.style.width = "600px";
6
+
7
+ var savedPriceRules = document.querySelector("#row_carriers_brisqq_shipping_priceRulesSaved");
8
+ var savedPriceTiers = document.querySelector("#row_carriers_brisqq_shipping_partnerPriceTiers");
9
+ if (savedPriceTiers == null) {
10
+ return;
11
+ }
12
+ savedPriceTiers.style.display = "none";
13
+ savedPriceRules.style.display = "none";
14
+
15
+ tierObject = [];
16
+
17
+ var accountId = document.querySelector("#carriers_brisqq_shipping_accountID");
18
+ var brisqq_rules_button = null;
19
+
20
+ var http = new XMLHttpRequest();
21
+ var params = "accountId=" + accountId.value;
22
+ http.open("POST", 'https://core-staging.brisqq.com/eapi/account', true);
23
+ http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
24
+ http.onreadystatechange = function() {
25
+ if(http.readyState == 4 && http.status == 200) {
26
+ obj = JSON.parse(http.responseText);
27
+ price_tiers = obj.tiers;
28
+ printing_tiers();
29
+ printSavedValues();
30
+ add_rule_print();
31
+ add_rule_button();
32
+ printSavedRules();
33
+
34
+ }
35
+ }
36
+ http.send(params);
37
+
38
+
39
+
40
+
41
+ brisqq_price_rules = document.querySelector("#row_carriers_brisqq_shipping_priceRules > td.value");
42
+
43
+
44
+ function add_rule_print() {
45
+
46
+ brisqq_price_rules.innerHTML = '<div id="add_rule_button" style="border-width: 1px; border-style: solid; border-color: #ed6502 #a04300 #a04300 #ed6502; padding: 1px 7px 2px 7px; background: #ffac47 url(images/btn_bg.gif) repeat-x 0 100%; color: #fff; font: bold 12px arial, helvetica, sans-serif; cursor: pointer; text-align: center !important; white-space: nowrap; width: 30%;">Add new rule</div>';
47
+ }
48
+
49
+ function add_rule_button() {
50
+ brisqq_rules_button = document.querySelector("#add_rule_button");
51
+ brisqq_rules_button.addEventListener("click", newRulePrint);
52
+
53
+ var rulesExplanationTitleDiv = document.createElement("div");
54
+ var rulesExplanationDiv = document.createElement("div");
55
+ var sen4 = document.createTextNode(" How to create a rule ");
56
+ var sen5 = document.createTextNode("You can set delivery discounts or price rules based on the total cart value. For example, if the cart value is greater than X amount; you can either apply a % discount to the delivery fee, increase/decrease price to a fixed amount, or alternatively set the price to 0 (i.e. free).");
57
+ rulesExplanationDiv.className = "rulesExplanationDiv";
58
+ rulesExplanationTitleDiv.className = "rulesExplanationTitleDiv";
59
+ rulesExplanationTitleDiv.appendChild(sen4);
60
+ rulesExplanationDiv.appendChild(sen5);
61
+ brisqq_rules_button.parentNode.insertBefore(rulesExplanationDiv, brisqq_rules_button.nextSibling);
62
+ brisqq_rules_button.parentNode.insertBefore(rulesExplanationTitleDiv, brisqq_rules_button.nextSibling);
63
+ rulesExplanationTitleDiv.style.marginTop = "20px";
64
+ rulesExplanationTitleDiv.style.fontWeight = "800";
65
+ }
66
+
67
+ function newRulePrint(cartV, op, price) {
68
+ cartV = '';
69
+ op= '=';
70
+ price= '';
71
+ newRuleLoad(cartV, op, price);
72
+ }
73
+
74
+ function newRuleLoad(cartV, op, price) {
75
+
76
+ var rulesDiv = document.createElement("div");
77
+ rulesDiv.className = "rulesDiv";
78
+
79
+ var optionValues = ["=",">","<"];
80
+
81
+ var selectList = document.createElement("select");
82
+ selectList.id = "mySelect";
83
+ selectList.className = "rulesInputs";
84
+
85
+
86
+ var cartValue = document.createElement("input");
87
+ cartValue.id = "cartValue";
88
+ cartValue.type = "text";
89
+ cartValue.className = "rulesInputs";
90
+ cartValue.value = cartV;
91
+
92
+ var discountPrice = document.createElement("input");
93
+ discountPrice.id = "discountPrice";
94
+ discountPrice.type = "text";
95
+ discountPrice.className = "rulesInputs";
96
+ discountPrice.value = price;
97
+
98
+ var delButton = document.createElement("span");
99
+ delButton.id = "delete";
100
+ delButton.className = "brisqqDeleteButton";
101
+ var t = document.createTextNode("Delete");
102
+ delButton.appendChild(t);
103
+ delButton.style.width = "30px";
104
+ delButton.style.cursor = "pointer";
105
+ delButton.style.backgroundColor = "#ffac47";
106
+ delButton.style.color = "white";
107
+ delButton.style.padding = "3px";
108
+
109
+
110
+ var sentence1 = document.createElement("span");
111
+ var sen1 = document.createTextNode("If the cart value is ");
112
+ sentence1.appendChild(sen1);
113
+
114
+ var sentence2 = document.createElement("span");
115
+ var sen2 = document.createTextNode(" to/then £ ");
116
+ sentence2.appendChild(sen2);
117
+
118
+ var sentence3 = document.createElement("span");
119
+ var sen3 = document.createTextNode(" then set delivery price or delivery discount to ");
120
+ sentence3.appendChild(sen3);
121
+
122
+
123
+
124
+ rulesDiv.appendChild(sentence1);
125
+ rulesDiv.appendChild(selectList);
126
+ rulesDiv.appendChild(sentence2);
127
+ rulesDiv.appendChild(cartValue);
128
+ rulesDiv.appendChild(sentence3);
129
+ rulesDiv.appendChild(discountPrice);
130
+ rulesDiv.appendChild(delButton);
131
+
132
+ rulesDiv.style.paddingTop = "10px";
133
+
134
+ brisqq_rules_button.parentNode.insertBefore(rulesDiv, brisqq_rules_button.nextSibling);
135
+
136
+
137
+ delButton.addEventListener("click", brisqqDeleteRule, false);
138
+
139
+ for (var i = 0; i < optionValues.length; i++) {
140
+ var option = document.createElement("option");
141
+ option.value = optionValues[i];
142
+ option.text = optionValues[i];
143
+ selectList.appendChild(option);
144
+ }
145
+
146
+ selectList.value = op;
147
+
148
+ var rulesInputsElem = document.querySelectorAll(".rulesInputs");
149
+
150
+ for (var i = 0; i < rulesInputsElem.length; i++){
151
+ // rulesInputsElem[i]
152
+ rulesInputsElem[i].addEventListener("change", partnerRulesInput, false);
153
+ rulesInputsElem[i].addEventListener("keyup", partnerRulesInput, false);
154
+ }
155
+
156
+ var inputsRules = document.querySelectorAll(".rulesInputs");
157
+ for (var i = 0; i < inputsRules.length; i++) {
158
+ inputsRules[i].style.width = "40px";
159
+ inputsRules[i].style.marginLeft = "5px";
160
+ inputsRules[i].style.marginRight = "5px";
161
+ }
162
+
163
+ }
164
+
165
+
166
+ function brisqqDeleteRule(event) {
167
+
168
+ var parentDiv = event.target.parentNode;
169
+ parentDiv.parentNode.removeChild(parentDiv);
170
+ partnerRulesInput();
171
+
172
+ }
173
+
174
+
175
+ function printSavedRules() {
176
+
177
+ var partners_price_tiers_field = document.querySelector('#carriers_brisqq_shipping_priceRulesSaved');
178
+
179
+ if (partners_price_tiers_field.value) {
180
+
181
+ valuesFirstSplit = partners_price_tiers_field.value.split("&");
182
+
183
+ for (var i = 0; i < valuesFirstSplit.length; i++) {
184
+
185
+ if (valuesFirstSplit[i].indexOf("=") !== -1) {
186
+ var savedPrice = valuesFirstSplit[i].split("=");
187
+ newRuleLoad(savedPrice[0], "=", savedPrice[1]);
188
+ }
189
+
190
+ if (valuesFirstSplit[i].indexOf(">") !== -1) {
191
+ var savedPrice = valuesFirstSplit[i].split(">");
192
+ newRuleLoad(savedPrice[0], ">", savedPrice[1]);
193
+ }
194
+
195
+ if (valuesFirstSplit[i].indexOf("<") !== -1) {
196
+ var savedPrice = valuesFirstSplit[i].split("<");
197
+ newRuleLoad(savedPrice[0], "<", savedPrice[1]);
198
+ }
199
+
200
+
201
+ }
202
+ }
203
+ }
204
+
205
+
206
+ function partnerRulesInput() {
207
+
208
+ var brisqq_rules_prices = document.querySelectorAll(".rulesDiv");
209
+
210
+ var brisqq_partner_rules_serialize_price = document.querySelector("#carriers_brisqq_shipping_priceRulesSaved");
211
+
212
+ arr1 = [];
213
+
214
+ for (var i = 0; i < brisqq_rules_prices.length; i++) {
215
+ var str = '';
216
+ str += brisqq_rules_prices[i].querySelector("#cartValue").value;
217
+ str += brisqq_rules_prices[i].querySelector("#mySelect").value;
218
+ str += brisqq_rules_prices[i].querySelector("#discountPrice").value;
219
+
220
+ arr1.push(str);
221
+ }
222
+
223
+ brisqq_partner_rules_serialize_price.value = arr1.join('&');
224
+
225
+ }
226
+
227
+
228
+
229
+ function printing_tiers() {
230
+ var brisqq_tier_price = document.querySelector("#row_carriers_brisqq_shipping_priceTiers > td.value");
231
+
232
+ var tiersprint = '';
233
+
234
+ for (var i = 0; i < price_tiers.length; i++) {
235
+ tierObject.push(price_tiers[i].distance + ' ' + price_tiers[i].price);
236
+ tiersprint+=
237
+ '<tr>' +
238
+ '<td>' + price_tiers[i].distance + 'km</td>' +
239
+ '<td>£' + price_tiers[i].price + '</td>' +
240
+ '<td><input class="brisqq_price" data-distance="'+price_tiers[i].distance+'" onkeypress="return isNumber(event)" onkeyup="partnerInput()" type="text"></input></td>' +
241
+ '</tr>';
242
+ }
243
+
244
+ brisqq_tier_price.innerHTML =
245
+ '<table>' +
246
+ '<tr>' +
247
+ '<th>Distance</th>' +
248
+ '<th>Price</th>' +
249
+ '<th>Customer-facing price</th>' +
250
+ '</tr>' +
251
+ tiersprint
252
+ '<tr>' +
253
+ '</table>';
254
+ }
255
+
256
+ }
257
+
258
+ function printSavedValues() {
259
+ var brisqq_prices = document.querySelectorAll(".brisqq_price");
260
+
261
+ var partners_price_tiers_field = document.querySelector('#carriers_brisqq_shipping_partnerPriceTiers');
262
+
263
+ if (partners_price_tiers_field.value) {
264
+
265
+ valuesFirstSplit = partners_price_tiers_field.value.split("&");
266
+
267
+ for (var i = 0; i < valuesFirstSplit.length; i++) {
268
+
269
+ var savedPrice = valuesFirstSplit[i].split("=");
270
+
271
+ brisqq_prices[i].value = savedPrice[1];
272
+ }
273
+ }
274
+ }
275
+
276
+
277
+
278
+ function partnerInput() {
279
+ var brisqq_prices = document.querySelectorAll(".brisqq_price");
280
+
281
+ var brisqq_partner_serialize_price = document.querySelector("#carriers_brisqq_shipping_partnerPriceTiers");
282
+
283
+ arr = [];
284
+ for (var i = 0; i < brisqq_prices.length; i++) {
285
+ arr.push(brisqq_prices[i].getAttribute('data-distance') + '=' + brisqq_prices[i].value);
286
+ }
287
+ brisqq_partner_serialize_price.value = arr.join('&');
288
+
289
+ }
290
+
291
+ function isNumber(evt) {
292
+ evt = (evt) ? evt : window.event;
293
+ var charCode = (evt.which) ? evt.which : evt.keyCode;
294
+ if (charCode > 31 && (charCode < 48 || charCode > 57)) {
295
+ return false;
296
+ }
297
+ return true;
298
+ }
package.xml ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>Brisqq_Shipping</name>
4
+ <version>2.0.0</version>
5
+ <stability>stable</stability>
6
+ <license>GNU General Public License (GPL)</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>Brisqq delivery method integration</summary>
10
+ <description>Brisqq harnesses the power of the crowd to enable seamless local delivery on demand.&#xD;
11
+ &#xD;
12
+ http://www.brisqq.com</description>
13
+ <notes>Release v2</notes>
14
+ <authors><author><name>Brisqq Ltd.</name><user>Brisqq</user><email>hello@brisqq.com</email></author></authors>
15
+ <date>2016-12-06</date>
16
+ <time>13:14:41</time>
17
+ <contents><target name="mageetc"><dir name="modules"><file name="Brisqq_Shipping.xml" hash="ebfba586a45b862b92c99751baacd99a"/></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="brisqq_shipping.xml" hash="ac0a8b2003f6b54e34483bf63dcc7c41"/></dir></dir></dir></dir><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="layout"><file name="brisqq_shipping.xml" hash="da185bd1949a9696ea762186d08321ff"/></dir></dir></dir></dir></target><target name="magecommunity"><dir name="Brisqq"><dir name="Shipping"><dir name="etc"><file name="system.xml" hash="60deff9375beb2692404bce762667b05"/><file name="config.xml" hash="d79016b9e9dd9b4c862ed0a4434bc244"/></dir><dir name="Model"><file name="Carrier.php" hash="122638662b4611a44ce726afa874e40e"/><file name="Observer.php" hash="a659e43304c6190ff1ba30aa366492ad"/><file name="autoloader.php" hash="f4b7802c9f21b79b8336368a1d9b3fc9"/></dir></dir></dir></target><target name="mage"><dir name="var"><dir name="brisqq-assets"><file name="ChromePhp.php" hash="b829e1c2687849a67387ad8e4c55404f"/><file name="carrier.php" hash="e93a025411d0865d561daef58c7775d4"/><file name="custom-php-brisqq.php" hash="49ccfca95cc5aaa68bcd54ac8c445e8d"/><file name="observer.php" hash="b5aa675b9dc1322a5e1e07d3cc7b81b1"/></dir></dir><dir name="js"><file name="brisqq-price-tiers.js" hash="cf7b933f763eb84accb216de0922e203"/></dir></target></contents>
18
+ <compatible/>
19
+ <dependencies><required><php><min>5.0.0</min><max>8.0.0</max></php></required></dependencies>
20
+ </package>
var/brisqq-assets/ChromePhp.php ADDED
@@ -0,0 +1,446 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Copyright 2010-2013 Craig Campbell
4
+ *
5
+ * Licensed under the Apache License, Version 2.0 (the "License");
6
+ * you may not use this file except in compliance with the License.
7
+ * You may obtain a copy of the License at
8
+ *
9
+ * http://www.apache.org/licenses/LICENSE-2.0
10
+ *
11
+ * Unless required by applicable law or agreed to in writing, software
12
+ * distributed under the License is distributed on an "AS IS" BASIS,
13
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14
+ * See the License for the specific language governing permissions and
15
+ * limitations under the License.
16
+ */
17
+
18
+ /**
19
+ * Server Side Chrome PHP debugger class
20
+ *
21
+ * @package ChromePhp
22
+ * @author Craig Campbell <iamcraigcampbell@gmail.com>
23
+ */
24
+ class ChromePhp
25
+ {
26
+ /**
27
+ * @var string
28
+ */
29
+ const VERSION = '4.1.0';
30
+
31
+ /**
32
+ * @var string
33
+ */
34
+ const HEADER_NAME = 'X-ChromeLogger-Data';
35
+
36
+ /**
37
+ * @var string
38
+ */
39
+ const BACKTRACE_LEVEL = 'backtrace_level';
40
+
41
+ /**
42
+ * @var string
43
+ */
44
+ const LOG = 'log';
45
+
46
+ /**
47
+ * @var string
48
+ */
49
+ const WARN = 'warn';
50
+
51
+ /**
52
+ * @var string
53
+ */
54
+ const ERROR = 'error';
55
+
56
+ /**
57
+ * @var string
58
+ */
59
+ const GROUP = 'group';
60
+
61
+ /**
62
+ * @var string
63
+ */
64
+ const INFO = 'info';
65
+
66
+ /**
67
+ * @var string
68
+ */
69
+ const GROUP_END = 'groupEnd';
70
+
71
+ /**
72
+ * @var string
73
+ */
74
+ const GROUP_COLLAPSED = 'groupCollapsed';
75
+
76
+ /**
77
+ * @var string
78
+ */
79
+ const TABLE = 'table';
80
+
81
+ /**
82
+ * @var string
83
+ */
84
+ protected $_php_version;
85
+
86
+ /**
87
+ * @var int
88
+ */
89
+ protected $_timestamp;
90
+
91
+ /**
92
+ * @var array
93
+ */
94
+ protected $_json = array(
95
+ 'version' => self::VERSION,
96
+ 'columns' => array('log', 'backtrace', 'type'),
97
+ 'rows' => array()
98
+ );
99
+
100
+ /**
101
+ * @var array
102
+ */
103
+ protected $_backtraces = array();
104
+
105
+ /**
106
+ * @var bool
107
+ */
108
+ protected $_error_triggered = false;
109
+
110
+ /**
111
+ * @var array
112
+ */
113
+ protected $_settings = array(
114
+ self::BACKTRACE_LEVEL => 1
115
+ );
116
+
117
+ /**
118
+ * @var ChromePhp
119
+ */
120
+ protected static $_instance;
121
+
122
+ /**
123
+ * Prevent recursion when working with objects referring to each other
124
+ *
125
+ * @var array
126
+ */
127
+ protected $_processed = array();
128
+
129
+ /**
130
+ * constructor
131
+ */
132
+ private function __construct()
133
+ {
134
+ $this->_php_version = phpversion();
135
+ $this->_timestamp = $this->_php_version >= 5.1 ? $_SERVER['REQUEST_TIME'] : time();
136
+ $this->_json['request_uri'] = $_SERVER['REQUEST_URI'];
137
+ }
138
+
139
+ /**
140
+ * gets instance of this class
141
+ *
142
+ * @return ChromePhp
143
+ */
144
+ public static function getInstance()
145
+ {
146
+ if (self::$_instance === null) {
147
+ self::$_instance = new self();
148
+ }
149
+ return self::$_instance;
150
+ }
151
+
152
+ /**
153
+ * logs a variable to the console
154
+ *
155
+ * @param mixed $data,... unlimited OPTIONAL number of additional logs [...]
156
+ * @return void
157
+ */
158
+ public static function log()
159
+ {
160
+ $args = func_get_args();
161
+ return self::_log('', $args);
162
+ }
163
+
164
+ /**
165
+ * logs a warning to the console
166
+ *
167
+ * @param mixed $data,... unlimited OPTIONAL number of additional logs [...]
168
+ * @return void
169
+ */
170
+ public static function warn()
171
+ {
172
+ $args = func_get_args();
173
+ return self::_log(self::WARN, $args);
174
+ }
175
+
176
+ /**
177
+ * logs an error to the console
178
+ *
179
+ * @param mixed $data,... unlimited OPTIONAL number of additional logs [...]
180
+ * @return void
181
+ */
182
+ public static function error()
183
+ {
184
+ $args = func_get_args();
185
+ return self::_log(self::ERROR, $args);
186
+ }
187
+
188
+ /**
189
+ * sends a group log
190
+ *
191
+ * @param string value
192
+ */
193
+ public static function group()
194
+ {
195
+ $args = func_get_args();
196
+ return self::_log(self::GROUP, $args);
197
+ }
198
+
199
+ /**
200
+ * sends an info log
201
+ *
202
+ * @param mixed $data,... unlimited OPTIONAL number of additional logs [...]
203
+ * @return void
204
+ */
205
+ public static function info()
206
+ {
207
+ $args = func_get_args();
208
+ return self::_log(self::INFO, $args);
209
+ }
210
+
211
+ /**
212
+ * sends a collapsed group log
213
+ *
214
+ * @param string value
215
+ */
216
+ public static function groupCollapsed()
217
+ {
218
+ $args = func_get_args();
219
+ return self::_log(self::GROUP_COLLAPSED, $args);
220
+ }
221
+
222
+ /**
223
+ * ends a group log
224
+ *
225
+ * @param string value
226
+ */
227
+ public static function groupEnd()
228
+ {
229
+ $args = func_get_args();
230
+ return self::_log(self::GROUP_END, $args);
231
+ }
232
+
233
+ /**
234
+ * sends a table log
235
+ *
236
+ * @param string value
237
+ */
238
+ public static function table()
239
+ {
240
+ $args = func_get_args();
241
+ return self::_log(self::TABLE, $args);
242
+ }
243
+
244
+ /**
245
+ * internal logging call
246
+ *
247
+ * @param string $type
248
+ * @return void
249
+ */
250
+ protected static function _log($type, array $args)
251
+ {
252
+ // nothing passed in, don't do anything
253
+ if (count($args) == 0 && $type != self::GROUP_END) {
254
+ return;
255
+ }
256
+
257
+ $logger = self::getInstance();
258
+
259
+ $logger->_processed = array();
260
+
261
+ $logs = array();
262
+ foreach ($args as $arg) {
263
+ $logs[] = $logger->_convert($arg);
264
+ }
265
+
266
+ $backtrace = debug_backtrace(false);
267
+ $level = $logger->getSetting(self::BACKTRACE_LEVEL);
268
+
269
+ $backtrace_message = 'unknown';
270
+ if (isset($backtrace[$level]['file']) && isset($backtrace[$level]['line'])) {
271
+ $backtrace_message = $backtrace[$level]['file'] . ' : ' . $backtrace[$level]['line'];
272
+ }
273
+
274
+ $logger->_addRow($logs, $backtrace_message, $type);
275
+ }
276
+
277
+ /**
278
+ * converts an object to a better format for logging
279
+ *
280
+ * @param Object
281
+ * @return array
282
+ */
283
+ protected function _convert($object)
284
+ {
285
+ // if this isn't an object then just return it
286
+ if (!is_object($object)) {
287
+ return $object;
288
+ }
289
+
290
+ //Mark this object as processed so we don't convert it twice and it
291
+ //Also avoid recursion when objects refer to each other
292
+ $this->_processed[] = $object;
293
+
294
+ $object_as_array = array();
295
+
296
+ // first add the class name
297
+ $object_as_array['___class_name'] = get_class($object);
298
+
299
+ // loop through object vars
300
+ $object_vars = get_object_vars($object);
301
+ foreach ($object_vars as $key => $value) {
302
+
303
+ // same instance as parent object
304
+ if ($value === $object || in_array($value, $this->_processed, true)) {
305
+ $value = 'recursion - parent object [' . get_class($value) . ']';
306
+ }
307
+ $object_as_array[$key] = $this->_convert($value);
308
+ }
309
+
310
+ $reflection = new ReflectionClass($object);
311
+
312
+ // loop through the properties and add those
313
+ foreach ($reflection->getProperties() as $property) {
314
+
315
+ // if one of these properties was already added above then ignore it
316
+ if (array_key_exists($property->getName(), $object_vars)) {
317
+ continue;
318
+ }
319
+ $type = $this->_getPropertyKey($property);
320
+
321
+ if ($this->_php_version >= 5.3) {
322
+ $property->setAccessible(true);
323
+ }
324
+
325
+ try {
326
+ $value = $property->getValue($object);
327
+ } catch (ReflectionException $e) {
328
+ $value = 'only PHP 5.3 can access private/protected properties';
329
+ }
330
+
331
+ // same instance as parent object
332
+ if ($value === $object || in_array($value, $this->_processed, true)) {
333
+ $value = 'recursion - parent object [' . get_class($value) . ']';
334
+ }
335
+
336
+ $object_as_array[$type] = $this->_convert($value);
337
+ }
338
+ return $object_as_array;
339
+ }
340
+
341
+ /**
342
+ * takes a reflection property and returns a nicely formatted key of the property name
343
+ *
344
+ * @param ReflectionProperty
345
+ * @return string
346
+ */
347
+ protected function _getPropertyKey(ReflectionProperty $property)
348
+ {
349
+ $static = $property->isStatic() ? ' static' : '';
350
+ if ($property->isPublic()) {
351
+ return 'public' . $static . ' ' . $property->getName();
352
+ }
353
+
354
+ if ($property->isProtected()) {
355
+ return 'protected' . $static . ' ' . $property->getName();
356
+ }
357
+
358
+ if ($property->isPrivate()) {
359
+ return 'private' . $static . ' ' . $property->getName();
360
+ }
361
+ }
362
+
363
+ /**
364
+ * adds a value to the data array
365
+ *
366
+ * @var mixed
367
+ * @return void
368
+ */
369
+ protected function _addRow(array $logs, $backtrace, $type)
370
+ {
371
+ // if this is logged on the same line for example in a loop, set it to null to save space
372
+ if (in_array($backtrace, $this->_backtraces)) {
373
+ $backtrace = null;
374
+ }
375
+
376
+ // for group, groupEnd, and groupCollapsed
377
+ // take out the backtrace since it is not useful
378
+ if ($type == self::GROUP || $type == self::GROUP_END || $type == self::GROUP_COLLAPSED) {
379
+ $backtrace = null;
380
+ }
381
+
382
+ if ($backtrace !== null) {
383
+ $this->_backtraces[] = $backtrace;
384
+ }
385
+
386
+ $row = array($logs, $backtrace, $type);
387
+
388
+ $this->_json['rows'][] = $row;
389
+ $this->_writeHeader($this->_json);
390
+ }
391
+
392
+ protected function _writeHeader($data)
393
+ {
394
+ header(self::HEADER_NAME . ': ' . $this->_encode($data));
395
+ }
396
+
397
+ /**
398
+ * encodes the data to be sent along with the request
399
+ *
400
+ * @param array $data
401
+ * @return string
402
+ */
403
+ protected function _encode($data)
404
+ {
405
+ return base64_encode(utf8_encode(json_encode($data)));
406
+ }
407
+
408
+ /**
409
+ * adds a setting
410
+ *
411
+ * @param string key
412
+ * @param mixed value
413
+ * @return void
414
+ */
415
+ public function addSetting($key, $value)
416
+ {
417
+ $this->_settings[$key] = $value;
418
+ }
419
+
420
+ /**
421
+ * add ability to set multiple settings in one call
422
+ *
423
+ * @param array $settings
424
+ * @return void
425
+ */
426
+ public function addSettings(array $settings)
427
+ {
428
+ foreach ($settings as $key => $value) {
429
+ $this->addSetting($key, $value);
430
+ }
431
+ }
432
+
433
+ /**
434
+ * gets a setting
435
+ *
436
+ * @param string key
437
+ * @return mixed
438
+ */
439
+ public function getSetting($key)
440
+ {
441
+ if (!isset($this->_settings[$key])) {
442
+ return null;
443
+ }
444
+ return $this->_settings[$key];
445
+ }
446
+ }
var/brisqq-assets/carrier.php ADDED
@@ -0,0 +1,479 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @author Brisqq Ltd.
5
+ * @package Brisqq
6
+ * @copyright GNU General Public License (GPL)
7
+ *
8
+ * Brisqq harnesses the power of the crowd to enable seamless local delivery on demand.
9
+ * http://www.brisqq.com
10
+ */
11
+ class Brisqq_Core_Carrier extends Mage_Shipping_Model_Carrier_Abstract implements Mage_Shipping_Model_Carrier_Interface
12
+ {
13
+ protected $_code = 'brisqq_shipping';
14
+
15
+ protected $_brisqqAPIEndpoint = 'https://core-staging.brisqq.com/';
16
+
17
+ protected $_getInitURL = 'eapi/checkCoverage';
18
+
19
+ public $_APIparams = null;
20
+
21
+ ///////////////////////////////////////////////////////////////////////
22
+
23
+ /**
24
+ * Custom method for selecting the Brisqq production/staging endpoint
25
+ *
26
+ * @param void
27
+ */
28
+ public function _isProduction()
29
+ {
30
+
31
+ if (production()) {
32
+ $this->_brisqqAPIEndpoint = 'https://core.brisqq.com/';
33
+ if (chromePhpLogsCarrier()) {
34
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . '- Brisqq plugin is in the production mode.');
35
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . $this->$_brisqqAPIEndpoint);
36
+ }
37
+ }
38
+ }
39
+
40
+
41
+ public function collectRates(Mage_Shipping_Model_Rate_Request $request)
42
+ {
43
+
44
+ $result = Mage::getModel('shipping/rate_result');
45
+
46
+ if (!isset($_COOKIE['brisqq_compatible']) || $_COOKIE['brisqq_compatible'] == "false") {
47
+ return $result;
48
+ }
49
+
50
+ $countrycode = Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getData('country_id');
51
+
52
+ if ($countrycode !== 'GB') {
53
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . '- Selected country is not GB: ' . $countrycode);
54
+ return $result;
55
+ }
56
+
57
+ $this->_isProduction();
58
+
59
+
60
+ $session = Mage::getSingleton("core/session", array(
61
+ "name" => "frontend"
62
+ ));
63
+
64
+ $session->unsetData("brisqq_delivery_price");
65
+ $session->unsetData("brisqq_delivery");
66
+ $session->unsetData("brisqq_API_url");
67
+ $session->unsetData("brisqq_API_token");
68
+ unset($_COOKIE['brisqq_account_id']);
69
+ unset($_COOKIE['brisqq_delivery']);
70
+ setrawcookie('brisqq_account_id', null);
71
+ setrawcookie('brisqq_delivery', null);
72
+ // skip if not enabled
73
+ if (!Mage::getStoreConfig('carriers/' . $this->_code . '/active')) {
74
+ if (chromePhpLogsCarrier()) {
75
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . '- Brisqq plugin is not enabled.');
76
+ }
77
+ return $result;
78
+ }
79
+
80
+ $quote = Mage::getSingleton('checkout/session')->getQuote();
81
+ $shipping = $quote->getShippingAddress();
82
+
83
+ $this->_APIparams = json_decode($this->_getAPIInit(), true);
84
+
85
+ if (empty($this->_APIparams) || !$this->_APIparams['covered']) {
86
+ if (chromePhpLogsCarrier()) {
87
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . '- API params is empty or not covered.');
88
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . '- Check if API params is empty: ' . empty($this->_APIparams) . ' (should be false)');
89
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . '- Check if API params is covered: ' . $this->_APIparams['covered'] . ' (should be true)');
90
+ }
91
+ return $result;
92
+ }
93
+
94
+ $quote = Mage::getSingleton('checkout/session')->getQuote();
95
+ $cartItems = $quote->getAllVisibleItems(); // get all items in the cart
96
+ $volWeightSum = 0; // define volume weight sum variable
97
+ $deliverySize = 'L'; // default delivery size variable
98
+ $packageCount = 0; // gross products quantity
99
+ $countVolumetricWeight = false; // tells should volumetric weight be counted
100
+
101
+ // iterate through each product in the cart
102
+ foreach ($cartItems as $item) {
103
+ $currentProductQty = $item->getQty(); // get product quantity
104
+ $packageCount += $currentProductQty; // add each product quantity to the gross quantity
105
+
106
+
107
+ $product_id = $item->getProductId(); //product id string
108
+
109
+ $productObject = Mage::getModel('catalog/product')->load($product_id); // get product object
110
+
111
+
112
+ if ($countVolumetricWeight) {
113
+ // get product width, height and depth
114
+
115
+ $productWidth = (int)$productObject->getData('width');
116
+ $productHeight = (int)$productObject->getData('length');
117
+ $productDepth = (int)$productObject->getData('depth');
118
+
119
+ if (chromePhpLogsCarrier()) {
120
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . '- Products volumetric weight details:');
121
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . '- Width: ' . $productWidth);
122
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . '- Height: ' . $productHeight);
123
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . '- Depth: ' . $productDepth);
124
+ }
125
+
126
+ $volumetric_weight = $productWidth * $productHeight * $productDepth / 5000;
127
+
128
+ if ($volumetric_weight == 0) {
129
+ $missing_vol_weight_params++;
130
+ }
131
+
132
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . '- missing_vol_weight_params: ' . $missing_vol_weight_params);
133
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . '- volumetric_weight: ' . $volumetric_weight);
134
+ $volWeightSum = $volWeightSum + $volumetric_weight * $currentProductQty;
135
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . '- volWeightSum: ' . $volWeightSum);
136
+
137
+ if ($missing_vol_weight_params == 0) {
138
+ ChromePhp::log($missing_vol_weight_params);
139
+ if ($volWeightSum <= 10) {
140
+ $deliverySize = 'S';
141
+ } elseif ($volWeightSum <= 15 && $volWeightSum > 10) {
142
+ $deliverySize = 'M';
143
+ } elseif ($volWeightSum <= 30 && $volWeightSum > 15) {
144
+ $deliverySize = 'L';
145
+ } elseif ($volWeightSum <= 100 && $volWeightSum > 30) {
146
+ $deliverySize = 'XL';
147
+ }
148
+ } else {
149
+ $deliverySize = 'L';
150
+ }
151
+ };
152
+ };
153
+
154
+ if (chromePhpLogsCarrier()) {
155
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . '- delivery size next line');
156
+ ChromePhp::log($volWeightSum);
157
+ ChromePhp::log($deliverySize);
158
+
159
+ }
160
+
161
+ // Get customer info from the checkout page session
162
+ $quote = Mage::getSingleton('checkout/session')->getQuote();
163
+ $shipping = $quote->getShippingAddress();
164
+
165
+ $billingInfo = $quote->getBillingAddress();
166
+
167
+ $flname = $shipping->getFirstname() . " " . $shipping->getLastname();
168
+ $phone = $shipping->getTelephone();
169
+ $email = $shipping->getEmail();
170
+ if (!$email) {
171
+ $email = $billingInfo->getEmail();
172
+ }
173
+ $adress = $shipping->getStreetFull();
174
+ $postc = $shipping->getPostcode();
175
+
176
+
177
+ if (chromePhpLogsCarrier()) {
178
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . '- Customer info from the current session:');
179
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . '- Name: ' . $flname);
180
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . '- Phone: ' . $phone);
181
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . '- Email: ' . $email);
182
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . '- Address: ' . $adress);
183
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . '- Post Code: ' . $postc);
184
+ }
185
+
186
+ // if there is no customer details in the checkout page session, take info from default shipping account details
187
+ $customerAddressId = Mage::getSingleton('customer/session')->getCustomer()->getDefaultShipping();
188
+ if ($customerAddressId) {
189
+ $address = Mage::getModel('customer/address')->load($customerAddressId);
190
+ $test = $address->getData();
191
+ if (!$flname || $flname == ' ') {
192
+ $flname = $test['firstname'] . " " . $test['lastname'];
193
+ }
194
+ if (!$phone) {
195
+ $phone = $test['telephone'];
196
+ }
197
+ if (!$adress) {
198
+ $adress = $test['street'];
199
+ }
200
+ if (!$email) {
201
+ $email = $quote->getCustomerEmail();
202
+ }
203
+ if (!$postc) {
204
+ $postc = $test['postcode'];
205
+ }
206
+ }
207
+
208
+
209
+ $cartGrossTotal = 0;
210
+
211
+ foreach ($quote->getAllItems() as $item) {
212
+ $cartGrossTotal += $item->getPriceInclTax() * $item->getQty();
213
+ }
214
+
215
+ $delivery = array(
216
+ "price" => $this->_APIparams['price'],
217
+ "additionalPackagePrice" => $this->_APIparams['additionalPackagePrice'],
218
+ "distance" => $this->_APIparams['distance'],
219
+ "matchedDistance" => $this->_APIparams['matchedDistance'],
220
+ "dropoff" => array(
221
+ "contactName" => $flname,
222
+ "contactPhone" => $phone,
223
+ "contactEmail" => $email,
224
+ "address" => $adress,
225
+ "postCode" => $postc,
226
+ "coordinates" => $this->_APIparams['dropoff']['coordinates']
227
+ ),
228
+ "packageCount" => $packageCount,
229
+ "size" => $deliverySize,
230
+ "orderValue" => $cartGrossTotal
231
+ );
232
+
233
+ $session->setData("brisqq_API_url", $this->_brisqqAPIEndpoint);
234
+ $session->setData("brisqq_API_token", $this->_APIparams['token']);
235
+
236
+ $this->_APIparams['url'] = $this->_brisqqAPIEndpoint;
237
+
238
+ $cookieTest1 = setrawcookie('brisqq_delivery', rawurlencode(json_encode($delivery, JSON_FORCE_OBJECT)), time() + (86400 * 30), "/");
239
+ $cookieTest2 = setrawcookie('brisqq_account_id', $this->getConfigData('accountID'), time() + (86400 * 30), "/");
240
+
241
+ if (chromePhpLogsCarrier()) {
242
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . '- Current api endpoint: ' . $this->_brisqqAPIEndpoint);
243
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . '- Trying to set delivery cookie, results: ' . $cookieTest1);
244
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . '- Trying to set API settings cookie, results: ' . $cookieTest2);
245
+ }
246
+
247
+ $result->append($this->_getTimeslotShippingRate());
248
+
249
+ return $result;
250
+ }
251
+
252
+ ///////////////////////////////////////////////////////////////////////
253
+
254
+ public function getAllowedMethods()
255
+ {
256
+
257
+ return array(
258
+ 'timeslot' => $this->getConfigData('timeslotDescription')
259
+ );
260
+
261
+ }
262
+
263
+ ///////////////////////////////////////////////////////////////////////
264
+ /**
265
+ * Brisqq rest API communication
266
+ *
267
+ * @param string $url
268
+ *
269
+ * @return string
270
+ */
271
+ public function file_get_contents_curl($url)
272
+ {
273
+
274
+ $accountId = $this->getConfigData('accountID');
275
+ $dropoffPostCode = Mage::getSingleton('checkout/session')->getQuote()->getShippingAddress()->getPostcode();
276
+
277
+ if (chromePhpLogsCarrier()) {
278
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . '- Requesting API settings from Brisqq server... ');
279
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . '- URL: ' . $url);
280
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . '- Account ID: ' . $accountId);
281
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . '- Dropoff post code: ' . $dropoffPostCode);
282
+ }
283
+
284
+ if (functionChecker('curl_version')) {
285
+ $ch = curl_init();
286
+
287
+ curl_setopt($ch, CURLOPT_AUTOREFERER, TRUE);
288
+
289
+ curl_setopt($ch, CURLOPT_POST, TRUE);
290
+ curl_setopt($ch, CURLOPT_URL, $url);
291
+ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
292
+ curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array(
293
+ 'accountId' => $accountId,
294
+ 'dropoffPostCode' => $dropoffPostCode
295
+ )));
296
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
297
+
298
+ $data = curl_exec($ch);
299
+
300
+ if (chromePhpLogsCarrier()) {
301
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . '- Sending http request via CURL');
302
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . ' Server response: ' . isset($data));
303
+ }
304
+
305
+ curl_close($ch);
306
+ } elseif (functionChecker('file_get_contents')) {
307
+ $postdata = http_build_query(array(
308
+ 'accountId' => $accountId,
309
+ 'dropoffPostCode' => $dropoffPostCode
310
+ ));
311
+
312
+ $opts = array(
313
+ 'http' => array(
314
+ 'method' => 'POST',
315
+ 'header' => 'Content-type: application/x-www-form-urlencoded',
316
+ 'content' => $postdata
317
+ )
318
+ );
319
+
320
+ $context = stream_context_create($opts);
321
+
322
+ $data = file_get_contents($url, false, $context);
323
+
324
+ if (chromePhpLogsCarrier()) {
325
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . '- Sending http request via FILE GET CONTENTS');
326
+ ChromePhp::log(fileName(__FILE__) . '/' . __LINE__ . ' Server response: ' . isset($data));
327
+ }
328
+
329
+ }
330
+
331
+ return $data;
332
+ }
333
+
334
+ protected function _getAPIInit()
335
+ {
336
+ $url = $this->_brisqqAPIEndpoint . $this->_getInitURL;
337
+ $result = $this->file_get_contents_curl($url);
338
+ return $result;
339
+ }
340
+
341
+ ///////////////////////////////////////////////////////////////////////
342
+
343
+ protected function _getTimeslotShippingRate()
344
+ {
345
+
346
+ $rate = Mage::getModel('shipping/rate_result_method');
347
+
348
+ $rate->setCarrier($this->_code);
349
+
350
+ $rate->setCarrierTitle($this->getConfigData('title'));
351
+
352
+ $rate->setMethod('standard');
353
+ $rate->setMethodTitle($this->getConfigData('timeslotDescription'));
354
+
355
+ $price = $this->_APIparams['price'];
356
+ $matchedDistance = $this->_APIparams['matchedDistance'];
357
+
358
+ $partnerPrices = $this->getConfigData('partnerPriceTiers');
359
+
360
+
361
+ if (isset($partnerPrices)) {
362
+ $partnerpriceserialized = explode('&', $partnerPrices);
363
+ }
364
+
365
+ $quote = Mage::getSingleton('checkout/session')->getQuote();
366
+ $cartGrossTotal = 0;
367
+
368
+ foreach ($quote->getAllItems() as $item) {
369
+ $cartGrossTotal += $item->getPriceInclTax() * $item->getQty();
370
+ }
371
+
372
+ $partnerPricesRules = $this->getConfigData('priceRulesSaved');
373
+
374
+ if (isset($partnerPricesRules)) {
375
+ $pricesRulesSerialized = explode('&', $partnerPricesRules);
376
+ }
377
+
378
+ $moreLessRule = array();
379
+ if (isset($partnerpriceserialized)) {
380
+ foreach ($partnerpriceserialized as $value) {
381
+ $customerpricetiers = explode('=', $value);
382
+ if (isset($customerpricetiers[1]) && $customerpricetiers[1] !== "" && $customerpricetiers[1] !== " " && $customerpricetiers[0] == $matchedDistance) {
383
+ $GLOBALS['brisqqShowTierPrice'] = $customerpricetiers[1];
384
+ }
385
+ }
386
+ }
387
+
388
+
389
+ if (isset($GLOBALS['brisqqShowTierPrice'])) {
390
+ $showprice = $GLOBALS['brisqqShowTierPrice'];
391
+ } else {
392
+ $showprice = $price;
393
+ }
394
+
395
+ if (!empty($showprice)) {
396
+ //
397
+ if (isset($pricesRulesSerialized) && $pricesRulesSerialized[0] != "") {
398
+ foreach ($pricesRulesSerialized as $key => $eachRule) {
399
+ if (strpos($eachRule, '=') !== false) {
400
+ $equalRule = explode("=", $eachRule);
401
+ if ($equalRule[0] == $cartGrossTotal) {
402
+ if (strpos($equalRule[1], '%') !== false) {
403
+ $priceOnly = explode('%', $equalRule[1]);
404
+ $newprice = round($showprice * ((100 - $priceOnly[0]) / 100), 2);
405
+ $showprice = $newprice;
406
+ if (!empty($showprice)) {
407
+ $rate->setPrice($showprice);
408
+ }
409
+ $rate->setCost(0);
410
+ return $rate;
411
+ } else {
412
+ $showprice = $equalRule[1];
413
+ if (!empty($showprice)) {
414
+ $rate->setPrice($showprice);
415
+ }
416
+ $rate->setCost(0);
417
+ return $rate;
418
+ }
419
+ }
420
+ }
421
+
422
+ if (strpos($eachRule, '>') !== false) {
423
+ $moreRule = explode(">", $eachRule);
424
+ if ($moreRule[0] <= $cartGrossTotal) {
425
+ $moreLessRule[] = $moreRule;
426
+ }
427
+ }
428
+
429
+ if (strpos($eachRule, '<') !== false) {
430
+ $lessRule = explode("<", $eachRule);
431
+ if ($lessRule[0] >= $cartGrossTotal) {
432
+ $moreLessRule[] = $lessRule;
433
+ }
434
+ }
435
+
436
+ }
437
+
438
+ if (isset($moreLessRule) && !empty($moreLessRule)) {
439
+
440
+ $finalRule = $moreLessRule[0];
441
+ if (strpos($finalRule[1], '%') !== false) {
442
+ $priceOnly = explode('%', $finalRule[1]);
443
+ $newprice = round($showprice * ((100 - $priceOnly[0]) / 100), 2);
444
+ $showprice = $newprice;
445
+ $GLOBALS['saveRulePrice'] = $newprice;
446
+ } else {
447
+ $showprice = $finalRule[1];
448
+ $GLOBALS['saveRulePrice'] = $finalRule[1];
449
+ }
450
+ }
451
+ }
452
+ $rate->setPrice($showprice);
453
+ }
454
+
455
+ if (!empty($showprice)) {
456
+ $rate->setPrice($showprice);
457
+ }
458
+
459
+ $rate->setCost(0);
460
+
461
+ return $rate;
462
+
463
+ }
464
+
465
+ ///////////////////////////////////////////////////////////////////////
466
+
467
+ //override default abstract class method
468
+ public function isTrackingAvailable()
469
+ {
470
+ return true;
471
+ }
472
+
473
+ ///////////////////////////////////////////////////////////////////////
474
+ }
475
+
476
+ # Loading custom code
477
+ CarrierActivate();
478
+
479
+ ?>
var/brisqq-assets/custom-php-brisqq.php ADDED
@@ -0,0 +1,43 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @author Brisqq Ltd.
5
+ * @package Brisqq
6
+ * @copyright GNU General Public License (GPL)
7
+ *
8
+ * Brisqq harnesses the power of the crowd to enable seamless local delivery on demand.
9
+ * http://www.brisqq.com
10
+ */
11
+
12
+ /**
13
+ * Custom code for the Carrier Class
14
+ *
15
+ */
16
+ function CarrierActivate()
17
+ {
18
+ class Brisqq_Custom_Code_Carrier extends Brisqq_Core_Carrier
19
+ {
20
+ # Write Custom Code for Carrier Class Here
21
+ }
22
+ }
23
+
24
+
25
+
26
+ ####################################################################
27
+ ####################################################################
28
+
29
+
30
+
31
+ /**
32
+ * Custom code for the Observer Class
33
+ *
34
+ */
35
+ function ObserverActivate()
36
+ {
37
+ class Brisqq_Custom_Code_Observer extends Brisqq_Core_Observer
38
+ {
39
+ # Write Custom Code for Observer Class Here
40
+ }
41
+ }
42
+
43
+ ?>
var/brisqq-assets/observer.php ADDED
@@ -0,0 +1,213 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * @author Brisqq Ltd.
5
+ * @package Brisqq
6
+ * @copyright GNU General Public License (GPL)
7
+ *
8
+ * Brisqq harnesses the power of the crowd to enable seamless local delivery on demand.
9
+ * http://www.brisqq.com
10
+ */
11
+
12
+ class Brisqq_Core_Observer extends Varien_Object
13
+ {
14
+
15
+ /**
16
+ * If Brisqq is selected, update the shipping_description field
17
+ * in the database with the selected date/time
18
+ *
19
+ */
20
+ public function updateDescriptionDateTime($observer)
21
+ {
22
+
23
+ $brisqq_chosen_time = Mage::getModel('core/cookie')->get('brisqq_chosen_time');
24
+ $brisqq_instructions = Mage::getModel('core/cookie')->get('brisqq_instructions');
25
+ $session = Mage::getSingleton("core/session", array(
26
+ "name" => "frontend"
27
+ ));
28
+ $shippingMethod = $session->getData("brisqq_shipping_method");
29
+
30
+ if ($shippingMethod != "brisqq_shipping_standard") {
31
+ return $this;
32
+ }
33
+
34
+ $id = Mage::getSingleton('core/session')->getShippingDescription();
35
+ $event = $observer->getEvent();
36
+ $order = $event->getOrder();
37
+ $order->setShippingDescription('Brisqq - selected Date and Time: ' . $brisqq_chosen_time . ', Instructions: ' . $brisqq_instructions);
38
+ $order->save();
39
+ }
40
+
41
+ ////////////////////////////////////////////////////////////////////////////
42
+
43
+ /**
44
+ * Save Brisqq JS file used for Magento backend
45
+ *
46
+ */
47
+ public function saveBrisqqBackendJs($observer) {
48
+
49
+ $block = $observer->getBlock();
50
+
51
+ if ($block instanceof Mage_Adminhtml_Block_System_Config_Edit) {
52
+ $transport = $observer->getTransport();
53
+ $html = $transport->getHtml();
54
+ $pos = strpos($html, "Brisqq");
55
+ if ($pos) {
56
+ remoteFileCallFilter('brisqq-price-tiers.js');
57
+ }
58
+ }
59
+ }
60
+
61
+ ////////////////////////////////////////////////////////////////////////////
62
+
63
+ /**
64
+ * Clear session after a successful purchase
65
+ *
66
+ */
67
+ public function clearPreviousSession($observer)
68
+ {
69
+
70
+ $session = Mage::getSingleton("core/session", array(
71
+ "name" => "frontend"
72
+ ));
73
+
74
+ $session->unsetData("brisqq_delivery");
75
+ $session->unsetData("brisqq_delivery_price");
76
+ return $this;
77
+
78
+ }
79
+
80
+ ////////////////////////////////////////////////////////////////////////////
81
+
82
+ /**
83
+ * Save in the session if Brisqq is selected as the shipping method
84
+ *
85
+ */
86
+ public function saveShippingMethod($observer)
87
+ {
88
+
89
+ $session = Mage::getSingleton("core/session", array(
90
+ "name" => "frontend"
91
+ ));
92
+ $event = $observer->getEvent();
93
+
94
+ $shippingMethod = $observer->getQuote()->getShippingAddress()->getShippingMethod();
95
+
96
+ if ($shippingMethod != "brisqq_shipping_standard") {
97
+ $session->unsetData("brisqq_delivery");
98
+ $session->unsetData("brisqq_delivery_price");
99
+ $session->unsetData("brisqq_shipping_method");
100
+ return $this;
101
+ }
102
+
103
+ $session->setData("brisqq_shipping_method", $shippingMethod);
104
+
105
+ return $this;
106
+
107
+ }
108
+
109
+ ////////////////////////////////////////////////////////////////////////////
110
+
111
+ /**
112
+ * After the order is confirmed, send the confirmation to the Brisqq endpoint
113
+ *
114
+ */
115
+ public function confirmDelivery($observer)
116
+ {
117
+
118
+ $session = Mage::getSingleton("core/session", array(
119
+ "name" => "frontend"
120
+ ));
121
+ $shippingMethod = $session->getData("brisqq_shipping_method");
122
+
123
+ if ($shippingMethod != "brisqq_shipping_standard") {
124
+ $session->unsetData("brisqq_delivery");
125
+ $session->unsetData("brisqq_delivery_price");
126
+ return $this;
127
+ }
128
+
129
+ $deliveryId = Mage::getModel('core/cookie')->get('brisqq_delivery_id');
130
+
131
+ if (empty($deliveryId)) {
132
+ $session->unsetData("brisqq_delivery");
133
+ $session->unsetData("brisqq_delivery_price");
134
+ return $this;
135
+ }
136
+
137
+ $url = $session->getData("brisqq_API_url");
138
+ $token = Mage::getModel('core/cookie')->get('brisqq_token');
139
+
140
+ if (empty($url)) {
141
+ $session->unsetData("brisqq_delivery");
142
+ $session->unsetData("brisqq_delivery_price");
143
+ }
144
+
145
+ $order = Mage::getModel('sales/order');
146
+ $orderId = Mage::getSingleton('checkout/session')->getLastRealOrderId();
147
+
148
+ $url .= "eapi/confirm";
149
+
150
+
151
+ if (functionChecker('curl_version')) {
152
+ $ch = curl_init();
153
+
154
+ curl_setopt($ch, CURLOPT_AUTOREFERER, TRUE);
155
+ curl_setopt($ch, CURLOPT_POST, TRUE);
156
+ curl_setopt($ch, CURLOPT_URL, $url);
157
+ curl_setopt($ch, CURLOPT_FOLLOWLOCATION, TRUE);
158
+ curl_setopt($ch, CURLOPT_HTTPHEADER, array(
159
+ 'Authorization: Bearer ' . $token
160
+ ));
161
+ curl_setopt($ch, CURLOPT_POSTFIELDS, http_build_query(array(
162
+ 'deliveryId' => $deliveryId,
163
+ 'orderId' => $orderId,
164
+ 'partner' => Mage::getStoreConfig('carriers/brisqq_shipping/accountID')
165
+ )));
166
+ curl_setopt($ch, CURLOPT_RETURNTRANSFER, 1);
167
+
168
+ $datat = curl_exec($ch);
169
+ curl_close($ch);
170
+
171
+ $result = $datat;
172
+
173
+ } elseif (functionChecker('file_get_contents')) {
174
+ $postdata = http_build_query(array(
175
+ 'deliveryId' => $deliveryId,
176
+ 'orderId' => $orderId,
177
+ 'partner' => Mage::getStoreConfig('carriers/brisqq_shipping/accountID'),
178
+ 'test' => null
179
+ ));
180
+
181
+ $opts = array(
182
+ 'http' => array(
183
+ 'method' => 'POST',
184
+ 'header' => "Authorization: Bearer " . $token,
185
+ 'Content-type: application/x-www-form-urlencoded',
186
+ 'content' => $postdata,
187
+ 'timeout' => 60
188
+ )
189
+ );
190
+
191
+ $context = stream_context_create($opts);
192
+
193
+ $result = file_get_contents($url, false, $context);
194
+
195
+ }
196
+
197
+
198
+ $session->unsetData("brisqq_delivery");
199
+ $session->unsetData("brisqq_delivery_price");
200
+
201
+ return $this;
202
+
203
+ }
204
+
205
+ ////////////////////////////////////////////////////////////////////////////
206
+
207
+ }
208
+
209
+ # Loading custom code
210
+ ObserverActivate();
211
+
212
+
213
+ ?>