codistoconnect - Version 1.90.2

Version Notes

Download this release

Release Info

Developer Codisto
Extension codistoconnect
Version 1.90.2
Comparing to
See all releases


Version 1.90.2

Files changed (30) hide show
  1. app/code/community/Codisto/Sync/Block/PaymentInfo.php +74 -0
  2. app/code/community/Codisto/Sync/Controller/Router.php +510 -0
  3. app/code/community/Codisto/Sync/Ebaypayment/Model/Paymentmethod.php +48 -0
  4. app/code/community/Codisto/Sync/Helper/CmsContent.php +17 -0
  5. app/code/community/Codisto/Sync/Helper/Data.php +837 -0
  6. app/code/community/Codisto/Sync/Helper/Signal.php +46 -0
  7. app/code/community/Codisto/Sync/Model/Indexer/Ebay.php +551 -0
  8. app/code/community/Codisto/Sync/Model/Observer.php +795 -0
  9. app/code/community/Codisto/Sync/Model/Resource/Mysql4/Setup.php +23 -0
  10. app/code/community/Codisto/Sync/Model/Sync.php +2158 -0
  11. app/code/community/Codisto/Sync/Test/Config/AdminHtml.php +66 -0
  12. app/code/community/Codisto/Sync/Test/Config/Config.php +162 -0
  13. app/code/community/Codisto/Sync/Test/Config/Config/expectations/testCodistoCoreConfig.yaml +5 -0
  14. app/code/community/Codisto/Sync/Test/Controller/Router.php +21 -0
  15. app/code/community/Codisto/Sync/Test/Controllers/CodistoController.php +35 -0
  16. app/code/community/Codisto/Sync/Test/Controllers/IndexController.php +9 -0
  17. app/code/community/Codisto/Sync/Test/Controllers/SyncController.php +9 -0
  18. app/code/community/Codisto/Sync/Test/Model/Paymentmethod.php +29 -0
  19. app/code/community/Codisto/Sync/Test/Model/Sync.php +28 -0
  20. app/code/community/Codisto/Sync/Test/README +2 -0
  21. app/code/community/Codisto/Sync/controllers/CodistoController.php +92 -0
  22. app/code/community/Codisto/Sync/controllers/IndexController.php +1989 -0
  23. app/code/community/Codisto/Sync/controllers/SyncController.php +973 -0
  24. app/code/community/Codisto/Sync/data/codisto_setup/data-install-1.90.2.php +76 -0
  25. app/code/community/Codisto/Sync/etc/adminhtml.xml +110 -0
  26. app/code/community/Codisto/Sync/etc/config.xml +299 -0
  27. app/code/community/Codisto/Sync/sql/codisto_setup/mysql4-install-1.90.2.php +33 -0
  28. app/design/ebay/README +9 -0
  29. app/etc/modules/Codisto_Sync.xml +30 -0
  30. package.xml +2 -0
app/code/community/Codisto/Sync/Block/PaymentInfo.php ADDED
@@ -0,0 +1,74 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Codisto eBay Sync Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * @category Codisto
16
+ * @package Codisto_Sync
17
+ * @copyright Copyright (c) 2015 On Technology Pty. Ltd. (http://codisto.com/)
18
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
19
+ */
20
+
21
+ class Codisto_Sync_Block_PaymentInfo extends Mage_Payment_Block_Info
22
+ {
23
+ public function toPdf()
24
+ {
25
+ $html = $this->escapeHtml($this->getMethod()->getTitle());
26
+
27
+ $specificInfo = $this->getSpecificInformation();
28
+
29
+ $html .= '{{pdf_row_separator}}';
30
+
31
+ foreach($specificInfo as $k => $v)
32
+ {
33
+ if(!preg_match('/_HTML$/', $k))
34
+ {
35
+ $html .= $k.': '.$v.'{{pdf_row_separator}}';
36
+ }
37
+ }
38
+
39
+ return $html;
40
+ }
41
+
42
+ protected function _toHtml()
43
+ {
44
+ $secureMode = $this->getIsSecureMode();
45
+
46
+ $html = $this->escapeHtml($this->getMethod()->getTitle());
47
+
48
+ $specificInfo = $this->getSpecificInformation();
49
+
50
+ $html .= '<table class="codisto-payment-info">';
51
+
52
+ foreach($specificInfo as $k => $v)
53
+ {
54
+ if($secureMode)
55
+ {
56
+ if(!preg_match('/_HTML$/', $k))
57
+ {
58
+ $html .= '<tr><td>'.$this->escapeHtml($k).'</td><td>'.$this->escapeHtml($v).'</td></tr>';
59
+ }
60
+ }
61
+ else
62
+ {
63
+ if(preg_match('/_HTML$/', $k))
64
+ {
65
+ $html .= '<tr><td>'.$this->escapeHtml(preg_replace('/_HTML$/', '', $k)).'</td><td>'.$v.'</td></tr>';
66
+ }
67
+ }
68
+ }
69
+
70
+ $html .= '</table>';
71
+
72
+ return $html;
73
+ }
74
+ }
app/code/community/Codisto/Sync/Controller/Router.php ADDED
@@ -0,0 +1,510 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Codisto eBay Sync Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * @category Codisto
16
+ * @package Codisto_Sync
17
+ * @copyright Copyright (c) 2015 On Technology Pty. Ltd. (http://codisto.com/)
18
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
19
+ */
20
+
21
+ class Codisto_Sync_Controller_Router extends Mage_Core_Controller_Varien_Router_Admin {
22
+
23
+ private function registerMerchant(Zend_Controller_Request_Http $request)
24
+ {
25
+ $merchantID = null;
26
+ $createMerchant = false;
27
+
28
+ try
29
+ {
30
+ if(!extension_loaded('pdo'))
31
+ {
32
+ throw new Exception('(PHP Data Objects) please refer to <a target="#blank" href="http://help.codisto.com/article/64-what-is-pdoexception-could-not-find-driver">Codisto help article</a>', 999);
33
+ }
34
+
35
+ if(!in_array("sqlite",PDO::getAvailableDrivers(), TRUE))
36
+ {
37
+ throw new PDOException('(sqlite PDO Driver) please refer to <a target="#blank" href="http://help.codisto.com/article/64-what-is-pdoexception-could-not-find-driver">Codisto help article</a>', 999);
38
+ }
39
+
40
+ //Can this request create a new merchant ?
41
+ $createMerchant = Mage::helper('codistosync')->createMerchantwithLock();
42
+ }
43
+
44
+ //Something else happened such as PDO related exception
45
+ catch(Exception $e)
46
+ {
47
+
48
+ //If competing requests are coming in as the extension is installed the lock above will be held ... don't report this back to Codisto .
49
+ if($e->getCode() != "HY000")
50
+ {
51
+ //Otherwise report other exception details to Codisto regarding register
52
+ Mage::helper('codistosync')->logExceptionCodisto($e, "https://ui.codisto.com/installed");
53
+ }
54
+ throw $e;
55
+ }
56
+
57
+ if($createMerchant)
58
+ {
59
+ $merchantID = Mage::helper('codistosync')->registerMerchant($request);
60
+ }
61
+
62
+ if($merchantID)
63
+ {
64
+ $merchantID = Zend_Json::decode($merchantID);
65
+ }
66
+
67
+ return $merchantID;
68
+ }
69
+
70
+
71
+ public function match(Zend_Controller_Request_Http $request)
72
+ {
73
+ $path = $request->getPathInfo();
74
+
75
+ if(preg_match('/^\/codisto\//', $path))
76
+ {
77
+ set_time_limit(0);
78
+
79
+ @ini_set('zlib.output_compression', 'Off');
80
+ @ini_set('output_buffering', 'Off');
81
+ @ini_set('output_handler', '');
82
+
83
+ $request->setDispatched(true);
84
+
85
+ $front = $this->getFront();
86
+ $response = $front->getResponse();
87
+ $response->clearAllHeaders();
88
+
89
+ // redirect to product page
90
+ if(preg_match('/^\/codisto\/ebaytab(?:\/|$)/', $path) && $request->getQuery('productid'))
91
+ {
92
+ $productUrl = Mage::helper('adminhtml')->getUrl('adminhtml/catalog_product/edit', array('id' => $request->getQuery('productid')));
93
+
94
+ $response->setRedirect($productUrl);
95
+ $response->sendResponse();
96
+
97
+ return true;
98
+ }
99
+
100
+ // external link handling - e.g. redirect to eBay listing
101
+ if(preg_match('/^\/codisto\/link(?:\/|$)/', $path))
102
+ {
103
+ $section = $request->getQuery('section');
104
+ $action = $request->getQuery('action');
105
+ $destUrl = Mage::helper('adminhtml')->getUrl('adminhtml/codisto/' . $section) . '?action=' . $action;
106
+ $response->setRedirect($destUrl);
107
+ $response->sendResponse();
108
+
109
+ return true;
110
+ }
111
+
112
+ $loggedIn = false;
113
+
114
+ if($request->getCookie('adminhtml'))
115
+ {
116
+ Mage::unregister('_singleton/admin/session');
117
+ Mage::unregister('_singleton/core/session');
118
+
119
+ session_id($request->getCookie('adminhtml'));
120
+
121
+ Mage::getSingleton('core/session', array( 'name' => 'adminhtml' ));
122
+ if(Mage::getSingleton('admin/session')->isLoggedIn())
123
+ {
124
+ $loggedIn = true;
125
+ }
126
+
127
+ Mage::unregister('_singleton/admin/session');
128
+ Mage::unregister('_singleton/core/session');
129
+ }
130
+
131
+ if(!$loggedIn && $request->getCookie('PHPSESSID'))
132
+ {
133
+ Mage::unregister('_singleton/admin/session');
134
+ Mage::unregister('_singleton/core/session');
135
+
136
+ session_id($request->getCookie('PHPSESSID'));
137
+
138
+ Mage::getSingleton('core/session', array( 'name' => null ));
139
+ if(Mage::getSingleton('admin/session')->isLoggedIn())
140
+ {
141
+ $loggedIn = true;
142
+ }
143
+
144
+ Mage::unregister('_singleton/admin/session');
145
+ Mage::unregister('_singleton/core/session');
146
+ }
147
+
148
+ // unlock session
149
+ if(class_exists('Zend_Session', false) && Zend_Session::isStarted())
150
+ {
151
+ Zend_Session::writeClose();
152
+ Zend_Session::destroy();
153
+ }
154
+ if(isset($_SESSION))
155
+ {
156
+ session_write_close();
157
+ }
158
+
159
+ if($loggedIn)
160
+ {
161
+ $storematch = array();
162
+
163
+ // get store context from request
164
+ if(preg_match('/^\/codisto\/ebaytab\/(\d+)\/\d+/', $path, $storematch))
165
+ {
166
+ $storeId = (int)$storematch[1];
167
+
168
+ $path = preg_replace('/(^\/codisto\/ebaytab\/)(\d+\/?)/', '$1', $path);
169
+ }
170
+ else
171
+ {
172
+ $storeId = (int)$request->getCookie('storeid', '0');
173
+ }
174
+
175
+ // look up merchantid/hostkey from store
176
+ $MerchantID = Mage::getStoreConfig('codisto/merchantid', $storeId);
177
+ $HostKey = Mage::getStoreConfig('codisto/hostkey', $storeId);
178
+
179
+ // register merchant on default admin store if config isn't present
180
+ if(!isset($MerchantID) || !isset($HostKey))
181
+ {
182
+ try
183
+ {
184
+ $MerchantID = $this->registerMerchant($request);
185
+ }
186
+ catch(Exception $e)
187
+ {
188
+ if($e->getCode() == 999)
189
+ {
190
+ $response->setBody('<!DOCTYPE html><html><head></head><body><h1>Unable to Register</h1><p>Sorry, we were unable to register your Codisto account,
191
+ your Magento installation is missing a required Pre-requisite' . $e->getMessage() .
192
+ ' or contact <a href="mailto:support@codisto.com">support@codisto.com</a> and our team will help to resolve the issue</p></body></html>');
193
+ }
194
+ else
195
+ {
196
+ $response->setBody('<!DOCTYPE html><html><head></head><body><h1>Unable to Register</h1><p>Sorry, we were unable to register your Codisto account,
197
+ please contact <a href="mailto:support@codisto.com">support@codisto.com</a> and our team will help to resolve the issue</p></body></html>');
198
+ }
199
+
200
+ return true;
201
+ }
202
+ }
203
+
204
+ if($MerchantID == null)
205
+ {
206
+ $response->setBody('<!DOCTYPE html><html><head></head><body><h1>Unable to Register</h1><p>Sorry, we were unable to register your Codisto account,
207
+ please contact <a href="mailto:support@codisto.com">support@codisto.com</a> and our team will help to resolve the issue</p></body></html>');
208
+
209
+ return true;
210
+ }
211
+
212
+ $MerchantID = Zend_Json::decode($MerchantID);
213
+ if(is_array($MerchantID))
214
+ {
215
+ $merchantmatch = array();
216
+
217
+ if(preg_match('/^\/codisto\/ebaytab\/(\d+)/', $path, $merchantmatch))
218
+ {
219
+ $requestedMerchantID = (int)$merchantmatch[1];
220
+
221
+ if(in_array($requestedMerchantID, $MerchantID))
222
+ {
223
+ $MerchantID = $requestedMerchantID;
224
+ }
225
+ else
226
+ {
227
+ $MerchantID = $MerchantID[0];
228
+ }
229
+
230
+ $path = preg_replace('/(^\/codisto\/ebaytab\/)(\d+\/?)/', '$1', $path);
231
+ }
232
+ else if(preg_match('/^\/codisto\/ebaypayment\/(\d+)/', $path, $merchantmatch))
233
+ {
234
+ $requestedMerchantID = (int)$merchantmatch[1];
235
+ if(in_array($requestedMerchantID, $MerchantID))
236
+ {
237
+ $MerchantID = $requestedMerchantID;
238
+ }
239
+ else
240
+ {
241
+ $MerchantID = $MerchantID[0];
242
+ }
243
+ $path = preg_replace('/(^\/codisto\/ebaypayment\/)(\d+\/?)/', '$1', $path);
244
+ }
245
+ else if(preg_match('/^\/codisto\/ebaysale\/(\d+)/', $path, $merchantmatch))
246
+ {
247
+ $requestedMerchantID = (int)$merchantmatch[1];
248
+ if(in_array($requestedMerchantID, $MerchantID))
249
+ {
250
+ $MerchantID = $requestedMerchantID;
251
+ }
252
+ else
253
+ {
254
+ $MerchantID = $MerchantID[0];
255
+ }
256
+ $path = preg_replace('/(^\/codisto\/ebaysale\/)(\d+\/?)/', '$1', $path);
257
+ }
258
+ else if(preg_match('/^\/codisto\/ebayuser\/(\d+)/', $path, $merchantmatch))
259
+ {
260
+ $requestedMerchantID = (int)$merchantmatch[1];
261
+ if(in_array($requestedMerchantID, $MerchantID))
262
+ {
263
+ $MerchantID = $requestedMerchantID;
264
+ }
265
+ else
266
+ {
267
+ $MerchantID = $MerchantID[0];
268
+ }
269
+ $path = preg_replace('/(^\/codisto\/ebayuser\/)(\d+\/?)/', '$1', $path);
270
+ }
271
+ else
272
+ {
273
+ $MerchantID = $MerchantID[0];
274
+ }
275
+ }
276
+ else
277
+ {
278
+ $path = preg_replace('/(^\/codisto\/ebaytab\/)(\d+\/?)/', '$1', $path);
279
+ }
280
+
281
+ // product page iframe
282
+ if(preg_match('/^\/codisto\/ebaytab\/product\/\d+\/iframe\/\d+\//', $path))
283
+ {
284
+ $tabPort = $request->getServer('SERVER_PORT');
285
+ $tabPort = $tabPort = '' || $tabPort == '80' || $tabPort == '443' ? '' : ':'.$tabPort;
286
+ $tabPath = $request->getServer('REQUEST_URI');
287
+ $tabPath = preg_replace('/iframe\/\d+\//', '', $tabPath);
288
+ $tabURL = $request->getScheme() . '://' . $request->getHttpHost() . $tabPort . $tabPath;
289
+
290
+ $response->clearAllHeaders();
291
+ //@codingStandardsIgnoreStart
292
+ if(function_exists('http_response_code'))
293
+ http_response_code(200);
294
+ //@codingStandardsIgnoreEnd
295
+ $response->setHttpResponseCode(200);
296
+ $response->setHeader('Cache-Control', 'public, max-age=86400', true);
297
+ $response->setHeader('Pragma', 'cache', true);
298
+ $response->setBody('<!DOCTYPE html><html><head><body><iframe id="codisto-control-panel" class="codisto-iframe codisto-product" src="'.$tabURL.'" frameborder="0" onmousewheel=""></iframe></body></html>');
299
+
300
+ return true;
301
+ }
302
+
303
+ $remotePath = preg_replace('/^\/codisto\/\/?|key\/[a-zA-z0-9]*\//', '', $path);
304
+ if($MerchantID)
305
+ {
306
+ $remoteUrl = 'https://ui.codisto.com/' . $MerchantID . '/' . $remotePath;
307
+ }
308
+ else
309
+ {
310
+ $remoteUrl = 'https://ui.codisto.com/' . $remotePath;
311
+ }
312
+
313
+ $querystring = '?';
314
+ foreach($request->getQuery() as $k=>$v) {
315
+
316
+ $querystring .= urlencode($k);
317
+ if($v)
318
+ $querystring .= '='.urlencode($v);
319
+ $querystring .= '&';
320
+
321
+ }
322
+ $querystring = rtrim(rtrim($querystring, '&'), '?');
323
+
324
+ $remoteUrl.=$querystring;
325
+
326
+ $starttime = microtime(true);
327
+
328
+ $extensionVersion = (string)Mage::getConfig()->getModuleConfig('Codisto_Sync')->version;
329
+
330
+ $curlOptions = array(CURLOPT_TIMEOUT => 60, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_0);
331
+ $acceptEncoding = $request->getHeader('Accept-Encoding');
332
+ $zlibEnabled = strtoupper(ini_get('zlib.output_compression'));
333
+
334
+ if(!$acceptEncoding || ($zlibEnabled == 1 || $zlibEnabled == 'ON'))
335
+ $curlOptions[CURLOPT_ENCODING] = '';
336
+
337
+ // proxy request
338
+ $client = new Zend_Http_Client($remoteUrl, array(
339
+ 'adapter' => 'Zend_Http_Client_Adapter_Curl',
340
+ 'curloptions' => $curlOptions,
341
+ 'keepalive' => false,
342
+ 'strict' => false,
343
+ 'strictredirects' => true,
344
+ 'maxredirects' => 0,
345
+ 'timeout' => 10
346
+ ));
347
+
348
+ $adminBasePort = $request->getServer('SERVER_PORT');
349
+ $adminBasePort = $adminBasePort = '' || $adminBasePort == '80' || $adminBasePort == '443' ? '' : ':'.$adminBasePort;
350
+ $adminBasePath = $request->getServer('REQUEST_URI');
351
+ $adminBasePath = substr($adminBasePath, 0, strpos($adminBasePath, '/codisto/'));
352
+ $adminBaseURL = $request->getScheme() . '://' . $request->getHttpHost() . $adminBasePort . $adminBasePath . '/codisto/ebaytab/'.$storeId.'/'.$MerchantID.'/';
353
+
354
+ $client->setHeaders('X-Admin-Base-Url', $adminBaseURL);
355
+ $client->setHeaders('X-Codisto-Version', $extensionVersion);
356
+
357
+ // set proxied headers
358
+ foreach($this->getAllHeaders() as $k=>$v)
359
+ {
360
+ if(strtolower($k) != 'host')
361
+ $client->setHeaders($k, $v);
362
+ }
363
+
364
+ $client->setHeaders(array('X-HostKey' => $HostKey));
365
+
366
+ $requestBody = $request->getRawBody();
367
+ if($requestBody)
368
+ $client->setRawData($requestBody);
369
+
370
+ for($retry = 0; ; $retry++)
371
+ {
372
+ $remoteResponse = null;
373
+
374
+ try
375
+ {
376
+ $remoteResponse = $client->request($request->getMethod());
377
+
378
+ if($remoteResponse->isError())
379
+ {
380
+ if((microtime(true) - $starttime < 10.0) &&
381
+ $retry < 3)
382
+ {
383
+ usleep(500000);
384
+ continue;
385
+ }
386
+ }
387
+ }
388
+ catch(Exception $exception)
389
+ {
390
+ if((microtime(true) - $starttime < 10.0) &&
391
+ $retry < 3)
392
+ {
393
+ usleep(500000);
394
+ continue;
395
+ }
396
+ }
397
+
398
+ if(!$remoteResponse)
399
+ {
400
+ $response->clearAllHeaders();
401
+ $response->setHttpResponseCode(500);
402
+ $response->setHeader('Pragma', 'no-cache', true);
403
+ $response->setHeader('Cache-Control', 'no-cache, must-revalidate', true);
404
+ $response->setBody('<!DOCTYPE html><html lang="en"><body><h1>Oops</h1><p>Temporary error encountered, please try again</p></body></html>');
405
+ return true;
406
+ }
407
+
408
+ // set proxied status and headers
409
+ $response->clearAllHeaders();
410
+ $response->setHttpResponseCode($remoteResponse->getStatus());
411
+ $response->setHeader('Pragma', '', true);
412
+ $response->setHeader('Cache-Control', '', true);
413
+
414
+ $filterHeaders = array('server', 'content-length', 'transfer-encoding', 'date', 'connection', 'x-storeviewmap');
415
+ if(!$acceptEncoding)
416
+ $filterHeaders[] = 'content-encoding';
417
+
418
+ foreach($remoteResponse->getHeaders() as $k => $v)
419
+ {
420
+ if(!in_array(strtolower($k), $filterHeaders, true))
421
+ {
422
+ if(is_array($v))
423
+ {
424
+ $response->setHeader($k, $v[0], true);
425
+
426
+ for($i = 1; $i < count($v); $i++)
427
+ {
428
+ $response->setHeader($k, $v[$i]);
429
+ }
430
+ }
431
+ else
432
+ {
433
+ $response->setHeader($k, $v, true);
434
+ }
435
+ }
436
+ else
437
+ {
438
+ if(strtolower($k) == 'x-storeviewmap')
439
+ {
440
+ $config = Mage::getConfig();
441
+
442
+ $storeViewMapping = Zend_Json::decode($v);
443
+
444
+ foreach($storeViewMapping as $mapping)
445
+ {
446
+ $storeId = $mapping['storeid'];
447
+ $merchantList = $mapping['merchants'];
448
+
449
+ if($storeId == 0)
450
+ {
451
+ $config->saveConfig('codisto/merchantid', $merchantList);
452
+ }
453
+ else
454
+ {
455
+ $config->saveConfig('codisto/merchantid', $merchantList, 'stores', $storeId);
456
+ }
457
+ }
458
+
459
+ $config->cleanCache();
460
+
461
+ Mage::app()->removeCache('config_store_data');
462
+ Mage::app()->getCacheInstance()->cleanType('config');
463
+ Mage::dispatchEvent('adminhtml_cache_refresh_type', array('type' => 'config'));
464
+ Mage::app()->reinitStores();
465
+ }
466
+ }
467
+ }
468
+
469
+ if(!$response->isRedirect())
470
+ {
471
+ // set proxied output
472
+ $response->setBody($remoteResponse->getRawBody());
473
+ }
474
+
475
+ return true;
476
+ }
477
+ }
478
+ else
479
+ {
480
+ include_once Mage::getBaseDir() . '/errors/404.php';
481
+
482
+ return true;
483
+ }
484
+ }
485
+ return false;
486
+ }
487
+
488
+ private function getAllHeaders($extra = false)
489
+ {
490
+
491
+ foreach ($_SERVER as $name => $value)
492
+ {
493
+ if (substr($name, 0, 5) == 'HTTP_')
494
+ {
495
+ $name = str_replace(' ', '-', ucwords(strtolower(str_replace('_', ' ', substr($name, 5)))));
496
+ $headers[$name] = $value;
497
+ } else if ($name == 'CONTENT_TYPE') {
498
+ $headers['Content-Type'] = $value;
499
+ } else if ($name == 'CONTENT_LENGTH') {
500
+ $headers['Content-Length'] = $value;
501
+ }
502
+ }
503
+
504
+ if($extra)
505
+ {
506
+ $headers = array_merge($headers, $extra);
507
+ }
508
+ return $headers;
509
+ }
510
+ }
app/code/community/Codisto/Sync/Ebaypayment/Model/Paymentmethod.php ADDED
@@ -0,0 +1,48 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Codisto eBay Sync Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * @category Codisto
16
+ * @package Codisto_Sync
17
+ * @copyright Copyright (c) 2014 On Technology Pty. Ltd. (http://codisto.com/)
18
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
19
+ */
20
+
21
+ class Codisto_Sync_Ebaypayment_Model_Paymentmethod extends Mage_Payment_Model_Method_Abstract
22
+ {
23
+ protected $_code = 'ebay';
24
+
25
+ protected $_infoBlockType = 'codisto/paymentInfo';
26
+
27
+ protected $_isGateway = false;
28
+ protected $_canAuthorize = false;
29
+ protected $_canCapture = false;
30
+ protected $_canCapturePartial = false;
31
+ protected $_canRefund = false;
32
+ protected $_canVoid = false;
33
+ protected $_canUseInternal = false;
34
+ protected $_canUseCheckout = false;
35
+ protected $_canUseForMultiShipping = false;
36
+ protected $_canSaveCc = false;
37
+
38
+ public function isAvailable($quote = null)
39
+ {
40
+ return true;
41
+ }
42
+
43
+ public function isApplicableToQuote($quote, $checksBitMask)
44
+ {
45
+ return true;
46
+ }
47
+
48
+ }
app/code/community/Codisto/Sync/Helper/CmsContent.php ADDED
@@ -0,0 +1,17 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once 'app/Mage.php';
4
+
5
+ Mage::app();
6
+
7
+ try {
8
+
9
+ $contents = file_get_contents('php://stdin');
10
+
11
+ echo Mage::helper('cms')->getBlockTemplateProcessor()->filter(trim($contents));
12
+
13
+ } catch (Exception $e) {
14
+
15
+ echo $e->getMessage();
16
+
17
+ }
app/code/community/Codisto/Sync/Helper/Data.php ADDED
@@ -0,0 +1,837 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Codisto eBay Sync Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * @category Codisto
16
+ * @package Codisto_Sync
17
+ * @copyright Copyright (c) 2015 On Technology Pty. Ltd. (http://codisto.com/)
18
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
19
+ */
20
+
21
+
22
+ if (!function_exists('hash_equals')) {
23
+
24
+ function hash_equals($known_string, $user_string)
25
+ {
26
+
27
+ /**
28
+ * This file is part of the hash_equals library
29
+ *
30
+ * For the full copyright and license information, please view the LICENSE
31
+ * file that was distributed with this source code.
32
+ *
33
+ * @copyright Copyright (c) 2013-2014 Rouven Weßling <http://rouvenwessling.de>
34
+ * @license http://opensource.org/licenses/MIT MIT
35
+ */
36
+
37
+ // We jump trough some hoops to match the internals errors as closely as possible
38
+ $argc = func_num_args();
39
+ $params = func_get_args();
40
+
41
+ if ($argc < 2) {
42
+ trigger_error("hash_equals() expects at least 2 parameters, {$argc} given", E_USER_WARNING);
43
+ return null;
44
+ }
45
+
46
+ if (!is_string($known_string)) {
47
+ trigger_error("hash_equals(): Expected known_string to be a string, " . gettype($known_string) . " given", E_USER_WARNING);
48
+ return false;
49
+ }
50
+ if (!is_string($user_string)) {
51
+ trigger_error("hash_equals(): Expected user_string to be a string, " . gettype($user_string) . " given", E_USER_WARNING);
52
+ return false;
53
+ }
54
+
55
+ if (strlen($known_string) !== strlen($user_string)) {
56
+ return false;
57
+ }
58
+ $len = strlen($known_string);
59
+ $result = 0;
60
+ for ($i = 0; $i < $len; $i++) {
61
+ $result |= (ord($known_string[$i]) ^ ord($user_string[$i]));
62
+ }
63
+ // They are only identical strings if $result is exactly 0...
64
+ return 0 === $result;
65
+ }
66
+ }
67
+
68
+
69
+ class Codisto_Sync_Helper_Data extends Mage_Core_Helper_Abstract
70
+ {
71
+ private $client;
72
+ private $phpInterpreter;
73
+
74
+ public function getCodistoVersion()
75
+ {
76
+ return (string) Mage::getConfig()->getNode()->modules->Codisto_Sync->version;
77
+ }
78
+
79
+ public function checkRequestHash($key, $server)
80
+ {
81
+ if(!isset($server['HTTP_X_NONCE']))
82
+ return false;
83
+
84
+ if(!isset($server['HTTP_X_HASH']))
85
+ return false;
86
+
87
+ $nonce = $server['HTTP_X_NONCE'];
88
+ $hash = $server['HTTP_X_HASH'];
89
+
90
+ try
91
+ {
92
+ $nonceDbPath = $this->getSyncPath('nonce.db');
93
+
94
+ $nonceDb = new PDO('sqlite:' . $nonceDbPath);
95
+ $nonceDb->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
96
+ $nonceDb->exec('CREATE TABLE IF NOT EXISTS nonce (value text NOT NULL PRIMARY KEY)');
97
+ $qry = $nonceDb->prepare('INSERT OR IGNORE INTO nonce (value) VALUES(?)');
98
+ $qry->execute( array( $nonce ) );
99
+ if($qry->rowCount() !== 1)
100
+ return false;
101
+ }
102
+ catch(Exception $e)
103
+ {
104
+ $this->logExceptionCodisto($e, 'https://ui.codisto.com/installed');
105
+ }
106
+
107
+ return $this->checkHash($key, $nonce, $hash);
108
+ }
109
+
110
+ private function checkHash($Key, $Nonce, $Hash)
111
+ {
112
+ $Sig = base64_encode( hash('sha256', $Key . $Nonce, true) );
113
+
114
+ return hash_equals( $Hash, $Sig );
115
+ }
116
+
117
+ public function getConfig($storeId)
118
+ {
119
+ $merchantID = Mage::getStoreConfig('codisto/merchantid', $storeId);
120
+ $hostKey = Mage::getStoreConfig('codisto/hostkey', $storeId);
121
+
122
+ return isset($merchantID) && $merchantID != "" && isset($hostKey) && $hostKey != "";
123
+ }
124
+
125
+ public function getMerchantId($storeId)
126
+ {
127
+ $merchantlist = Zend_Json::decode(Mage::getStoreConfig('codisto/merchantid', $storeId));
128
+ if($merchantlist)
129
+ {
130
+ if(is_array($merchantlist))
131
+ {
132
+ return $merchantlist[0];
133
+ }
134
+ return $merchantlist;
135
+ }
136
+ else
137
+ {
138
+ return 0;
139
+ }
140
+ }
141
+
142
+ //Determine if we can create a new merchant. Prevent multiple requests from being able to complete signups
143
+ public function createMerchantwithLock()
144
+ {
145
+ $createMerchant = false;
146
+ $lockFile = Mage::getBaseDir('var') . '/codisto-lock';
147
+
148
+ $lockDb = new PDO('sqlite:' . $lockFile);
149
+ $lockDb->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
150
+ $lockDb->setAttribute(PDO::ATTR_TIMEOUT, 1);
151
+ $lockDb->exec('BEGIN EXCLUSIVE TRANSACTION');
152
+ $lockDb->exec('CREATE TABLE IF NOT EXISTS Lock (id real NOT NULL)');
153
+
154
+ $lockQuery = $lockDb->query('SELECT id FROM Lock UNION SELECT 0 WHERE NOT EXISTS(SELECT 1 FROM Lock)');
155
+ $lockQuery->execute();
156
+ $lockRow = $lockQuery->fetch();
157
+ $timeStamp = $lockRow['id'];
158
+
159
+ $lockQuery->closeCursor();
160
+
161
+ if($timeStamp + 5000000 < microtime(true))
162
+ {
163
+ $createMerchant = true;
164
+
165
+ $lockDb->exec('DELETE FROM Lock');
166
+ $lockDb->exec('INSERT INTO Lock (id) VALUES('. microtime(true) .')');
167
+ }
168
+
169
+ $lockDb->exec('COMMIT TRANSACTION');
170
+ $lockDb = null;
171
+ return $createMerchant;
172
+ }
173
+
174
+ //Register a new merchant with Codisto
175
+ public function registerMerchant()
176
+ {
177
+
178
+ try
179
+ {
180
+
181
+ $MerchantID = null;
182
+ $HostKey = null;
183
+
184
+ // Load admin/user so that cookie deserialize will work properly
185
+ Mage::getModel("admin/user");
186
+
187
+ // Get the admin session
188
+ $session = Mage::getSingleton('admin/session');
189
+
190
+ // Get the user object from the session
191
+ $user = $session->getUser();
192
+ if(!$user)
193
+ {
194
+ $user = Mage::getModel('admin/user')->getCollection()->setPageSize(1)->setCurPage(1)->getFirstItem();
195
+ }
196
+
197
+ $createLockFile = Mage::getBaseDir('var') . '/codisto-create-lock';
198
+
199
+ $createLockDb = new PDO('sqlite:' . $createLockFile);
200
+ $createLockDb->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
201
+ $createLockDb->setAttribute(PDO::ATTR_TIMEOUT, 60);
202
+ $createLockDb->exec('BEGIN EXCLUSIVE TRANSACTION');
203
+
204
+ Mage::app()->getStore(0)->resetConfig();
205
+
206
+ $MerchantID = Mage::getStoreConfig('codisto/merchantid', 0);
207
+ $HostKey = Mage::getStoreConfig('codisto/hostkey', 0);
208
+
209
+ if(!isset($MerchantID) || !isset($HostKey))
210
+ {
211
+ $url = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB);
212
+ $version = Mage::getVersion();
213
+ $storename = Mage::getStoreConfig('general/store_information/name', 0);
214
+ $email = $user->getEmail();
215
+ $codistoversion = $this->getCodistoVersion();
216
+ $ResellerKey = Mage::getConfig()->getNode('codisto/resellerkey');
217
+ if($ResellerKey)
218
+ {
219
+ $ResellerKey = intval(trim((string)$ResellerKey));
220
+ }
221
+ else
222
+ {
223
+ $ResellerKey = '0';
224
+ }
225
+
226
+ $curlOptions = array(CURLOPT_TIMEOUT => 60, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_0);
227
+
228
+ $client = new Zend_Http_Client("https://ui.codisto.com/create", array(
229
+ 'adapter' => 'Zend_Http_Client_Adapter_Curl',
230
+ 'curloptions' => $curlOptions,
231
+ 'keepalive' => true,
232
+ 'strict' => false,
233
+ 'strictredirects' => true,
234
+ 'maxredirects' => 0,
235
+ 'timeout' => 30
236
+ ));
237
+
238
+ $client->setHeaders('Content-Type', 'application/json');
239
+ for($retry = 0; ; $retry++)
240
+ {
241
+ try
242
+ {
243
+ $remoteResponse = $client->setRawData(Zend_Json::encode(array( 'type' => 'magento', 'version' => Mage::getVersion(),
244
+ 'url' => $url, 'email' => $email, 'storename' => $storename , 'resellerkey' => $ResellerKey, 'codistoversion' => $codistoversion)))->request('POST');
245
+
246
+ if(!$remoteResponse->isSuccessful())
247
+ {
248
+ throw new Exception('Error Creating Account');
249
+ }
250
+
251
+ // @codingStandardsIgnoreStart
252
+ $data = Zend_Json::decode($remoteResponse->getRawBody(), true);
253
+ // @codingStandardsIgnoreEnd
254
+
255
+ //If the merchantid and hostkey was present in response body
256
+ if(isset($data['merchantid']) && $data['merchantid'] && isset($data['hostkey']) && $data['hostkey'])
257
+ {
258
+ $MerchantID = $data['merchantid'];
259
+ $HostKey = $data['hostkey'];
260
+
261
+ Mage::getModel("core/config")->saveConfig("codisto/merchantid", $MerchantID);
262
+ Mage::getModel("core/config")->saveConfig("codisto/hostkey", $HostKey);
263
+
264
+ Mage::app()->removeCache('config_store_data');
265
+ Mage::app()->getCacheInstance()->cleanType('config');
266
+ Mage::dispatchEvent('adminhtml_cache_refresh_type', array('type' => 'config'));
267
+ Mage::app()->reinitStores();
268
+
269
+ //See if Codisto can reach this server. If not, then attempt to schedule Magento cron entries
270
+ try
271
+ {
272
+
273
+ $h = new Zend_Http_Client();
274
+ $h->setConfig(array( 'keepalive' => true, 'maxredirects' => 0, 'timeout' => 20 ));
275
+ $h->setStream();
276
+ $h->setUri('https://ui.codisto.com/'.$MerchantID.'/testendpoint/');
277
+ $h->setHeaders('X-HostKey', $HostKey);
278
+ $testResponse = $h->request('GET');
279
+ $testdata = Zend_Json::decode($testResponse->getRawBody(), true);
280
+
281
+ if(isset($testdata['ack']) && $testdata['ack'] == "FAILED") {
282
+
283
+ //Endpoint Unreachable - Turn on cron fallback
284
+ $file = new Varien_Io_File();
285
+ $file->open(array('path' => Mage::getBaseDir('var')));
286
+ $file->write('codisto-external-sync-failed', '0');
287
+ $file->close();
288
+
289
+ }
290
+
291
+ }
292
+ //Codisto can't reach this url so register with Magento cron to pull
293
+ catch (Exception $e) {
294
+
295
+ //Check in cron
296
+ $file = new Varien_Io_File();
297
+ $file->open(array('path' => Mage::getBaseDir('var')));
298
+ $file->write('codisto-external-test-failed', '0');
299
+ $file->close();
300
+
301
+ Mage::log('Error testing endpoint and writing failed sync file. Message: ' . $e->getMessage() . ' on line: ' . $e->getLine());
302
+
303
+ }
304
+ }
305
+ }
306
+ //Attempt to retry register
307
+ catch(Exception $e)
308
+ {
309
+ Mage::log($e->getMessage());
310
+ //Attempt again to register if we
311
+ if($retry < 3)
312
+ {
313
+ usleep(1000000);
314
+ continue;
315
+ }
316
+ //Give in , we can't register at the moment
317
+ throw $e;
318
+ }
319
+
320
+ break;
321
+ }
322
+ }
323
+
324
+ $createLockDb->exec('COMMIT TRANSACTION');
325
+ $createLockDb = null;
326
+ }
327
+ catch(Exception $e)
328
+ {
329
+ // remove lock file immediately if any error during account creation
330
+ @unlink($lockFile);
331
+ }
332
+ return $MerchantID;
333
+ }
334
+
335
+ public function canSyncIncrementally($syncDbPath, $storeId)
336
+ {
337
+
338
+
339
+
340
+ return false;
341
+ }
342
+
343
+ public function logExceptionCodisto(Exception $e, $endpoint)
344
+ {
345
+ $request = Mage::app()->getRequest();
346
+
347
+ try
348
+ {
349
+
350
+ $url = ($request->getServer('SERVER_PORT') == '443' ? 'https://' : 'http://') . $request->getServer('HTTP_HOST') . $request->getServer('REQUEST_URI');
351
+ $magentoversion = Mage::getVersion();
352
+ $codistoversion = $this->getCodistoVersion();
353
+
354
+ $logEntry = Zend_Json::encode(array(
355
+ 'url' => $url,
356
+ 'magento_version' => $magentoversion,
357
+ 'codisto_version' => $codistoversion,
358
+ 'message' => $e->getMessage(),
359
+ 'code' => $e->getCode(),
360
+ 'file' => $e->getFile(),
361
+ 'line' => $e->getLine()));
362
+
363
+ Mage::log('CodistoConnect '.$logEntry);
364
+
365
+ $client = new Zend_Http_Client($endpoint, array( 'adapter' => 'Zend_Http_Client_Adapter_Curl', 'curloptions' => array(CURLOPT_SSL_VERIFYPEER => false), 'keepalive' => false, 'maxredirects' => 0 ));
366
+ $client->setHeaders('Content-Type', 'application/json');
367
+ $client->setRawData($logEntry);
368
+ $client->request('POST');
369
+ }
370
+ catch(Exception $e2)
371
+ {
372
+ Mage::log("Couldn't notify " . $endpoint . " endpoint of install error. Exception details " . $e->getMessage() . " on line: " . $e->getLine());
373
+ }
374
+ }
375
+
376
+ public function eBayReIndex()
377
+ {
378
+ try
379
+ {
380
+ $indexer = Mage::getModel('index/process');
381
+ $indexer->load('codistoebayindex', 'indexer_code');
382
+ $indexer->reindexAll();
383
+ $indexer->changeStatus(Mage_Index_Model_Process::STATUS_REQUIRE_REINDEX);
384
+ }
385
+ catch (Exception $e)
386
+ {
387
+ Mage::log($e->getMessage());
388
+ }
389
+ }
390
+
391
+ public function getSyncPath($path)
392
+ {
393
+ $file = new Varien_Io_File();
394
+
395
+ $base_path = Mage::getBaseDir('var') . '/codisto/';
396
+
397
+ try {
398
+
399
+ $file->checkAndCreateFolder( $base_path, 0777 );
400
+
401
+ } catch (Exception $e) {
402
+
403
+ return preg_replace( '/\/+/', '/', Mage::getBaseDir('var') . '/' . $path );
404
+
405
+ }
406
+
407
+ return preg_replace( '/\/+/', '/', $base_path . $path );
408
+ }
409
+
410
+ public function getSyncPathTemp($path)
411
+ {
412
+ $base_path = $this->getSyncPath('');
413
+
414
+ return tempnam( $base_path , $path . '-' );
415
+ }
416
+
417
+ public function prepareSqliteDatabase($db, $pagesize = 65536, $timeout = 60)
418
+ {
419
+ $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
420
+ $db->setAttribute(PDO::ATTR_TIMEOUT, $timeout);
421
+ $db->exec('PRAGMA synchronous=OFF');
422
+ $db->exec('PRAGMA temp_store=MEMORY');
423
+ $db->exec('PRAGMA page_size='.$pagesize);
424
+ $db->exec('PRAGMA encoding=\'UTF-8\'');
425
+ $db->exec('PRAGMA cache_size=15000');
426
+ $db->exec('PRAGMA soft_heap_limit=67108864');
427
+ $db->exec('PRAGMA journal_mode=MEMORY');
428
+ }
429
+
430
+ private function phpTest($interpreter, $args, $script)
431
+ {
432
+ $process = proc_open('"'.$interpreter.'" '.$args, array(
433
+ array('pipe', 'r'),
434
+ array('pipe', 'w')
435
+ ), $pipes);
436
+
437
+ @fwrite($pipes[0], $script);
438
+ fclose($pipes[0]);
439
+
440
+ $result = @stream_get_contents($pipes[1]);
441
+ if(!$result)
442
+ $result = '';
443
+
444
+ fclose($pipes[1]);
445
+
446
+ proc_close($process);
447
+
448
+ return $result;
449
+ }
450
+
451
+ private function phpCheck($interpreter, $requiredVersion, $requiredExtensions)
452
+ {
453
+ if(function_exists('proc_open') &&
454
+ function_exists('proc_close'))
455
+ {
456
+ if(is_array($requiredExtensions))
457
+ {
458
+ $extensionScript = '<?php echo serialize(array('.implode(',',
459
+ array_map(create_function('$ext',
460
+ 'return \'\\\'\'.$ext.\'\\\' => extension_loaded(\\\'\'.$ext.\'\\\')\';'),
461
+ $requiredExtensions)).'));';
462
+
463
+ $extensionSet = array();
464
+ foreach ($requiredExtensions as $extension)
465
+ {
466
+ $extensionSet[$extension] = 1;
467
+ }
468
+ }
469
+ else
470
+ {
471
+ $extensionScript = '';
472
+ $extensionSet = array();
473
+ }
474
+
475
+ $php_version = $this->phpTest($interpreter, '-n', '<?php echo phpversion();');
476
+
477
+ if(!preg_match('/^\d+\.\d+\.\d+/', $php_version))
478
+ return '';
479
+
480
+ if(version_compare($php_version, $requiredVersion, 'lt'))
481
+ return '';
482
+
483
+ if($extensionScript)
484
+ {
485
+ $extensions = $this->phpTest($interpreter, '-n', $extensionScript);
486
+ $extensions = @unserialize($extensions);
487
+ if(!is_array($extensions))
488
+ $extensions = array();
489
+
490
+ if($extensionSet == $extensions)
491
+ {
492
+ return '"'.$interpreter.'" -n';
493
+ }
494
+ else
495
+ {
496
+ $php_ini = php_ini_loaded_file();
497
+ if($php_ini)
498
+ {
499
+ $extensions = $this->phpTest($interpreter, '-c "'.$php_ini.'"', $extensionScript);
500
+ $extensions = @unserialize($extensions);
501
+ if(!is_array($extensions))
502
+ $extensions = array();
503
+ }
504
+
505
+ if($extensionSet == $extensions)
506
+ {
507
+ return '"'.$interpreter.'" -c "'.$php_ini.'"';
508
+ }
509
+ else
510
+ {
511
+ $extensions = $this->phpTest($interpreter, '', $extensionScript);
512
+ $extensions = @unserialize($extensions);
513
+ if(!is_array($extensions))
514
+ $extensions = array();
515
+
516
+ if($extensionSet == $extensions)
517
+ {
518
+ return '"'.$interpreter.'"';
519
+ }
520
+ }
521
+ }
522
+ }
523
+ }
524
+ else
525
+ {
526
+ return '"'.$interpreter.'"';
527
+ }
528
+
529
+ return '';
530
+ }
531
+
532
+ private function phpPath($requiredExtensions)
533
+ {
534
+ if(isset($this->phpInterpreter))
535
+ return $this->phpInterpreter;
536
+
537
+ $interpreterName = array( 'php', 'php5', 'php-cli', 'hhvm' );
538
+ $extension = '';
539
+ if('\\' === DIRECTORY_SEPARATOR)
540
+ {
541
+ $extension = '.exe';
542
+ }
543
+
544
+ $dirs = array(PHP_BINDIR);
545
+ if ('\\' === DIRECTORY_SEPARATOR)
546
+ {
547
+ $dirs[] = getenv('SYSTEMDRIVE').'\\xampp\\php\\';
548
+ }
549
+
550
+ $open_basedir = ini_get('open_basedir');
551
+ if($open_basedir)
552
+ {
553
+ $basedirs = explode(PATH_SEPARATOR, ini_get('open_basedir'));
554
+ foreach($basedirs as $dir)
555
+ {
556
+ if(@is_dir($dir))
557
+ {
558
+ $dirs[] = $dir;
559
+ }
560
+ }
561
+ }
562
+ else
563
+ {
564
+ $dirs = array_merge(explode(PATH_SEPARATOR, getenv('PATH')), $dirs);
565
+ }
566
+
567
+ foreach ($dirs as $dir)
568
+ {
569
+ foreach ($interpreterName as $fileName)
570
+ {
571
+ $file = $dir.DIRECTORY_SEPARATOR.$fileName.$extension;
572
+
573
+ if(@is_file($file) && ('\\' === DIRECTORY_SEPARATOR || @is_executable($file)))
574
+ {
575
+ $file = $this->phpCheck($file, '5.0.0', $requiredExtensions);
576
+ if(!$file)
577
+ continue;
578
+
579
+ $this->phpInterpreter = $file;
580
+
581
+ return $file;
582
+ }
583
+ }
584
+ }
585
+
586
+ if(function_exists('shell_exec'))
587
+ {
588
+ foreach ($interpreterName as $fileName)
589
+ {
590
+ $file = shell_exec('which '.$fileName.$extension);
591
+ if($file)
592
+ {
593
+ $file = trim($file);
594
+ if(@is_file($file) && ('\\' === DIRECTORY_SEPARATOR || @is_executable($file)))
595
+ {
596
+ $file = $this->phpCheck($file, '5.0.0', $requiredExtensions);
597
+ if(!$file)
598
+ continue;
599
+
600
+ $this->phpInterpreter = $file;
601
+
602
+ return $file;
603
+ }
604
+ }
605
+ }
606
+ }
607
+
608
+ $this->phpInterpreter = null;
609
+
610
+ return null;
611
+ }
612
+
613
+ private function runProcessBackground($script, $args, $extensions)
614
+ {
615
+ if(function_exists('proc_open'))
616
+ {
617
+ $interpreter = $this->phpPath($extensions);
618
+ if($interpreter)
619
+ {
620
+ $curl_cainfo = ini_get('curl.cainfo');
621
+ if(!$curl_cainfo && isset($_SERVER['CURL_CA_BUNDLE']))
622
+ {
623
+ $curl_cainfo = $_SERVER['CURL_CA_BUNDLE'];
624
+ }
625
+ if(!$curl_cainfo && isset($_SERVER['SSL_CERT_FILE']))
626
+ {
627
+ $curl_cainfo = $_SERVER['SSL_CERT_FILE'];
628
+ }
629
+ if(!$curl_cainfo && isset($_SERVER['CURL_CA_BUNDLE']))
630
+ {
631
+ $curl_cainfo = $_ENV['CURL_CA_BUNDLE'];
632
+ }
633
+ if(!$curl_cainfo && isset($_ENV['SSL_CERT_FILE']))
634
+ {
635
+ $curl_cainfo = $_ENV['SSL_CERT_FILE'];
636
+ }
637
+
638
+ $cmdline = '';
639
+ foreach($args as $arg)
640
+ {
641
+ $cmdline .= '\''.$arg.'\' ';
642
+ }
643
+
644
+ if (strtoupper(substr(PHP_OS, 0, 3)) === 'WIN')
645
+ {
646
+ $process = proc_open('start /b '.$interpreter.' "'.$script.'" '.$cmdline, array(), $pipes, Mage::getBaseDir('base'), array( 'CURL_CA_BUNDLE' => $curl_cainfo ));
647
+ }
648
+ else
649
+ {
650
+ $process = proc_open($interpreter.' "'.$script.'" '.$cmdline.' &', array(), $pipes, Mage::getBaseDir('base'), array( 'CURL_CA_BUNDLE' => $curl_cainfo ));
651
+ }
652
+
653
+ if(is_resource($process))
654
+ {
655
+ proc_close($process);
656
+ return true;
657
+ }
658
+ }
659
+ }
660
+
661
+ return false;
662
+ }
663
+
664
+ function runProcess($script, $args, $extensions, $stdin)
665
+ {
666
+ if(function_exists('proc_open')
667
+ && function_exists('proc_close'))
668
+ {
669
+ $interpreter = $this->phpPath($extensions);
670
+ if($interpreter)
671
+ {
672
+ $curl_cainfo = ini_get('curl.cainfo');
673
+ if(!$curl_cainfo && isset($_SERVER['CURL_CA_BUNDLE']))
674
+ {
675
+ $curl_cainfo = $_SERVER['CURL_CA_BUNDLE'];
676
+ }
677
+ if(!$curl_cainfo && isset($_SERVER['SSL_CERT_FILE']))
678
+ {
679
+ $curl_cainfo = $_SERVER['SSL_CERT_FILE'];
680
+ }
681
+ if(!$curl_cainfo && isset($_ENV['CURL_CA_BUNDLE']))
682
+ {
683
+ $curl_cainfo = $_ENV['CURL_CA_BUNDLE'];
684
+ }
685
+ if(!$curl_cainfo && isset($_ENV['SSL_CERT_FILE']))
686
+ {
687
+ $curl_cainfo = $_ENV['SSL_CERT_FILE'];
688
+ }
689
+
690
+ $cmdline = '';
691
+ if(is_array($cmdline))
692
+ {
693
+ foreach($args as $arg)
694
+ {
695
+ $cmdline .= '\''.$arg.'\' ';
696
+ }
697
+ }
698
+
699
+ $descriptors = array(
700
+ 1 => array('pipe', 'w')
701
+ );
702
+
703
+ if(is_string($stdin))
704
+ {
705
+ $descriptors[0] = array('pipe', 'r');
706
+ }
707
+
708
+ $process = proc_open($interpreter.' "'.$script.'" '.$cmdline,
709
+ $descriptors, $pipes, Mage::getBaseDir('base'), array( 'CURL_CA_BUNDLE' => $curl_cainfo ));
710
+ if(is_resource($process))
711
+ {
712
+ if(is_string($stdin))
713
+ {
714
+ for($written = 0; $written < strlen($stdin); )
715
+ {
716
+ $writecount = fwrite($pipes[0], substr($stdin, $written));
717
+ if($writecount === false)
718
+ break;
719
+
720
+ $written += $writecount;
721
+ }
722
+
723
+ fclose($pipes[0]);
724
+ }
725
+
726
+ $result = stream_get_contents($pipes[1]);
727
+ fclose($pipes[1]);
728
+
729
+ proc_close($process);
730
+ return $result;
731
+ }
732
+ }
733
+ }
734
+
735
+ return null;
736
+ }
737
+
738
+ public function processCmsContent($content)
739
+ {
740
+ if(strpos($content, '{{') === false)
741
+ return trim($content);
742
+
743
+ $result = $this->runProcess('app/code/community/Codisto/Sync/Helper/CmsContent.php', null, array('pdo', 'curl', 'simplexml'), $content);
744
+ if($result != null)
745
+ return $result;
746
+
747
+ return Mage::helper('cms')->getBlockTemplateProcessor()->filter(trim($content));
748
+ }
749
+
750
+ public function signalOnShutdown($merchants, $msg, $eventtype, $productids)
751
+ {
752
+ try
753
+ {
754
+ if(is_array($productids))
755
+ {
756
+ $syncObject = Mage::getModel('codistosync/sync');
757
+
758
+ $storeVisited = array();
759
+
760
+ foreach($merchants as $merchant)
761
+ {
762
+ $storeId = $merchant['storeid'];
763
+
764
+ if(!isset($storeVisited[$storeId]))
765
+ {
766
+ if($storeId == 0)
767
+ {
768
+ // jump the storeid to first non admin store
769
+ $stores = Mage::getModel('core/store')->getCollection()
770
+ ->addFieldToFilter('is_active', array('neq' => 0))
771
+ ->addFieldToFilter('store_id', array('gt' => 0))
772
+ ->setOrder('store_id', 'ASC');
773
+
774
+ if($stores->getSize() == 1)
775
+ {
776
+ $stores->setPageSize(1)->setCurPage(1);
777
+ $firstStore = $stores->getFirstItem();
778
+ if(is_object($firstStore) && $firstStore->getId())
779
+ {
780
+ $storeId = $firstStore->getId();
781
+ }
782
+ }
783
+ }
784
+
785
+ $syncDb = $this->getSyncPath('sync-'.$storeId.'.db');
786
+
787
+ if($eventtype == Mage_Index_Model_Event::TYPE_DELETE)
788
+ {
789
+ $syncObject->DeleteProduct($syncDb, $productids, $storeId);
790
+ }
791
+ else
792
+ {
793
+ $syncObject->UpdateProducts($syncDb, $productids, $storeId);
794
+ }
795
+
796
+ $storeVisited[$storeId] = 1;
797
+ }
798
+ }
799
+ }
800
+
801
+ $backgroundSignal = $this->runProcessBackground('app/code/community/Codisto/Sync/Helper/Signal.php', array(serialize($merchants), $msg), array('pdo', 'curl', 'simplexml'));
802
+ if($backgroundSignal)
803
+ return;
804
+
805
+ if(!$this->client)
806
+ {
807
+ $this->client = new Zend_Http_Client();
808
+ $this->client->setConfig(array( 'adapter' => 'Zend_Http_Client_Adapter_Curl', 'curloptions' => array(CURLOPT_TIMEOUT => 4, CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_0), 'keepalive' => true, 'maxredirects' => 0 ));
809
+ $this->client->setStream();
810
+ }
811
+
812
+ foreach($merchants as $merchant)
813
+ {
814
+ try
815
+ {
816
+ $this->client->setUri('https://api.codisto.com/'.$merchant['merchantid']);
817
+ $this->client->setHeaders('X-HostKey', $merchant['hostkey']);
818
+ $this->client->setRawData($msg)->request('POST');
819
+ }
820
+ catch(Exception $e)
821
+ {
822
+
823
+ }
824
+ }
825
+ }
826
+ catch(Exception $e)
827
+ {
828
+ Mage::log('error signalling '.$e->getMessage(), null, 'codisto.log');
829
+ }
830
+ }
831
+
832
+ public function signal($merchants, $msg, $eventtype = null, $productids = null)
833
+ {
834
+ register_shutdown_function(array($this, 'signalOnShutdown'), $merchants, $msg, $eventtype, $productids);
835
+ }
836
+
837
+ }
app/code/community/Codisto/Sync/Helper/Signal.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ require_once 'app/Mage.php';
4
+
5
+ Mage::app();
6
+
7
+ $merchants = unserialize($argv[1]);
8
+ $msg = $argv[2];
9
+
10
+ $curlOptions = array( CURLOPT_TIMEOUT => 10 );
11
+
12
+ if(isset($_ENV['CURL_CA_BUNDLE']) && $_ENV['CURL_CA_BUNDLE'])
13
+ {
14
+ $curlOptions[CURLOPT_CAINFO] = $_ENV['CURL_CA_BUNDLE'];
15
+ }
16
+
17
+ $client = new Zend_Http_Client();
18
+ $client->setConfig(array( 'adapter' => 'Zend_Http_Client_Adapter_Curl', 'curloptions' => $curlOptions, 'keepalive' => true, 'maxredirects' => 0 ));
19
+ $client->setStream();
20
+
21
+ foreach($merchants as $merchant)
22
+ {
23
+ for($Retry = 0; ; $Retry++)
24
+ {
25
+ try
26
+ {
27
+ $client->setUri('https://api.codisto.com/'.$merchant['merchantid']);
28
+ $client->setHeaders('X-HostKey', $merchant['hostkey']);
29
+ $client->setRawData($msg)->request('POST');
30
+ break;
31
+ }
32
+ catch(Exception $e)
33
+ {
34
+ if($Retry >= 3)
35
+ {
36
+ Mage::logException($e);
37
+ break;
38
+ }
39
+
40
+ usleep(100000);
41
+ continue;
42
+ }
43
+ }
44
+ }
45
+
46
+ ?>
app/code/community/Codisto/Sync/Model/Indexer/Ebay.php ADDED
@@ -0,0 +1,551 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Codisto eBay Sync Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * @category Codisto
16
+ * @package Codisto_Sync
17
+ * @copyright Copyright (c) 2015 On Technology Pty. Ltd. (http://codisto.com/)
18
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
19
+ */
20
+
21
+ class Codisto_Sync_Model_Indexer_Ebay extends Mage_Index_Model_Indexer_Abstract
22
+ {
23
+
24
+ const EVENT_MATCH_RESULT_KEY = 'codisto_sync_match_result';
25
+
26
+ public function getName()
27
+ {
28
+ return 'eBay Index';
29
+ }
30
+
31
+ public function getDescription()
32
+ {
33
+ return 'Index Catalog data for synchronisation with eBay';
34
+ }
35
+
36
+ public function matchEvent(Mage_Index_Model_Event $event)
37
+ {
38
+ $data = $event->getNewData();
39
+ $type = $event->getType();
40
+
41
+ if (isset($data[self::EVENT_MATCH_RESULT_KEY])) {
42
+ return $data[self::EVENT_MATCH_RESULT_KEY];
43
+ }
44
+
45
+ $entity = $event->getEntity();
46
+
47
+ if($entity == Mage_Catalog_Model_Product::ENTITY)
48
+ {
49
+ if($type == Mage_Index_Model_Event::TYPE_SAVE ||
50
+ $type == Mage_Index_Model_Event::TYPE_DELETE)
51
+ {
52
+ $event->addNewData(self::EVENT_MATCH_RESULT_KEY, true);
53
+ return true;
54
+ }
55
+ }
56
+
57
+ if($entity == Mage_CatalogInventory_Model_Stock_Item::ENTITY)
58
+ {
59
+ if($type == Mage_Index_Model_Event::TYPE_SAVE ||
60
+ $type == Mage_Index_Model_Event::TYPE_DELETE)
61
+ {
62
+ $event->addNewData(self::EVENT_MATCH_RESULT_KEY, true);
63
+ return true;
64
+ }
65
+ }
66
+
67
+ if($entity == Mage_Catalog_Model_Category::ENTITY)
68
+ {
69
+ if($type == Mage_Index_Model_Event::TYPE_SAVE ||
70
+ $type == Mage_Index_Model_Event::TYPE_DELETE)
71
+ {
72
+ $event->addNewData(self::EVENT_MATCH_RESULT_KEY, true);
73
+ }
74
+ return true;
75
+ }
76
+
77
+ if($entity == Mage_Core_Model_Store::ENTITY ||
78
+ $entity == Mage_Core_Model_Store_Group::ENTITY)
79
+ {
80
+ $event->addNewData(self::EVENT_MATCH_RESULT_KEY, true);
81
+ return true;
82
+ }
83
+
84
+ $result = parent::matchEvent($event);
85
+
86
+ $event->addNewData(self::EVENT_MATCH_RESULT_KEY, $result);
87
+
88
+ return $result;
89
+ }
90
+
91
+ protected function _registerEvent(Mage_Index_Model_Event $event)
92
+ {
93
+ $event->addNewData(self::EVENT_MATCH_RESULT_KEY, true);
94
+
95
+ $entity = $event->getEntity();
96
+
97
+ switch ($entity) {
98
+ case Mage_Catalog_Model_Product::ENTITY:
99
+
100
+ $event->addNewData('codisto_sync_product', true);
101
+ break;
102
+
103
+ case Mage_CatalogInventory_Model_Stock_Item::ENTITY:
104
+
105
+ $event->addNewData('codisto_sync_stock', true);
106
+ break;
107
+
108
+ case Mage_Catalog_Model_Category::ENTITY:
109
+
110
+ $event->addNewData('codisto_sync_category', true);
111
+ break;
112
+
113
+ case Mage_Catalog_Model_Convert_Adapter_Product::ENTITY:
114
+
115
+ $event->addNewData('codisto_sync_bulkproduct', true);
116
+ break;
117
+
118
+ case Mage_Core_Model_Store::ENTITY:
119
+ case Mage_Core_Model_Store_Group::ENTITY:
120
+
121
+ $event->addNewData('codisto_sync_store', true);
122
+ break;
123
+ }
124
+ return $this;
125
+ }
126
+
127
+ protected function _processEvent(Mage_Index_Model_Event $event)
128
+ {
129
+ $data = $event->getNewData();
130
+ $type = $event->getType();
131
+
132
+ if(isset($data['codisto_sync_category']))
133
+ {
134
+ if($event->getDataObject())
135
+ {
136
+ $helper = Mage::helper('codistosync');
137
+
138
+ $syncedCategories = Mage::registry('codisto_synced_categories');
139
+ if(!is_array($syncedCategories))
140
+ {
141
+ $syncedCategories = array();
142
+ }
143
+
144
+ // always synchronise the admin store on any edit
145
+ $syncStores = array(0);
146
+
147
+ $eventData = $event->getDataObject()->getData();
148
+ $storeId = isset($eventData['store_id']) ? $eventData['store_id'] : 0;
149
+ if(!isset($storeId) || !$storeId)
150
+ $storeId = 0;
151
+
152
+ if($storeId != 0)
153
+ {
154
+ $defaultMerchantId = Mage::getConfig()->getNode('stores/admin/codisto/merchantid');
155
+ $storeMerchantId = Mage::getStoreConfig('codisto/merchantid', $storeId);
156
+
157
+ // if the default Codisto merchantid is different at this store level
158
+ // explicitly synchronise it as well
159
+ if($defaultMerchantId != $storeMerchantId)
160
+ {
161
+ $syncStores[] = $storeId;
162
+ }
163
+ }
164
+ else
165
+ {
166
+ $defaultMerchantId = Mage::getConfig()->getNode('stores/admin/codisto/merchantid');
167
+
168
+ $stores = Mage::getModel('core/store')->getCollection();
169
+
170
+ if($stores->count() > 1)
171
+ {
172
+ foreach($stores as $store)
173
+ {
174
+ if($store->getId() != 0)
175
+ {
176
+ $storeMerchantId = Mage::getStoreConfig('codisto/merchantid', $store->getId());
177
+
178
+ if($defaultMerchantId != $storeMerchantId)
179
+ {
180
+ $syncStores[] = $store->getId();
181
+ }
182
+ }
183
+ }
184
+ }
185
+ }
186
+
187
+ $syncObject = Mage::getModel('codistosync/sync');
188
+
189
+ $categoryId = $event->getDataObject()->getId();
190
+
191
+ if(!in_array($categoryId, $syncedCategories))
192
+ {
193
+ $syncedCategories[] = $categoryId;
194
+
195
+ Mage::unregister('codisto_synced_categories');
196
+ Mage::register('codisto_synced_categories', $syncedCategories);
197
+
198
+ $merchants = array();
199
+ $merchantSignalled = array();
200
+
201
+ foreach($syncStores as $storeId)
202
+ {
203
+ $syncDb = $helper->getSyncPath('sync-'.$storeId.'.db');
204
+
205
+ if(Mage_Index_Model_Event::TYPE_SAVE == $type)
206
+ $syncObject->UpdateCategory($syncDb, $categoryId, $storeId);
207
+ else
208
+ $syncObject->DeleteCategory($syncDb, $categoryId, $storeId);
209
+
210
+ $merchantid = Mage::getStoreConfig('codisto/merchantid', $storeId);
211
+ $hostkey = Mage::getStoreConfig('codisto/hostkey', $storeId);
212
+
213
+ $merchantlist = Zend_Json::decode($merchantid);
214
+ if(!is_array($merchantlist))
215
+ $merchantlist = array($merchantlist);
216
+
217
+ foreach($merchantlist as $merchantid)
218
+ {
219
+ if(!in_array($merchantid, $merchantSignalled, true))
220
+ {
221
+ $merchantSignalled[] = $merchantid;
222
+ $merchants[] = array('merchantid' => $merchantid, 'hostkey' => $hostkey, 'storeid' => $storeId );
223
+ }
224
+ }
225
+ }
226
+
227
+ $helper->signal($merchants, 'action=sync&categoryid='.$categoryId);
228
+ }
229
+ }
230
+ }
231
+
232
+ if(isset($data['codisto_sync_stock']))
233
+ {
234
+ if($event->getDataObject())
235
+ {
236
+ $helper = Mage::helper('codistosync');
237
+
238
+ $syncedProducts = Mage::registry('codisto_synced_products');
239
+ if(!is_array($syncedProducts))
240
+ {
241
+ $syncedProducts = array();
242
+ }
243
+
244
+ // always synchronise the admin store on any edit
245
+ $syncStores = array(0);
246
+
247
+ $eventData = $event->getDataObject()->getData();
248
+ $storeId = isset($eventData['store_id']) ? $eventData['store_id'] : 0;
249
+ if(!isset($storeId) || !$storeId)
250
+ $storeId = 0;
251
+
252
+ if($storeId != 0)
253
+ {
254
+ $defaultMerchantId = Mage::getConfig()->getNode('stores/admin/codisto/merchantid');
255
+ $storeMerchantId = Mage::getStoreConfig('codisto/merchantid', $storeId);
256
+
257
+ // if the default Codisto merchantid is different at this store level
258
+ // explicitly synchronise it as well
259
+ if($defaultMerchantId != $storeMerchantId)
260
+ {
261
+ $syncStores[] = $storeId;
262
+ }
263
+ }
264
+ else
265
+ {
266
+ $defaultMerchantId = Mage::getConfig()->getNode('stores/admin/codisto/merchantid');
267
+
268
+ $stores = Mage::getModel('core/store')->getCollection();
269
+
270
+ if($stores->count() > 1)
271
+ {
272
+ foreach($stores as $store)
273
+ {
274
+ if($store->getId() != 0)
275
+ {
276
+ $storeMerchantId = Mage::getStoreConfig('codisto/merchantid', $store->getId());
277
+
278
+ if($defaultMerchantId != $storeMerchantId)
279
+ {
280
+ $syncStores[] = $store->getId();
281
+ }
282
+ }
283
+ }
284
+ }
285
+ }
286
+
287
+ $syncObject = Mage::getModel('codistosync/sync');
288
+ $syncIds = Mage::getResourceSingleton('catalog/product_type_configurable')->getParentIdsByChild($event->getDataObject()->getProductId());
289
+ if(!is_array($syncIds))
290
+ $syncIds = array();
291
+ $syncIds[] = $event->getDataObject()->getProductId();
292
+
293
+ $syncIds = array_diff($syncIds, $syncedProducts);
294
+
295
+ if(!empty($syncIds))
296
+ {
297
+ foreach($syncIds as $productid)
298
+ {
299
+ if(!in_array($productid, $syncedProducts))
300
+ {
301
+ $syncedProducts[] = $productid;
302
+ }
303
+ }
304
+
305
+ Mage::unregister('codisto_synced_products');
306
+ Mage::register('codisto_synced_products', $syncedProducts);
307
+
308
+ $productIds = '';
309
+ if(count($syncIds) == 1)
310
+ $productIds = $syncIds[0];
311
+ else
312
+ $productIds = '['.implode(',', $syncIds).']';
313
+
314
+ $merchants = array();
315
+ $merchantSignalled = array();
316
+
317
+ $eventtype = $type;
318
+ if($type == Mage_Index_Model_Event::TYPE_DELETE &&
319
+ count($syncIds) == 1 &&
320
+ $syncIds[0] == $event-getDataObject()->getId())
321
+ {
322
+ $eventtype = Mage_Index_Model_Event::TYPE_DELETE;
323
+ }
324
+ else
325
+ {
326
+ $eventtype = Mage_Index_Model_Event::TYPE_SAVE;
327
+ }
328
+
329
+ foreach($syncStores as $storeId)
330
+ {
331
+ $merchantid = Mage::getStoreConfig('codisto/merchantid', $storeId);
332
+ $hostkey = Mage::getStoreConfig('codisto/hostkey', $storeId);
333
+
334
+ $merchantlist = Zend_Json::decode($merchantid);
335
+ if(!is_array($merchantlist))
336
+ $merchantlist = array($merchantlist);
337
+
338
+ foreach($merchantlist as $merchantid)
339
+ {
340
+ if(!in_array($merchantid, $merchantSignalled, true))
341
+ {
342
+ $merchantSignalled[] = $merchantid;
343
+ $merchants[] = array('merchantid' => $merchantid, 'hostkey' => $hostkey, 'storeid' => $storeId );
344
+ }
345
+ }
346
+ }
347
+
348
+ $helper->signal($merchants, 'action=sync&productid='.$productIds, $eventtype, $syncIds);
349
+ }
350
+ }
351
+ }
352
+
353
+ if(isset($data['codisto_sync_product']))
354
+ {
355
+ if($event->getDataObject())
356
+ {
357
+ $helper = Mage::helper('codistosync');
358
+
359
+ $syncedProducts = Mage::registry('codisto_synced_products');
360
+ if(!is_array($syncedProducts))
361
+ {
362
+ $syncedProducts = array();
363
+ }
364
+
365
+ // always synchronise the admin store on any edit
366
+ $syncStores = array(0);
367
+ $eventData = $event->getDataObject()->getData();
368
+
369
+ $storeId = isset($eventData['store_id']) ? $eventData['store_id'] : 0;
370
+ if(!isset($storeId) || !$storeId)
371
+ $storeId = 0;
372
+
373
+ if($storeId != 0)
374
+ {
375
+ $defaultMerchantId = Mage::getConfig()->getNode('stores/admin/codisto/merchantid');
376
+ $storeMerchantId = Mage::getStoreConfig('codisto/merchantid', $storeId);
377
+
378
+ // if the default Codisto merchantid is different at this store level
379
+ // explicitly synchronise it as well
380
+ if($defaultMerchantId != $storeMerchantId)
381
+ {
382
+ $syncStores[] = $storeId;
383
+ }
384
+ }
385
+ else
386
+ {
387
+ $defaultMerchantId = Mage::getConfig()->getNode('stores/admin/codisto/merchantid');
388
+
389
+ $stores = Mage::getModel('core/store')->getCollection();
390
+
391
+ if($stores->count() > 1)
392
+ {
393
+ foreach($stores as $store)
394
+ {
395
+ if($store->getId() != 0)
396
+ {
397
+ $storeMerchantId = Mage::getStoreConfig('codisto/merchantid', $store->getId());
398
+
399
+ if($defaultMerchantId != $storeMerchantId)
400
+ {
401
+ $syncStores[] = $store->getId();
402
+ }
403
+ }
404
+ }
405
+ }
406
+ }
407
+
408
+ $syncObject = Mage::getModel('codistosync/sync');
409
+ $syncIds = Mage::getResourceSingleton('catalog/product_type_configurable')->getParentIdsByChild($event->getDataObject()->getId());
410
+ if(!is_array($syncIds))
411
+ $syncIds = array();
412
+ $syncIds[] = $event->getDataObject()->getId();
413
+
414
+ $syncIds = array_diff($syncIds, $syncedProducts);
415
+
416
+ if(!empty($syncIds))
417
+ {
418
+ foreach($syncIds as $productid)
419
+ {
420
+ if(!in_array($productid, $syncedProducts))
421
+ {
422
+ $syncedProducts[] = $productid;
423
+ }
424
+ }
425
+
426
+ Mage::unregister('codisto_synced_products');
427
+ Mage::register('codisto_synced_products', $syncedProducts);
428
+
429
+ $productIds = '';
430
+ if(count($syncIds) == 1)
431
+ $productIds = $syncIds[0];
432
+ else
433
+ $productIds = '['.implode(',', $syncIds).']';
434
+
435
+ $merchants = array();
436
+ $merchantSignalled = array();
437
+
438
+ $eventtype = $type;
439
+ if($type == Mage_Index_Model_Event::TYPE_DELETE &&
440
+ count($syncIds) == 1 &&
441
+ $syncIds[0] == $event->getDataObject()->getId())
442
+ {
443
+ $eventtype = Mage_Index_Model_Event::TYPE_DELETE;
444
+ }
445
+ else
446
+ {
447
+ $eventtype = Mage_Index_Model_Event::TYPE_SAVE;
448
+ }
449
+
450
+ foreach($syncStores as $storeId)
451
+ {
452
+ $merchantid = Mage::getStoreConfig('codisto/merchantid', $storeId);
453
+ $hostkey = Mage::getStoreConfig('codisto/hostkey', $storeId);
454
+
455
+ $merchantlist = Zend_Json::decode($merchantid);
456
+ if(!is_array($merchantlist))
457
+ $merchantlist = array($merchantlist);
458
+
459
+ foreach($merchantlist as $merchantid)
460
+ {
461
+ if(!in_array($merchantid, $merchantSignalled, true))
462
+ {
463
+ $merchantSignalled[] = $merchantid;
464
+ $merchants[] = array('merchantid' => $merchantid, 'hostkey' => $hostkey, 'storeid' => $storeId );
465
+ }
466
+ }
467
+ }
468
+
469
+ $helper->signal($merchants, 'action=sync&productid='.$productIds, $eventtype, $syncIds);
470
+ }
471
+ }
472
+ }
473
+
474
+ if(isset($data['codisto_sync_store']))
475
+ {
476
+ if(!Mage::registry('codisto_synced_stores'))
477
+ {
478
+ $helper = Mage::helper('codistosync');
479
+
480
+ $merchants = array();
481
+ $visited = array();
482
+
483
+ $stores = Mage::getModel('core/store')->getCollection();
484
+
485
+ foreach($stores as $store)
486
+ {
487
+ $merchantlist = Zend_Json::decode($store->getConfig('codisto/merchantid'));
488
+ if($merchantlist)
489
+ {
490
+ if(!is_array($merchantlist))
491
+ $merchantlist = array($merchantlist);
492
+
493
+ foreach($merchantlist as $merchantId)
494
+ {
495
+ if(!in_array($merchantId, $visited, true))
496
+ {
497
+ $merchants[] = array( 'merchantid' => $merchantId, 'hostkey' => $store->getConfig('codisto/hostkey'), 'storeid' => $store->getId() );
498
+ $visited[] = $merchantId;
499
+ }
500
+ }
501
+ }
502
+ }
503
+
504
+ unset($visited);
505
+
506
+ Mage::register('codisto_synced_stores', true);
507
+
508
+ $helper->signal($merchants, 'action=syncstores');
509
+ }
510
+ }
511
+
512
+ if(isset($data['codisto_sync_category']))
513
+ {
514
+ $this->reindexAll();
515
+ }
516
+
517
+ }
518
+
519
+ public function reindexAll()
520
+ {
521
+ $helper = Mage::helper('codistosync');
522
+
523
+ $merchants = array();
524
+ $visited = array();
525
+
526
+ $stores = Mage::getModel('core/store')->getCollection();
527
+
528
+ foreach($stores as $store)
529
+ {
530
+ $merchantlist = Zend_Json::decode($store->getConfig('codisto/merchantid'));
531
+ if($merchantlist)
532
+ {
533
+ if(!is_array($merchantlist))
534
+ $merchantlist = array($merchantlist);
535
+
536
+ foreach($merchantlist as $merchantId)
537
+ {
538
+ if(!in_array($merchantId, $visited, true))
539
+ {
540
+ $merchants[] = array( 'merchantid' => $merchantId, 'hostkey' => $store->getConfig('codisto/hostkey'), 'storeid' => $store->getId() );
541
+ $visited[] = $merchantId;
542
+ }
543
+ }
544
+ }
545
+ }
546
+
547
+ unset($visited);
548
+
549
+ $helper->signal($merchants, 'action=sync');
550
+ }
551
+ }
app/code/community/Codisto/Sync/Model/Observer.php ADDED
@@ -0,0 +1,795 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Codisto eBay Sync Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * @category Codisto
16
+ * @package Codisto_Sync
17
+ * @copyright Copyright (c) 2015 On Technology Pty. Ltd. (http://codisto.com/)
18
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
19
+ */
20
+
21
+ class Codisto_Sync_Model_Observer
22
+ {
23
+
24
+ public function cronSync($synctype)
25
+ {
26
+ $SyncTimeout = 600;
27
+ $Sleep = 100000;
28
+ $ConfigurableCount = 6;
29
+ $SimpleCount = 250;
30
+
31
+ $helper = Mage::helper('codistosync');
32
+
33
+ $file = new Varien_Io_File();
34
+
35
+ $indexer = Mage::getModel('index/process')->load('codistoebayindex', 'indexer_code');
36
+
37
+ try
38
+ {
39
+ if($indexer->load('codistoebayindex', 'indexer_code')->getStatus() == 'working')
40
+ return;
41
+
42
+ $extSyncFailed = $helper->getSyncPath('codisto-external-sync-failed');
43
+ $extTestFailed = $helper->getSyncPath('codisto-external-test-failed');
44
+
45
+ if(!file_exists($extSyncFailed) && !file_exists($extTestFailed)) {
46
+ return 'External sync has not failed, manual sync not run';
47
+ }
48
+
49
+ $merchants = array();
50
+ $visited = array();
51
+
52
+ $stores = Mage::getModel('core/store')->getCollection();
53
+ foreach($stores as $store)
54
+ {
55
+ $merchantlist = Zend_Json::decode($store->getConfig('codisto/merchantid'));
56
+
57
+ if($merchantlist)
58
+ {
59
+ if(!is_array($merchantlist))
60
+ $merchantlist = array($merchantlist);
61
+
62
+ foreach($merchantlist as $merchantId)
63
+ {
64
+ if(!in_array($merchantId, $visited, true))
65
+ {
66
+ $merchants[] = array( 'merchantid' => $merchantId, 'hostkey' => $store->getConfig('codisto/hostkey'), 'storeid' => $store->getId() );
67
+ $visited[] = $merchantId;
68
+ }
69
+ }
70
+ }
71
+ }
72
+
73
+ $merchantlist = Zend_Json::decode(Mage::getStoreConfig('codisto/merchantid', 0));
74
+ if($merchantlist)
75
+ {
76
+ $HostKey = Mage::getStoreConfig('codisto/hostkey', 0);
77
+
78
+ if(!is_array($merchantlist))
79
+ $merchantlist = array($merchantlist);
80
+
81
+ foreach($merchantlist as $merchantId)
82
+ {
83
+ if(!in_array($merchantId, $visited, true))
84
+ {
85
+ $merchants[] = array( 'merchantid' => $merchantId, 'hostkey' => $HostKey, 'storeid' => 0);
86
+ $visited[] = $merchantId;
87
+ }
88
+ }
89
+ }
90
+
91
+ unset($visited);
92
+
93
+ $client = new Zend_Http_Client();
94
+ $client->setConfig(array( 'keepalive' => false, 'maxredirects' => 0, 'timeout' => 30 ));
95
+ $client->setStream();
96
+
97
+ foreach($merchants as $merchant)
98
+ {
99
+ try
100
+ {
101
+ $client->setUri('https://ui.codisto.com/'.$merchant['merchantid'].'/testendpoint/');
102
+ $client->setHeaders('X-HostKey', $merchant['hostkey']);
103
+ $remoteResponse = $client->request('GET');
104
+
105
+ $data = Zend_Json::decode($remoteResponse->getRawBody(), true);
106
+
107
+ if(isset($testdata['ack']) && $testdata['ack'] == "SUCCESS") {
108
+ if(file_exists($extSyncFailed)) {
109
+ unlink($extSyncFailed);
110
+ unlink($extTestFailed);
111
+ }
112
+ break;
113
+ }
114
+
115
+ }
116
+ catch(Exception $e)
117
+ {
118
+
119
+ Mage::log('Error posting to https://ui.codisto.com/testendpoint'.$merchant['merchantid'].'/: ' . $e->getMessage() . ' on line: ' . $e->getLine() . ' in file: ' . $e->getFile() . ' for merchant ' . $merchant['merchantid']);
120
+
121
+ }
122
+ }
123
+
124
+ if(!file_exists($extSyncFailed)) {
125
+ return; //External endpoint now reachable! Manual sync not run
126
+ }
127
+
128
+ if(file_exists($extTestFailed)) {
129
+ return; //Test endpoint again
130
+ }
131
+
132
+
133
+ $file->open( array('path' => $helper->getSyncPath('') ) );
134
+ $lastSyncTime = $file->read('codisto-external-sync-failed');
135
+
136
+ if((microtime(true) - $lastSyncTime) < 1800)
137
+ return; //The manual cron sync has already run in the last 30 mins
138
+
139
+ if($indexer->load('codistoebayindex', 'indexer_code')->getStatus() == 'working')
140
+ return;
141
+
142
+ for($Retry = 0; ; $Retry++)
143
+ {
144
+ try
145
+ {
146
+ $indexer->changeStatus(Mage_Index_Model_Process::STATUS_RUNNING);
147
+ break;
148
+ }
149
+ catch(Exception $e)
150
+ {
151
+ if($Retry >= 3)
152
+ throw $e;
153
+
154
+ usleep(500000);
155
+ continue;
156
+ }
157
+ }
158
+
159
+ $http = new Zend_Http_Client();
160
+ $http->setConfig(array( 'keepalive' => false, 'maxredirects' => 0, 'timeout' => 5 ));
161
+ $http->setStream();
162
+
163
+ foreach($merchants as $merchant)
164
+ {
165
+
166
+ $storeId = $merchant['storeid'];
167
+ $syncObject = Mage::getModel('codistosync/sync');
168
+ $syncDb = $helper->getSyncPath('sync-cron-'.$storeId.'.db');
169
+
170
+ $startTime = microtime(true);
171
+
172
+ for($i = 0;;$i++)
173
+ {
174
+
175
+ try
176
+ {
177
+
178
+ $http->setUri('https://ui.codisto.com/'.$merchant['merchantid'].'/');
179
+ $http->setHeaders(array('Content-Type' => 'multipart/form-data'));
180
+ $http->setHeaders('X-HostKey', $merchant['hostkey']);
181
+ $http->setParameterPost(array('cmd' => 'updatestatus', 'status' => 'inprogress', 'progress' => (20+$i)));
182
+ $response = $http->request('POST');
183
+
184
+ } catch (Exception $e)
185
+ {
186
+ // if we fail to update status - that's ok
187
+ }
188
+
189
+ $result = $syncObject->SyncChunk($syncDb, $SimpleCount, $ConfigurableCount, $storeId, false);
190
+
191
+ if($result == 'complete')
192
+ {
193
+ $syncObject->SyncTax($syncDb, $storeId);
194
+ $syncObject->SyncStores($syncDb, $storeId);
195
+
196
+ for($Retry = 0; ; $Retry++)
197
+ {
198
+ try
199
+ {
200
+ $indexer->changeStatus(Mage_Index_Model_Process::STATUS_PENDING);
201
+ break;
202
+ }
203
+ catch(Exception $e)
204
+ {
205
+ if($Retry >= 3)
206
+ break;
207
+
208
+ usleep(500000);
209
+ }
210
+ }
211
+ break;
212
+ }
213
+
214
+ $now = microtime(true);
215
+
216
+ if(($now - $startTime) > $SyncTimeout)
217
+ {
218
+ break;
219
+ }
220
+
221
+ usleep($Sleep);
222
+ }
223
+
224
+ if($result == 'complete') {
225
+
226
+ try
227
+ {
228
+ $http->setParameterPost(array('cmd' => 'updatestatus', 'status' => 'complete'));
229
+ $response = $http->request('POST');
230
+ }
231
+ catch(Exception $e)
232
+ {
233
+
234
+ }
235
+ }
236
+
237
+ try {
238
+
239
+ if($result == 'complete' && file_exists($syncDb)) {
240
+
241
+ $http->setUri('https://ui.codisto.com/'.$merchant['merchantid'].'/');
242
+ $http->setHeaders(array('Content-Type' => 'multipart/form-data'));
243
+ $http->setParameterPost(array('cmd' => 'pushalldata'));
244
+ $http->setFileUpload($syncDb, 'syncdb');
245
+ $http->setHeaders('X-HostKey', $merchant['hostkey']);
246
+ $response = $http->request('POST');
247
+
248
+ unlink($syncDb);
249
+
250
+ }
251
+
252
+ } catch (Exception $e) {
253
+
254
+ try
255
+ {
256
+
257
+ $http->setUri('https://ui.codisto.com/'.$merchant['merchantid'].'/');
258
+ $http->setHeaders(array('Content-Type' => 'multipart/form-data'));
259
+ $http->setHeaders('X-HostKey', $merchant['hostkey']);
260
+ $http->setParameterPost(array('cmd' => 'updatestatus', 'status' => 'failed'));
261
+ $response = $http->request('POST');
262
+
263
+ } catch (Exception $e)
264
+ {
265
+
266
+ }
267
+
268
+ Mage::log('Error Posting sync data to ui.codisto.com: ' . $e->getMessage() . ' on line: ' . $e->getLine() . ' in file: ' . $e->getFile() . ' for merchant ' . $merchant['merchantid']);
269
+
270
+ }
271
+
272
+ }
273
+
274
+
275
+ $file->write('codisto-external-sync-failed', (string)microtime(true));
276
+
277
+ } catch (Exception $e) {
278
+
279
+ $file->write('codisto-external-sync-failed', 0);
280
+
281
+ Mage::log('Codisto Sync Error: ' . $e->getMessage() . ' on line: ' . $e->getLine() . ' in file: ' . $e->getFile());
282
+
283
+ }
284
+
285
+ for($Retry = 0; ; $Retry++)
286
+ {
287
+ try
288
+ {
289
+ $indexer->changeStatus(Mage_Index_Model_Process::STATUS_PENDING);
290
+ break;
291
+ }
292
+ catch(Exception $e)
293
+ {
294
+ if($Retry >= 3)
295
+ break;
296
+
297
+ usleep(500000);
298
+ continue;
299
+ }
300
+ }
301
+ }
302
+
303
+ public function catalogRuleAfterApply($observer)
304
+ {
305
+ if(Mage::registry('codisto_catalog_rule_after_apply'))
306
+ return;
307
+
308
+ $product = $observer->getProduct();
309
+ if($product || is_numeric($product))
310
+ {
311
+ Mage::register('codisto_catalog_rule_after_apply', 1);
312
+ return;
313
+ }
314
+
315
+ $indexer = Mage::getModel('index/process');
316
+ $indexer->load('codistoebayindex', 'indexer_code');
317
+ $indexer->reindexAll();
318
+
319
+ try
320
+ {
321
+ $indexer->changeStatus(Mage_Index_Model_Process::STATUS_REQUIRE_REINDEX);
322
+ }
323
+ catch(Exception $e)
324
+ {
325
+
326
+ }
327
+ }
328
+
329
+ public function paymentInfoBlockPrepareSpecificInformation($observer)
330
+ {
331
+ $transport = $observer->getEvent()->getTransport();
332
+ $payment = $observer->getEvent()->getPayment();
333
+ $paymentmethod = $payment->getMethodInstance()->getCode();
334
+
335
+ if($paymentmethod == 'ebay' && Mage::getDesign()->getArea() == 'adminhtml')
336
+ {
337
+ $helper = Mage::helper('codistosync');
338
+
339
+ $paypaltransactionid = $payment->getLastTransId();
340
+ $order = $payment->getOrder();
341
+ $orderid = $order->getCodistoOrderid();
342
+ $storeid = $order->getStoreId();
343
+ $merchantid = $helper->getMerchantId($storeid);
344
+
345
+ if($paypaltransactionid)
346
+ {
347
+ $transport['PayPal TransactionID_HTML'] = '<a href="'.htmlspecialchars(Mage::getUrl('', array('_secure' => true))).'codisto/ebaypayment/' . $merchantid . '?orderid='.htmlspecialchars($orderid).'" target="codisto!ebaypayment" class="codisto-ebay-payment-link">'.htmlspecialchars($paypaltransactionid).'</a>';
348
+ $transport['PayPal TransactionID'] = $paypaltransactionid;
349
+ }
350
+
351
+ $additionalInfo = $payment->getData('additional_information');
352
+
353
+ if(is_array($additionalInfo))
354
+ {
355
+ if(isset($additionalInfo['ebaysalesrecordnumber']) &&
356
+ $additionalInfo['ebaysalesrecordnumber'])
357
+ {
358
+ $transport['eBay Sales Record Number_HTML'] = '<a href="'.htmlspecialchars(Mage::getUrl('', array('_secure' => true))).'codisto/ebaysale/' . $merchantid . '?orderid='.htmlspecialchars($orderid).'" target="codisto!ebaysale" class="codisto-ebay-sales-link">'.htmlspecialchars($additionalInfo['ebaysalesrecordnumber']).'</a>';
359
+ $transport['eBay Sales Record Number'] = $additionalInfo['ebaysalesrecordnumber'];
360
+ }
361
+
362
+ if(isset($additionalInfo['ebayuser']) &&
363
+ $additionalInfo['ebayuser'])
364
+ {
365
+ $transport['eBay User_HTML'] = '<a href="'.htmlspecialchars(Mage::getUrl('', array('_secure' => true))).'codisto/ebayuser/' . $merchantid . '?orderid='.htmlspecialchars($orderid).'" target="codisto!ebayuser" class="codisto-ebay-user-link">'.htmlspecialchars($additionalInfo['ebayuser']).'</a>';
366
+ $transport['eBay User'] = $additionalInfo['ebayuser'];
367
+ }
368
+ }
369
+ }
370
+
371
+ return $this;
372
+ }
373
+
374
+ public function taxSettingsChangeAfter(Varien_Event_Observer $observer)
375
+ {
376
+ $merchants = array();
377
+ $visited = array();
378
+
379
+ $helper = Mage::helper('codistosync');
380
+
381
+ $stores = Mage::getModel('core/store')->getCollection();
382
+
383
+ foreach($stores as $store)
384
+ {
385
+ $merchantlist = Zend_Json::decode($store->getConfig('codisto/merchantid'));
386
+ if($merchantlist)
387
+ {
388
+ if(!is_array($merchantlist))
389
+ $merchantlist = array($merchantlist);
390
+
391
+ foreach($merchantlist as $merchantId)
392
+ {
393
+ if(!in_array($merchantId, $visited, true))
394
+ {
395
+ $merchants[] = array( 'merchantid' => $merchantId, 'hostkey' => $store->getConfig('codisto/hostkey'), 'storeid' => $store->getId() );
396
+ $visited[] = $merchantId;
397
+ }
398
+ }
399
+ }
400
+ }
401
+
402
+ $merchantlist = Zend_Json::decode(Mage::getStoreConfig('codisto/merchantid', 0));
403
+ if($merchantlist)
404
+ {
405
+ $HostKey = Mage::getStoreConfig('codisto/hostkey', 0);
406
+
407
+ if(!is_array($merchantlist))
408
+ $merchantlist = array($merchantlist);
409
+
410
+ foreach($merchantlist as $merchantId)
411
+ {
412
+ if(!in_array($merchantId, $visited, true))
413
+ {
414
+ $merchants[] = array( 'merchantid' => $merchantId, 'hostkey' => $HostKey, 'storeid' => 0);
415
+ $visited[] = $merchantId;
416
+ }
417
+ }
418
+ }
419
+
420
+ unset($visited);
421
+
422
+ $helper->signal($merchants, 'action=synctax');
423
+
424
+ return $this;
425
+ }
426
+
427
+ public function salesOrderShipmentSaveAfter(Varien_Event_Observer $observer)
428
+ {
429
+ $shipment = $observer->getEvent()->getShipment();
430
+ $order = $shipment->getOrder();
431
+ $orderid = $order->getCodistoOrderid();
432
+ $storeId = $order->getStoreId();
433
+
434
+ if($orderid)
435
+ {
436
+ $this->signalOrderChange( array( $orderid ), $storeId );
437
+ }
438
+
439
+ return $this;
440
+ }
441
+
442
+ public function salesOrderInvoiceSaveAfter(Varien_Event_Observer $observer)
443
+ {
444
+ $invoice = $observer->getEvent()->getInvoice();
445
+ $order = $invoice->getOrder();
446
+ $orderid = $order->getCodistoOrderid();
447
+ $storeId = $order->getStoreId();
448
+
449
+ if($orderid)
450
+ {
451
+ $this->signalOrderChange( array( $orderid ), $storeId );
452
+ }
453
+
454
+ return $this;
455
+ }
456
+
457
+ public function salesOrderShipmentTrackSaveAfter(Varien_Event_Observer $observer)
458
+ {
459
+ $track = $this->getEvent()->getTrack();
460
+ $shipment = $track->getShipment();
461
+ $order = $shipment->getOrder();
462
+ $orderid = $order->getCodistoOrderid();
463
+ $storeId = $order->getStoreId();
464
+
465
+ if($orderid)
466
+ {
467
+ $this->signalOrderChange( array( $orderid ), $storeId );
468
+ }
469
+ }
470
+
471
+ public function checkoutAllSubmitAfter($observer)
472
+ {
473
+ if ($observer->getEvent()->hasOrders()) {
474
+ $orders = $observer->getEvent()->getOrders();
475
+ } else {
476
+ $orders = array($observer->getEvent()->getOrder());
477
+ }
478
+
479
+ $stockItems = array();
480
+ foreach ($orders as $order) {
481
+ foreach ($order->getAllItems() as $orderItem) {
482
+ if ($orderItem->getQtyOrdered()) {
483
+
484
+ $stockItems[] = $orderItem->getProductId();
485
+
486
+ }
487
+ }
488
+ }
489
+
490
+ if (!empty($stockItems)) {
491
+
492
+ $this->signalStockChange($stockItems);
493
+
494
+ }
495
+
496
+ return $this;
497
+ }
498
+
499
+ public function catalogProductImportFinishBefore($observer)
500
+ {
501
+ $stockItems = array();
502
+ $adapter = $observer->getEvent()->getAdapter();
503
+
504
+ if( $adapter &&
505
+ method_exists( $adapter, 'getAffectedEntityIds' ) )
506
+ {
507
+ $stockItems = $adapter->getAffectedEntityIds();
508
+ }
509
+
510
+ $this->signalStockChange($stockItems);
511
+
512
+ return $this;
513
+ }
514
+
515
+ public function addProductTab($observer)
516
+ {
517
+ $block = $observer->getEvent()->getBlock();
518
+
519
+ if ($block instanceof Mage_Adminhtml_Block_Catalog_Product_Edit_Tabs){
520
+
521
+ $product = Mage::registry('product');
522
+
523
+ $type = $product->getTypeId();
524
+
525
+ if(in_array($type, array('simple', 'configurable', 'grouped')))
526
+ {
527
+ $storeId = $block->getRequest()->getParam('store');
528
+ if(!$storeId)
529
+ $storeId = 0;
530
+
531
+ $merchantId = '';
532
+ $merchantlist = Mage::getStoreConfig('codisto/merchantid', $storeId);
533
+ if($merchantlist)
534
+ {
535
+ $merchantlist = Zend_Json::decode($merchantlist);
536
+ if(is_array($merchantlist))
537
+ $merchantId = $merchantlist[0];
538
+ else
539
+ $merchantId = $merchantlist;
540
+ }
541
+
542
+ $entity_id = $product->getId();
543
+
544
+ $url = preg_replace('/\/index\/product\//', '/product/', Mage::getModel('adminhtml/url')->getUrl('codisto/ebaytab/index', array('product' => $entity_id, 'iframe' => 1)));
545
+ if($merchantId)
546
+ $url .= '?merchantid='.$merchantId.'&storeid='.$storeId;
547
+
548
+ $block->addTab('codisto_ebay_tab', array(
549
+ 'label' => 'eBay',
550
+ 'class' => 'ajax',
551
+ 'url' => $url
552
+ ));
553
+ }
554
+ }
555
+ return $this;
556
+ }
557
+
558
+ public function addScript($observer)
559
+ {
560
+ $helper = Mage::helper('codistosync');
561
+
562
+ $version = $helper->getCodistoVersion();
563
+
564
+ $merchantlist = Mage::getStoreConfig('codisto/merchantid', 0);
565
+ if($merchantlist)
566
+ {
567
+ $merchantlist = Zend_Json::decode($merchantlist);
568
+ if(is_array($merchantlist))
569
+ $merchant = $merchantlist[0];
570
+ else
571
+ $merchant = $merchantlist;
572
+ }
573
+ else
574
+ {
575
+ $merchant = '0';
576
+ }
577
+
578
+ $controller = $observer->getAction();
579
+ $layout = $controller->getLayout();
580
+ $block = $layout->createBlock('core/text');
581
+ $block->setText(
582
+ '<script type="text/javascript">
583
+ window.codisto = {
584
+ merchantid : '.$merchant.'
585
+ };
586
+ (function() {
587
+ var s = document.createElement("script");
588
+ s.src = "https://d31wxntiwn0x96.cloudfront.net/connect/" + window.codisto.merchantid + "/js/app/adminhtml.js?v'.$version.'";
589
+ document.getElementsByTagName("HEAD")[0].appendChild(s);
590
+ })();
591
+ </script>');
592
+
593
+ $jsBlock = $layout->getBlock('js');
594
+ if($jsBlock)
595
+ $jsBlock->append($block);
596
+
597
+ return $this;
598
+ }
599
+
600
+ public function cmsStaticBlockSaveAfter($observer)
601
+ {
602
+ if(is_object($observer))
603
+ {
604
+ $eventData = $observer->getEvent()->getData();
605
+
606
+ if(isset($eventData['data_object']))
607
+ {
608
+ $dataObject = $eventData['data_object'];
609
+
610
+ if(is_subclass_of($dataObject, 'Mage_Core_Model_Abstract'))
611
+ {
612
+ if($dataObject->getResourceName() == 'cms/block')
613
+ {
614
+ $helper = Mage::helper('codistosync');
615
+
616
+ $merchants = array();
617
+ $visited = array();
618
+
619
+ $stores = Mage::getModel('core/store')->getCollection();
620
+
621
+ foreach($stores as $store)
622
+ {
623
+ $merchantlist = Zend_Json::decode($store->getConfig('codisto/merchantid'));
624
+ if($merchantlist)
625
+ {
626
+ if(!is_array($merchantlist))
627
+ $merchantlist = array($merchantlist);
628
+
629
+ foreach($merchantlist as $merchantId)
630
+ {
631
+ if(!in_array($merchantId, $visited, true))
632
+ {
633
+ $merchants[] = array( 'merchantid' => $merchantId, 'hostkey' => $store->getConfig('codisto/hostkey'), 'storeid' => $store->getId() );
634
+ $visited[] = $merchantId;
635
+ }
636
+ }
637
+ }
638
+ }
639
+
640
+ unset($visited);
641
+
642
+ $helper->signal($merchants, 'action=syncstaticblock&id='.rawurlencode($dataObject->getId()).'&identifier='.rawurlencode($dataObject->getIdentifier()).'&content='.rawurlencode($dataObject->getContent()));
643
+ }
644
+ }
645
+ }
646
+ }
647
+
648
+ return $this;
649
+ }
650
+
651
+ private function getMerchants() {
652
+
653
+ $merchants = array();
654
+ $visited = array();
655
+
656
+ $stores = Mage::getModel('core/store')->getCollection();
657
+
658
+ foreach($stores as $store)
659
+ {
660
+ $merchantlist = Zend_Json::decode($store->getConfig('codisto/merchantid'));
661
+ if($merchantlist)
662
+ {
663
+ if(!is_array($merchantlist))
664
+ $merchantlist = array($merchantlist);
665
+
666
+ foreach($merchantlist as $merchantId)
667
+ {
668
+ if(!in_array($merchantId, $visited, true))
669
+ {
670
+ $merchants[] = array( 'merchantid' => $merchantId, 'hostkey' => $store->getConfig('codisto/hostkey'), 'storeid' => $store->getId() );
671
+ $visited[] = $merchantId;
672
+ }
673
+ }
674
+ }
675
+ }
676
+
677
+ $MerchantID = Zend_Json::decode(Mage::getStoreConfig('codisto/merchantid', 0));
678
+ $HostKey = Mage::getStoreConfig('codisto/hostkey', 0);
679
+ if(!in_array($MerchantID, $visited, true))
680
+ $merchants[] = array( 'merchantid' => $MerchantID, 'hostkey' => $HostKey, 'storeid' => 0);
681
+
682
+ unset($visited);
683
+
684
+ return $merchants;
685
+
686
+ }
687
+
688
+ private function signalOrderChange($orderIds, $storeId)
689
+ {
690
+ $helper = Mage::helper('codistosync');
691
+
692
+ $hostkey = Mage::getStoreConfig('codisto/hostkey', $storeId);
693
+
694
+ $merchantList = Zend_Json::decode(Mage::getStoreConfig('codisto/merchantid', $storeId));
695
+ if($merchantList)
696
+ {
697
+ if(!is_array($merchantList))
698
+ $merchantList = array($merchantList);
699
+
700
+ $visited = array();
701
+
702
+ foreach($merchantList as $merchantId)
703
+ {
704
+ if(!in_array($merchantId, $visited, true))
705
+ {
706
+ $merchants[] = array( 'merchantid' => $merchantId, 'hostkey' => $hostkey, 'storeid' => $storeId );
707
+ $visited[] = $merchantId;
708
+ }
709
+ }
710
+
711
+ $helper->signal($merchants, 'action=syncorder&orderid='.$orderid);
712
+ }
713
+ }
714
+
715
+ private function signalStockChange($stockItems)
716
+ {
717
+ if(!empty($stockItems))
718
+ {
719
+ $helper = Mage::helper('codistosync');
720
+
721
+ $merchants = array();
722
+ $visited = array();
723
+
724
+ $stores = Mage::getModel('core/store')->getCollection();
725
+
726
+ foreach($stores as $store)
727
+ {
728
+ $merchantlist = Zend_Json::decode($store->getConfig('codisto/merchantid'));
729
+ if($merchantlist)
730
+ {
731
+ if(!is_array($merchantlist))
732
+ $merchantlist = array($merchantlist);
733
+
734
+ foreach($merchantlist as $merchantId)
735
+ {
736
+ if(!in_array($merchantId, $visited, true))
737
+ {
738
+ $merchants[] = array( 'merchantid' => $merchantId, 'hostkey' => $store->getConfig('codisto/hostkey'), 'storeid' => $store->getId() );
739
+ $visited[] = $merchantId;
740
+ }
741
+ }
742
+ }
743
+ }
744
+
745
+ $MerchantID = Zend_Json::decode(Mage::getStoreConfig('codisto/merchantid', 0));
746
+ $HostKey = Mage::getStoreConfig('codisto/hostkey', 0);
747
+ if(!in_array($MerchantID, $visited, true))
748
+ $merchants[] = array( 'merchantid' => $MerchantID, 'hostkey' => $HostKey, 'storeid' => 0);
749
+
750
+ unset($visited);
751
+
752
+ $syncedProducts = Mage::registry('codisto_synced_products');
753
+ if(!is_array($syncedProducts))
754
+ {
755
+ $syncedProducts = array();
756
+ }
757
+
758
+ $syncIds = array_diff($stockItems, $syncedProducts);
759
+
760
+ if(!empty($syncIds))
761
+ {
762
+ foreach($syncIds as $productid)
763
+ {
764
+ if(!in_array($productid, $syncedProducts))
765
+ {
766
+ $syncedProducts[] = $productid;
767
+ }
768
+ }
769
+
770
+ Mage::unregister('codisto_synced_products');
771
+ Mage::register('codisto_synced_products', $syncedProducts);
772
+
773
+ if(count($syncIds) == 1)
774
+ $productids = $syncIds[0];
775
+ else
776
+ $productids = '['.implode(',', $syncIds).']';
777
+
778
+ $helper->signal($merchants, 'action=sync&productid='.$productids, Mage_Index_Model_Event::TYPE_SAVE, $stockItems);
779
+ }
780
+ }
781
+ }
782
+
783
+
784
+
785
+ /* deprecated */
786
+ public function stockRevertProductsSale($observer)
787
+ {
788
+
789
+ }
790
+
791
+ public function cancelOrderItem($observer)
792
+ {
793
+
794
+ }
795
+ }
app/code/community/Codisto/Sync/Model/Resource/Mysql4/Setup.php ADDED
@@ -0,0 +1,23 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Codisto eBay Sync Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * @category Codisto
16
+ * @package Codisto_Sync
17
+ * @copyright Copyright (c) 2015 On Technology Pty. Ltd. (http://codisto.com/)
18
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
19
+ */
20
+
21
+ class Codisto_Sync_Model_Resource_Mysql4_Setup extends Mage_Core_Model_Resource_Setup {
22
+
23
+ }
app/code/community/Codisto/Sync/Model/Sync.php ADDED
@@ -0,0 +1,2158 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Codisto eBay Sync Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * @category Codisto
16
+ * @package Codisto_Sync
17
+ * @copyright Copyright (c) 2015 On Technology Pty. Ltd. (http://codisto.com/)
18
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
19
+ */
20
+
21
+ class Codisto_Sync_Model_Sync
22
+ {
23
+ private $currentEntityId;
24
+ private $productsProcessed;
25
+ private $ordersProcessed;
26
+
27
+ private $useTaxHelper = true;
28
+
29
+ private $taxCalculation;
30
+ private $rateRequest;
31
+
32
+ private $ebayGroupId;
33
+
34
+ private $attributeCache;
35
+ private $groupCache;
36
+ private $optionCache;
37
+ private $optionTextCache;
38
+
39
+ public function __construct()
40
+ {
41
+ if(method_exists('Mage', 'getEdition'))
42
+ {
43
+ $edition = Mage::getEdition();
44
+ }
45
+ else
46
+ {
47
+ $edition = 'Community';
48
+ }
49
+
50
+ $version = Mage::getVersionInfo();
51
+
52
+ $versionNumber = (int)(
53
+ ((int)$version['major']*10000)+
54
+ ((int)$version['minor']*100)+
55
+ ((int)$version['revision']*10));
56
+
57
+ $this->useTaxHelper = ($edition == 'Enterprise' && $versionNumber > 11300) || ($edition == 'Community' && $versionNumber >= 10810);
58
+
59
+ if(!$this->useTaxHelper)
60
+ {
61
+ $this->taxCalculation = Mage::getModel('tax/calculation');
62
+ }
63
+
64
+ $this->attributeCache = array();
65
+ $this->groupCache = array();
66
+ $this->optionCache = array();
67
+ $this->optionTextCache = array();
68
+
69
+ $ebayGroup = Mage::getModel('customer/group');
70
+ $ebayGroup->load('eBay', 'customer_group_code');
71
+
72
+ $this->ebayGroupId = $ebayGroup->getId();
73
+ if(!$this->ebayGroupId)
74
+ $this->ebayGroupId = Mage_Customer_Model_Group::NOT_LOGGED_IN_ID;
75
+ }
76
+
77
+ private function FilesInDir($dir, $prefix = '')
78
+ {
79
+ $dir = rtrim($dir, '\\/');
80
+ $result = array();
81
+
82
+ try
83
+ {
84
+ if(is_dir($dir))
85
+ {
86
+ $scan = @scandir($dir);
87
+
88
+ if($scan !== false)
89
+ {
90
+ foreach ($scan as $f) {
91
+ if ($f !== '.' and $f !== '..') {
92
+ if (is_dir("$dir/$f")) {
93
+ $result = array_merge($result, $this->FilesInDir("$dir/$f", "$f/"));
94
+ } else {
95
+ $result[] = $prefix.$f;
96
+ }
97
+ }
98
+ }
99
+ }
100
+ }
101
+ }
102
+ catch(Exception $e)
103
+ {
104
+
105
+ }
106
+
107
+ return $result;
108
+ }
109
+
110
+ public function TemplateRead($templateDb)
111
+ {
112
+ $ebayDesignDir = Mage::getBaseDir('design').'/ebay/';
113
+
114
+ try
115
+ {
116
+ $db = $this->GetTemplateDb($templateDb);
117
+
118
+ $insert = $db->prepare('INSERT OR IGNORE INTO File(Name, Content, LastModified) VALUES (?, ?, ?)');
119
+ $update = $db->prepare('UPDATE File SET Content = ?, Changed = -1 WHERE Name = ? AND LastModified != ?');
120
+
121
+ $filelist = $this->FilesInDir(Mage::getBaseDir('design').'/ebay/');
122
+
123
+ $db->exec('BEGIN EXCLUSIVE TRANSACTION');
124
+
125
+ foreach ($filelist as $key => $name)
126
+ {
127
+ try
128
+ {
129
+ $fileName = $ebayDesignDir.$name;
130
+
131
+ if(!in_array($name, array('README')))
132
+ {
133
+ $content = @file_get_contents($fileName);
134
+ if($content !== false)
135
+ {
136
+ $stat = stat($fileName);
137
+
138
+ $lastModified = strftime('%Y-%m-%d %H:%M:%S', $stat['mtime']);
139
+
140
+ $update->bindParam(1, $content);
141
+ $update->bindParam(2, $name);
142
+ $update->bindParam(3, $lastModified);
143
+ $update->execute();
144
+
145
+ if($update->rowCount() == 0)
146
+ {
147
+ $insert->bindParam(1, $name);
148
+ $insert->bindParam(2, $content);
149
+ $insert->bindParam(3, $lastModified);
150
+ $insert->execute();
151
+ }
152
+ }
153
+ }
154
+ }
155
+ catch(Exception $e)
156
+ {
157
+
158
+ }
159
+ }
160
+ $db->exec('COMMIT TRANSACTION');
161
+ }
162
+ catch(Exception $e)
163
+ {
164
+ return $e->getMessage();
165
+ }
166
+
167
+ return 'ok';
168
+ }
169
+
170
+ public function TemplateWrite($templateDb)
171
+ {
172
+ $ebayDesignDir = Mage::getBaseDir('design').'/ebay/';
173
+
174
+ try
175
+ {
176
+ $db = new PDO('sqlite:' . $templateDb);
177
+
178
+ Mage::helper('codistosync')->prepareSqliteDatabase($db);
179
+
180
+ $files = $db->prepare('SELECT Name, Content FROM File');
181
+ $files->execute();
182
+
183
+ $files->bindColumn(1, $name);
184
+ $files->bindColumn(2, $content);
185
+
186
+ while($files->fetch())
187
+ {
188
+ $fileName = $ebayDesignDir.$name;
189
+
190
+ if(strpos($name, '..') === false)
191
+ {
192
+ if(!file_exists($fileName))
193
+ {
194
+ $dir = dirname($fileName);
195
+
196
+ if(!is_dir($dir))
197
+ {
198
+ mkdir($dir.'/', 0755, true);
199
+ }
200
+
201
+ @file_put_contents($fileName, $content);
202
+ }
203
+ }
204
+ }
205
+
206
+ $files->closeCursor();
207
+ }
208
+ catch(Exception $e)
209
+ {
210
+ return $e->getMessage();
211
+ }
212
+
213
+ return 'ok';
214
+ }
215
+
216
+ public function UpdateCategory($syncDb, $id, $storeId)
217
+ {
218
+ $store = Mage::app()->getStore($storeId);
219
+
220
+ $db = $this->GetSyncDb($syncDb);
221
+
222
+ $insertCategory = $db->prepare('INSERT OR REPLACE INTO Category(ExternalReference, Name, ParentExternalReference, LastModified, Enabled, Sequence) VALUES(?,?,?,?,?,?)');
223
+
224
+ $category = Mage::getModel('catalog/category', array('disable_flat' => true))->getCollection()
225
+ ->addAttributeToSelect(array('name', 'image', 'is_active'), 'left')
226
+ ->addAttributeToFilter('entity_id', array('eq' => $id));
227
+
228
+ $db->exec('BEGIN EXCLUSIVE TRANSACTION');
229
+
230
+ Mage::getSingleton('core/resource_iterator')->walk($category->getSelect(), array(array($this, 'SyncCategoryData')), array( 'db' => $db, 'preparedStatement' => $insertCategory, 'store' => $store ));
231
+
232
+ $db->exec('COMMIT TRANSACTION');
233
+ }
234
+
235
+ public function DeleteCategory($syncDb, $id, $storeId)
236
+ {
237
+ $db = $this->GetSyncDb($syncDb);
238
+
239
+ $args = array();
240
+ $args[] = $id;
241
+
242
+ $db->exec('BEGIN EXCLUSIVE TRANSACTION');
243
+
244
+ $db->exec('CREATE TABLE IF NOT EXISTS CategoryDelete(ExternalReference text NOT NULL PRIMARY KEY);'.
245
+ 'INSERT OR IGNORE INTO CategoryDelete VALUES('.$id.');'.
246
+ 'DELETE FROM Category WHERE ExternalReference = '.$id.';'.
247
+ 'DELETE FROM CategoryProduct WHERE CategoryExternalReference = '.$id);
248
+
249
+ $db->exec('COMMIT TRANSACTION');
250
+ }
251
+
252
+ public function UpdateProducts($syncDb, $ids, $storeId)
253
+ {
254
+ $store = Mage::app()->getStore($storeId);
255
+
256
+ $db = $this->GetSyncDb($syncDb);
257
+
258
+ $insertCategoryProduct = $db->prepare('INSERT OR IGNORE INTO CategoryProduct(ProductExternalReference, CategoryExternalReference, Sequence) VALUES(?,?,?)');
259
+ $insertProduct = $db->prepare('INSERT INTO Product(ExternalReference, Type, Code, Name, Price, ListPrice, TaxClass, Description, Enabled, StockControl, StockLevel, Weight, InStore) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
260
+ $checkProduct = $db->prepare('SELECT CASE WHEN EXISTS(SELECT 1 FROM Product WHERE ExternalReference = ?) THEN 1 ELSE 0 END');
261
+ $insertSKU = $db->prepare('INSERT OR IGNORE INTO SKU(ExternalReference, Code, ProductExternalReference, Name, StockControl, StockLevel, Price, Enabled, InStore) VALUES(?,?,?,?,?,?,?,?,?)');
262
+ $insertSKULink = $db->prepare('INSERT OR REPLACE INTO SKULink (SKUExternalReference, ProductExternalReference, Price) VALUES (?, ?, ?)');
263
+ $insertSKUMatrix = $db->prepare('INSERT INTO SKUMatrix(SKUExternalReference, ProductExternalReference, Code, OptionName, OptionValue, ProductOptionExternalReference, ProductOptionValueExternalReference) VALUES(?,?,?,?,?,?,?)');
264
+ $insertImage = $db->prepare('INSERT INTO ProductImage(ProductExternalReference, URL, Tag, Sequence, Enabled) VALUES(?,?,?,?,?)');
265
+ $insertProductOptionValue = $db->prepare('INSERT INTO ProductOptionValue (ExternalReference, Sequence) VALUES (?,?)');
266
+ $insertProductHTML = $db->prepare('INSERT OR IGNORE INTO ProductHTML(ProductExternalReference, Tag, HTML) VALUES (?, ?, ?)');
267
+ $clearAttribute = $db->prepare('DELETE FROM ProductAttributeValue WHERE ProductExternalReference = ?');
268
+ $insertAttribute = $db->prepare('INSERT OR REPLACE INTO Attribute(ID, Code, Label, Type, Input) VALUES (?, ?, ?, ?, ?)');
269
+ $insertAttributeGroup = $db->prepare('INSERT OR IGNORE INTO AttributeGroup(ID, Name) VALUES(?, ?)');
270
+ $insertAttributeGroupMap = $db->prepare('INSERT OR IGNORE INTO AttributeGroupMap(GroupID, AttributeID) VALUES(?,?)');
271
+ $insertProductAttribute = $db->prepare('INSERT OR IGNORE INTO ProductAttributeValue(ProductExternalReference, AttributeID, Value) VALUES (?, ?, ?)');
272
+ $clearProductQuestion = $db->prepare('DELETE FROM ProductQuestionAnswer WHERE ProductQuestionExternalReference IN (SELECT ExternalReference FROM ProductQuestion WHERE ProductExternalReference = ?1); DELETE FROM ProductQuestion WHERE ProductExternalReference = ?1');
273
+ $insertProductQuestion = $db->prepare('INSERT OR REPLACE INTO ProductQuestion(ExternalReference, ProductExternalReference, Name, Type, Sequence) VALUES (?, ?, ?, ?, ?)');
274
+ $insertProductAnswer = $db->prepare('INSERT INTO ProductQuestionAnswer(ProductQuestionExternalReference, Value, PriceModifier, SKUModifier, Sequence) VALUES (?, ?, ?, ?, ?)');
275
+
276
+ $this->productsProcessed = array();
277
+
278
+ $coreResource = Mage::getSingleton('core/resource');
279
+
280
+ $catalogWebsiteName = $coreResource->getTableName('catalog/product_website');
281
+ $storeName = $coreResource->getTableName('core/store');
282
+ $superLinkName = $coreResource->getTableName('catalog/product_super_link');
283
+
284
+ // Configurable products
285
+ $configurableProducts = $this->getProductCollection()
286
+ ->addAttributeToSelect(array('entity_id', 'sku', 'name', 'image', 'description', 'short_description', 'price', 'special_price', 'special_from_date', 'special_to_date', 'status', 'tax_class_id', 'weight'), 'left')
287
+ ->addAttributeToFilter('type_id', array('eq' => 'configurable'));
288
+
289
+ $sqlCheckModified = '(`e`.entity_id IN ('.implode(',', $ids).') OR `e`.entity_id IN (SELECT parent_id FROM `'.$superLinkName.'` WHERE product_id IN ('.implode(',', $ids).')))';
290
+
291
+ $configurableProducts->getSelect()
292
+ ->columns(array('codisto_in_store'=> new Zend_Db_Expr('CASE WHEN `e`.entity_id IN (SELECT product_id FROM `'.$catalogWebsiteName.'` WHERE website_id IN (SELECT website_id FROM `'.$storeName.'` WHERE store_id = '.$storeId.' OR EXISTS(SELECT 1 FROM `'.$storeName.'` WHERE store_id = '.$storeId.' AND website_id = 0))) THEN -1 ELSE 0 END')))
293
+ ->where($sqlCheckModified);
294
+
295
+ // Simple Products not participating as configurable skus
296
+ $simpleProducts = $this->getProductCollection()
297
+ ->addAttributeToSelect(array('entity_id', 'sku', 'name', 'image', 'description', 'short_description', 'price', 'special_price', 'special_from_date', 'special_to_date', 'status', 'tax_class_id', 'weight'), 'left')
298
+ ->addAttributeToFilter('type_id', array('eq' => 'simple'))
299
+ ->addAttributeToFilter('entity_id', array('in' => $ids));
300
+
301
+ $simpleProducts->getSelect()
302
+ ->columns(array('codisto_in_store'=> new Zend_Db_Expr('CASE WHEN `e`.entity_id IN (SELECT product_id FROM `'.$catalogWebsiteName.'` WHERE website_id IN (SELECT website_id FROM `'.$storeName.'` WHERE store_id = '.$storeId.' OR EXISTS(SELECT 1 FROM `'.$storeName.'` WHERE store_id = '.$storeId.' AND website_id = 0))) THEN -1 ELSE 0 END')));
303
+
304
+ $db->exec('BEGIN EXCLUSIVE TRANSACTION');
305
+
306
+ $db->exec('DELETE FROM Product WHERE ExternalReference IN ('.implode(',', $ids).')');
307
+ $db->exec('DELETE FROM ProductImage WHERE ProductExternalReference IN ('.implode(',', $ids).')');
308
+ $db->exec('DELETE FROM ProductHTML WHERE ProductExternalReference IN ('.implode(',', $ids).')');
309
+ $db->exec('DELETE FROM SKUMatrix WHERE ProductExternalReference IN ('.implode(',', $ids).')');
310
+ $db->exec('DELETE FROM SKULink WHERE ProductExternalReference IN ('.implode(',', $ids).')');
311
+ $db->exec('DELETE FROM SKU WHERE ProductExternalReference IN ('.implode(',', $ids).')');
312
+ $db->exec('DELETE FROM ProductQuestionAnswer WHERE ProductQuestionExternalReference IN (SELECT ExternalReference FROM ProductQuestion WHERE ProductExternalReference IN ('.implode(',', $ids).'))');
313
+ $db->exec('DELETE FROM ProductQuestion WHERE ProductExternalReference IN ('.implode(',', $ids).')');
314
+ $db->exec('DELETE FROM CategoryProduct WHERE ProductExternalReference IN ('.implode(',', $ids).')');
315
+
316
+ Mage::getSingleton('core/resource_iterator')->walk($configurableProducts->getSelect(), array(array($this, 'SyncConfigurableProductData')),
317
+ array(
318
+ 'type' => 'configurable',
319
+ 'db' => $db,
320
+ 'preparedStatement' => $insertProduct,
321
+ 'preparedcheckproductStatement' => $checkProduct,
322
+ 'preparedskuStatement' => $insertSKU,
323
+ 'preparedskulinkStatement' => $insertSKULink,
324
+ 'preparedskumatrixStatement' => $insertSKUMatrix,
325
+ 'preparedcategoryproductStatement' => $insertCategoryProduct,
326
+ 'preparedimageStatement' => $insertImage,
327
+ 'preparedproductoptionvalueStatement' => $insertProductOptionValue,
328
+ 'preparedproducthtmlStatement' => $insertProductHTML,
329
+ 'preparedclearattributeStatement' => $clearAttribute,
330
+ 'preparedattributeStatement' => $insertAttribute,
331
+ 'preparedattributegroupStatement' => $insertAttributeGroup,
332
+ 'preparedattributegroupmapStatement' => $insertAttributeGroupMap,
333
+ 'preparedproductattributeStatement' => $insertProductAttribute,
334
+ 'preparedclearproductquestionStatement' => $clearProductQuestion,
335
+ 'preparedproductquestionStatement' => $insertProductQuestion,
336
+ 'preparedproductanswerStatement' => $insertProductAnswer,
337
+ 'store' => $store )
338
+ );
339
+
340
+ Mage::getSingleton('core/resource_iterator')->walk($simpleProducts->getSelect(), array(array($this, 'SyncSimpleProductData')),
341
+ array(
342
+ 'type' => 'simple',
343
+ 'db' => $db,
344
+ 'preparedStatement' => $insertProduct,
345
+ 'preparedcheckproductStatement' => $checkProduct,
346
+ 'preparedcategoryproductStatement' => $insertCategoryProduct,
347
+ 'preparedimageStatement' => $insertImage,
348
+ 'preparedproducthtmlStatement' => $insertProductHTML,
349
+ 'preparedclearattributeStatement' => $clearAttribute,
350
+ 'preparedattributeStatement' => $insertAttribute,
351
+ 'preparedattributegroupStatement' => $insertAttributeGroup,
352
+ 'preparedattributegroupmapStatement' => $insertAttributeGroupMap,
353
+ 'preparedproductattributeStatement' => $insertProductAttribute,
354
+ 'preparedclearproductquestionStatement' => $clearProductQuestion,
355
+ 'preparedproductquestionStatement' => $insertProductQuestion,
356
+ 'preparedproductanswerStatement' => $insertProductAnswer,
357
+ 'store' => $store )
358
+ );
359
+
360
+ $insertProductOptionValue = $db->prepare('INSERT INTO ProductOptionValue (ExternalReference, Sequence) VALUES (?,?)');
361
+
362
+ $options = Mage::getResourceModel('eav/entity_attribute_option_collection')
363
+ ->setPositionOrder('asc', true)
364
+ ->load();
365
+
366
+ foreach($options as $opt){
367
+ $sequence = $opt->getSortOrder();
368
+ $optId = $opt->getId();
369
+ $insertProductOptionValue->execute(array($optId, $sequence));
370
+ }
371
+
372
+ $db->exec('COMMIT TRANSACTION');
373
+ }
374
+
375
+ public function DeleteProduct($syncDb, $ids, $storeId)
376
+ {
377
+ $db = $this->GetSyncDb($syncDb);
378
+
379
+ $db->exec('BEGIN EXCLUSIVE TRANSACTION');
380
+
381
+ if(!is_array($ids))
382
+ {
383
+ $ids = array($ids);
384
+ }
385
+
386
+ foreach($ids as $id)
387
+ {
388
+ $db->exec( 'CREATE TABLE IF NOT EXISTS ProductDelete(ExternalReference text NOT NULL PRIMARY KEY);'.
389
+ 'INSERT OR IGNORE INTO ProductDelete VALUES('.$id.');'.
390
+ 'DELETE FROM Product WHERE ExternalReference = '.$id.';'.
391
+ 'DELETE FROM ProductImage WHERE ProductExternalReference = '.$id.';'.
392
+ 'DELETE FROM ProductHTML WHERE ProductExternalReference = '.$id.';'.
393
+ 'DELETE FROM SKULink WHERE ProductExternalReference = '.$id.';'.
394
+ 'DELETE FROM SKUMatrix WHERE ProductExternalReference = '.$id.';'.
395
+ 'DELETE FROM SKU WHERE ProductExternalReference = '.$id.';'.
396
+ 'DELETE FROM CategoryProduct WHERE ProductExternalReference = '.$id);
397
+ }
398
+
399
+ $db->exec('COMMIT TRANSACTION');
400
+ }
401
+
402
+ public function SyncCategoryData($args)
403
+ {
404
+ $categoryData = $args['row'];
405
+
406
+ if($categoryData['level'] < 2)
407
+ return;
408
+
409
+ $insertSQL = $args['preparedStatement'];
410
+ $insertFields = array('entity_id', 'name', 'parent_id', 'updated_at', 'is_active', 'position');
411
+
412
+ if($categoryData['level'] == 2)
413
+ $categoryData['parent_id'] = 0;
414
+
415
+ $data = array();
416
+ foreach ($insertFields as $key)
417
+ {
418
+
419
+ $value = $categoryData[$key];
420
+
421
+ if(!$value) {
422
+ if($key == 'entity_id') {
423
+ return;
424
+ } else if ($key == 'name') {
425
+ $value = '';
426
+ } else if ($key == 'parent_id') {
427
+ $value = 0;
428
+ } else if ($key == 'updated_at') {
429
+ $value = '1970-01-01 00:00:00';
430
+ } else if ($key == 'is_active') {
431
+ $value = 0;
432
+ } else if ($key == 'position') {
433
+ $value = 0;
434
+ }
435
+ }
436
+
437
+ $data[] = $value;
438
+ }
439
+
440
+ $insertSQL->execute($data);
441
+ }
442
+
443
+ public function SyncProductPrice($store, $parentProduct, $options = null)
444
+ {
445
+ $currentStoreId = $store->getStoreId();
446
+ $currentStoreWebsiteId = $store->getWebsiteId();
447
+ $currentProductWebsiteId = $parentProduct->getWebsiteId();
448
+
449
+ if ($currentProductWebsiteId == 0) {
450
+ $tempStoreId = Mage::app()->getWebsite(true)->getDefaultGroup()->getDefaultStoreId();
451
+ $store->setStoreId($tempStoreId);
452
+ $tempWebsiteId = Mage::app()->getStore($tempStoreId)->getWebsiteId();
453
+ $store->setWebsiteId($tempWebsiteId);
454
+ $parentProduct->setWebsiteId($tempWebsiteId);
455
+ }
456
+
457
+ $addInfo = new Varien_Object();
458
+
459
+ if(is_array($options))
460
+ {
461
+ $addInfo->setData(array(
462
+ 'product' => $parentProduct->getId(),
463
+ 'qty' => 1,
464
+ 'super_attribute' => $options
465
+ ));
466
+ }
467
+ else
468
+ {
469
+ $addInfo->setQty(1);
470
+ }
471
+
472
+ $parentProduct->unsetData('final_price');
473
+
474
+ $parentProduct->getTypeInstance(true)->processConfiguration($addInfo, $parentProduct, Mage_Catalog_Model_Product_Type_Abstract::PROCESS_MODE_LITE);
475
+
476
+ $price = $this->getExTaxPrice($parentProduct, $parentProduct->getFinalPrice(), $store);
477
+
478
+ if ($currentProductWebsiteId == 0) {
479
+ $store->setStoreId($currentStoreId);
480
+ $store->setWebsiteId($currentStoreWebsiteId);
481
+ $parentProduct->setWebsiteId($currentProductWebsiteId);
482
+ }
483
+
484
+ return $price;
485
+ }
486
+
487
+ public function SyncSKUData($args)
488
+ {
489
+ $skuData = $args['row'];
490
+ $db = $args['db'];
491
+
492
+ $store = $args['store'];
493
+
494
+ $insertSKULinkSQL = $args['preparedskulinkStatement'];
495
+ $insertSKUMatrixSQL = $args['preparedskumatrixStatement'];
496
+
497
+ $attributes = $args['attributes'];
498
+
499
+ $product = Mage::getModel('catalog/product');
500
+ $product->setData($skuData)
501
+ ->setStore($store)
502
+ ->setStoreId($store->getId())
503
+ ->setWebsiteId($store->getWebsiteId())
504
+ ->setCustomerGroupId($this->ebayGroupId);
505
+
506
+ $stockItem = Mage::getModel('cataloginventory/stock_item');
507
+ $stockItem->setStockId(Mage_CatalogInventory_Model_Stock::DEFAULT_STOCK_ID)
508
+ ->assignProduct($product);
509
+
510
+ $productParent = $args['parent_product'];
511
+
512
+ $attributeCodes = array();
513
+
514
+ foreach($attributes as $attribute)
515
+ {
516
+ $attributeCodes[] = $attribute->getProductAttribute()->getAttributeCode();
517
+ }
518
+
519
+ $attributeValues = Mage::getResourceSingleton('catalog/product')->getAttributeRawValue($skuData['entity_id'], $attributeCodes, $store->getId());
520
+
521
+ if(!is_array($attributeValues))
522
+ $attributeValues = array( $attributeCodes[0] => $attributeValues );
523
+
524
+ $options = array();
525
+
526
+ foreach($attributes as $attribute)
527
+ {
528
+ $productAttribute = $attribute->getProductAttribute();
529
+
530
+ $options[$productAttribute->getId()] = $attributeValues[$productAttribute->getAttributeCode()];
531
+ }
532
+ $price = $this->SyncProductPrice($store, $productParent, $options);
533
+
534
+ if(!$price)
535
+ $price = 0;
536
+
537
+ $insertSKULinkSQL->execute(array($skuData['entity_id'], $args['parent_id'], $price));
538
+
539
+
540
+ // SKU Matrix
541
+ foreach($attributes as $attribute)
542
+ {
543
+ $productAttribute = $attribute->getProductAttribute();
544
+ $productOptionId = $productAttribute->getId();
545
+ $productOptionValueId = $attributeValues[$productAttribute->getAttributeCode()];
546
+
547
+ if(isset($productOptionValueId))
548
+ {
549
+ $attributeName = $attribute->getLabel();
550
+ $attributeValue = $productAttribute->getSource()->getOptionText($productOptionValueId);
551
+
552
+ $insertSKUMatrixSQL->execute(array(
553
+ $skuData['entity_id'],
554
+ $args['parent_id'],
555
+ '',
556
+ $attributeName,
557
+ $attributeValue,
558
+ $productOptionId,
559
+ $productOptionValueId));
560
+ }
561
+ }
562
+ }
563
+
564
+ public function SyncConfigurableProductData($args)
565
+ {
566
+ $productData = $args['row'];
567
+
568
+ $store = $args['store'];
569
+ $db = $args['db'];
570
+
571
+ $insertSQL = $args['preparedskuStatement'];
572
+ $insertSKULinkSQL = $args['preparedskulinkStatement'];
573
+ $insertCategorySQL = $args['preparedcategoryproductStatement'];
574
+ $insertSKUMatrixSQL = $args['preparedskumatrixStatement'];
575
+
576
+ $this->SyncSimpleProductData(array_merge($args, array('row' => $productData)));
577
+
578
+ $product = Mage::getModel('catalog/product')
579
+ ->setData($productData)
580
+ ->setStore($store)
581
+ ->setStoreId($store->getId())
582
+ ->setWebsiteId($store->getWebsiteId())
583
+ ->setCustomerGroupId($this->ebayGroupId)
584
+ ->setIsSuperMode(true);
585
+
586
+ $configurableData = Mage::getModel('catalog/product_type_configurable');
587
+
588
+ $configurableAttributes = $configurableData->getConfigurableAttributes($product);
589
+
590
+ $childProducts = $configurableData->getUsedProductCollection($product)
591
+ ->addAttributeToSelect(array('price', 'special_price', 'special_from_date', 'special_to_date', 'tax_class_id'), 'left');
592
+
593
+ Mage::getSingleton('core/resource_iterator')->walk($childProducts->getSelect(), array(array($this, 'SyncSKUData')),
594
+ array(
595
+ 'parent_id' => $productData['entity_id'],
596
+ 'parent_product' => $product,
597
+ 'attributes' => $configurableAttributes,
598
+ 'db' => $db,
599
+ 'preparedStatement' => $insertSQL,
600
+ 'preparedskulinkStatement' => $insertSKULinkSQL,
601
+ 'preparedskumatrixStatement' => $insertSKUMatrixSQL,
602
+ 'preparedcategoryproductStatement' => $insertCategorySQL,
603
+ 'store' => $store )
604
+ );
605
+
606
+ $this->productsProcessed[] = $productData['entity_id'];
607
+
608
+ if($productData['entity_id'] > $this->currentEntityId)
609
+ $this->currentEntityId = $productData['entity_id'];
610
+ }
611
+
612
+ public function SyncGroupedProductData($args)
613
+ {
614
+ $productData = $args['row'];
615
+
616
+ $store = $args['store'];
617
+ $db = $args['db'];
618
+
619
+ $insertSQL = $args['preparedskuStatement'];
620
+ $insertSKULinkSQL = $args['preparedskulinkStatement'];
621
+ $insertSKUMatrixSQL = $args['preparedskumatrixStatement'];
622
+
623
+ $product = Mage::getModel('catalog/product')
624
+ ->setData($productData)
625
+ ->setStore($store)
626
+ ->setStoreId($store->getId())
627
+ ->setWebsiteId($store->getWebsiteId())
628
+ ->setCustomerGroupId($this->ebayGroupId)
629
+ ->setIsSuperMode(true);
630
+
631
+ $groupedData = Mage::getModel('catalog/product_type_grouped');
632
+
633
+ $childProducts = $groupedData->getAssociatedProductCollection($product);
634
+ $childProducts->addAttributeToSelect(array('sku', 'name', 'price', 'special_price', 'special_from_date', 'special_to_date'));
635
+
636
+ $skulinkArgs = array();
637
+ $skumatrixArgs = array();
638
+
639
+ $minPrice = 0;
640
+
641
+ $optionValues = array();
642
+
643
+ foreach($childProducts as $childProduct)
644
+ {
645
+ $childProduct
646
+ ->setStore($store)
647
+ ->setStoreId($store->getId())
648
+ ->setWebsiteId($store->getWebsiteId())
649
+ ->setCustomerGroupId($this->ebayGroupId)
650
+ ->setIsSuperMode(true);
651
+
652
+ $price = $this->SyncProductPrice($store, $childProduct);
653
+
654
+ if($minPrice == 0)
655
+ $minPrice = $price;
656
+ else
657
+ $minPrice = min($minPrice, $price);
658
+
659
+ $skulinkArgs[] = array($childProduct->getId(), $productData['entity_id'], $price);
660
+ $skumatrixArgs[] = array($childProduct->getId(), $productData['entity_id'], '', 'Option', $childProduct->getName(), 0, 0);
661
+
662
+ if(isset($optionValues[$childProduct->getName()]))
663
+ $optionValues[$childProduct->getName()]++;
664
+ else
665
+ $optionValues[$childProduct->getName()] = 1;
666
+ }
667
+
668
+ foreach($optionValues as $key => $count)
669
+ {
670
+ if($count > 1)
671
+ {
672
+ $i = 0;
673
+
674
+ foreach($childProducts as $childProduct)
675
+ {
676
+ if($childProduct->getName() == $key)
677
+ {
678
+ $skumatrixArg = &$skumatrixArgs[$i];
679
+ $skumatrixArg[4] = $childProduct->getSku().' - '.$childProduct->getName();
680
+ }
681
+
682
+ $i++;
683
+ }
684
+ }
685
+ }
686
+
687
+ $productData['price'] = $minPrice;
688
+ $productData['final_price'] = $minPrice;
689
+ $productData['minimal_price'] = $minPrice;
690
+ $productData['min_price'] = $minPrice;
691
+ $productData['max_price'] = $minPrice;
692
+
693
+ $this->SyncSimpleProductData(array_merge($args, array('row' => $productData)));
694
+
695
+ for($i = 0; $i < count($skulinkArgs); $i++)
696
+ {
697
+ $insertSKULinkSQL->execute($skulinkArgs[$i]);
698
+ $insertSKUMatrixSQL->execute($skumatrixArgs[$i]);
699
+ }
700
+
701
+ $this->productsProcessed[] = $productData['entity_id'];
702
+
703
+ if($productData['entity_id'] > $this->currentEntityId)
704
+ $this->currentEntityId = $productData['entity_id'];
705
+ }
706
+
707
+ public function SyncSimpleProductData($args)
708
+ {
709
+ $type = $args['type'];
710
+
711
+ $db = $args['db'];
712
+
713
+ $parentids;
714
+
715
+ $store = $args['store'];
716
+ $productData = $args['row'];
717
+
718
+ $product_id = $productData['entity_id'];
719
+
720
+ if(isset($args['preparedcheckproductStatement']))
721
+ {
722
+ $checkProductSQL = $args['preparedcheckproductStatement'];
723
+ $checkProductSQL->execute(array($product_id));
724
+ if($checkProductSQL->fetchColumn())
725
+ {
726
+ $checkProductSQL->closeCursor();
727
+ return;
728
+ }
729
+ $checkProductSQL->closeCursor();
730
+ }
731
+
732
+ $product = Mage::getModel('catalog/product');
733
+ $product->setData($productData)
734
+ ->setStore($store)
735
+ ->setStoreId($store->getId())
736
+ ->setWebsiteId($store->getWebsiteId())
737
+ ->setCustomerGroupId($this->ebayGroupId)
738
+ ->setIsSuperMode(true);
739
+
740
+ $stockItem = Mage::getModel('cataloginventory/stock_item');
741
+ $stockItem->setStockId(Mage_CatalogInventory_Model_Stock::DEFAULT_STOCK_ID)
742
+ ->assignProduct($product);
743
+
744
+ $insertSQL = $args['preparedStatement'];
745
+ $insertCategorySQL = $args['preparedcategoryproductStatement'];
746
+ $insertImageSQL = $args['preparedimageStatement'];
747
+ $insertHTMLSQL = $args['preparedproducthtmlStatement'];
748
+ $clearAttributeSQL = $args['preparedclearattributeStatement'];
749
+ $insertAttributeSQL = $args['preparedattributeStatement'];
750
+ $insertAttributeGroupSQL = $args['preparedattributegroupStatement'];
751
+ $insertAttributeGroupMapSQL = $args['preparedattributegroupmapStatement'];
752
+ $insertProductAttributeSQL = $args['preparedproductattributeStatement'];
753
+ $clearProductQuestionSQL = $args['preparedclearproductquestionStatement'];
754
+ $insertProductQuestionSQL = $args['preparedproductquestionStatement'];
755
+ $insertProductAnswerSQL = $args['preparedproductanswerStatement'];
756
+
757
+ $price = $this->SyncProductPrice($store, $product);
758
+
759
+ $listPrice = $this->getExTaxPrice($product, $product->getPrice(), $store);
760
+ if(!is_numeric($listPrice))
761
+ $listPrice = $price;
762
+
763
+ $qty = $stockItem->getQty();
764
+ if(!is_numeric($qty))
765
+ $qty = 0;
766
+
767
+ // work around for description not appearing via collection
768
+ if(!isset($productData['description']))
769
+ {
770
+ $description = Mage::getResourceSingleton('catalog/product')->getAttributeRawValue($product_id, 'description', $store->getId());
771
+ }
772
+ else
773
+ {
774
+ $description = $productData['description'];
775
+ }
776
+
777
+ $description = Mage::helper('codistosync')->processCmsContent($description);
778
+ if($type == 'simple' &&
779
+ $description == '')
780
+ {
781
+ if(!isset($parentids))
782
+ {
783
+ $configurableparentids = Mage::getModel('catalog/product_type_configurable')->getParentIdsByChild($product_id);
784
+ $groupedparentids = Mage::getModel('catalog/product_type_grouped')->getParentIdsByChild($product_id);
785
+ $bundleparentids = Mage::getModel('bundle/product_type')->getParentIdsByChild($product_id);
786
+
787
+ $parentids = array_unique(array_merge($configurableparentids, $groupedparentids, $bundleparentids));
788
+ }
789
+
790
+ foreach ($parentids as $parentid) {
791
+
792
+ $description = Mage::getResourceSingleton('catalog/product')->getAttributeRawValue($parentid, 'description', $store->getId());
793
+ if($description)
794
+ {
795
+ $description = Mage::helper('codistosync')->processCmsContent($description);
796
+ break;
797
+ }
798
+
799
+ }
800
+
801
+ if(!$description)
802
+ $description = '';
803
+ }
804
+
805
+ $productName = $productData['name'];
806
+ if(!$productName)
807
+ $productName = '';
808
+
809
+ $data = array();
810
+
811
+ $data[] = $product_id;
812
+ $data[] = $type == 'configurable' ? 'c' : ($type == 'grouped' ? 'g' : 's');
813
+ $data[] = $productData['sku'];
814
+ $data[] = $productName;
815
+ $data[] = $price;
816
+ $data[] = $listPrice;
817
+ $data[] = isset($productData['tax_class_id']) && $productData['tax_class_id'] ? $productData['tax_class_id'] : '';
818
+ $data[] = $description;
819
+ $data[] = $productData['status'] != 1 ? 0 : -1;
820
+ $data[] = $stockItem->getManageStock() ? -1 : 0;
821
+ $data[] = (int)$qty;
822
+ $data[] = isset($productData['weight']) && is_numeric($productData['weight']) ? (float)$productData['weight'] : $productData['weight'];
823
+ $data[] = $productData['codisto_in_store'];
824
+
825
+ $insertSQL->execute($data);
826
+
827
+ $categoryIds = $product->getCategoryIds();
828
+ foreach ($categoryIds as $categoryId) {
829
+ $insertCategorySQL->execute(array($product_id, $categoryId, 0));
830
+ }
831
+
832
+ if(isset($productData['short_description']) && strlen($productData['short_description']) > 0)
833
+ {
834
+ $shortDescription = Mage::helper('codistosync')->processCmsContent($productData['short_description']);
835
+
836
+ $insertHTMLSQL->execute(array($product_id, 'Short Description', $shortDescription));
837
+ }
838
+
839
+ $clearAttributeSQL->execute(array($product_id));
840
+
841
+ $attributeSet = array();
842
+ $attributeCodes = array();
843
+ $attributeTypes = array();
844
+ $attributeCodeIDMap = array();
845
+
846
+ $attributeSetID = $product->getAttributeSetId();
847
+ if(isset($this->attributeCache[$attributeSetID]))
848
+ {
849
+ $attributes = $this->attributeCache[$attributeSetID];
850
+ }
851
+ else
852
+ {
853
+ $attributes = $product->getAttributes();
854
+
855
+ $this->attributeCache[$attributeSetID] = $attributes;
856
+ }
857
+
858
+ foreach($attributes as $attribute)
859
+ {
860
+ $backend = $attribute->getBackEnd();
861
+ if(!$backend->isStatic())
862
+ {
863
+ $attributeID = $attribute->getId();
864
+ $attributeCode = $attribute->getAttributeCode();
865
+ $attributeLabel = $attribute->getStoreLabel();
866
+ $attributeTable = $backend->getTable();
867
+
868
+ $attributeCodeIDMap[$attributeID] = $attributeCode;
869
+
870
+ $attributeTypes[$attributeTable][$attributeID] = $attributeCode;
871
+
872
+ if($attributeLabel)
873
+ {
874
+ $attributeGroupID = $attribute->getAttributeGroupId();
875
+ $attributeGroupName = '';
876
+
877
+ if($attributeGroupID)
878
+ {
879
+ if(isset($this->groupCache[$attributeGroupID]))
880
+ {
881
+ $attributeGroupName = $this->groupCache[$attributeGroupID];
882
+ }
883
+ else
884
+ {
885
+ $attributeGroup = Mage::getModel('catalog/product_attribute_group')->load($attributeGroupID);
886
+
887
+ $attributeGroupName = html_entity_decode($attributeGroup->getAttributeGroupName());
888
+
889
+ $this->groupCache[$attributeGroupID] = $attributeGroupName;
890
+ }
891
+ }
892
+
893
+ $attributeFrontEnd = $attribute->getFrontend();
894
+
895
+ $attributeData = array(
896
+ 'id' => $attributeID,
897
+ 'code' => $attributeCode,
898
+ 'name' => $attribute->getName(),
899
+ 'label' => $attributeLabel,
900
+ 'backend_type' => $attribute->getBackendType(),
901
+ 'frontend_type' => $attributeFrontEnd->getInputType(),
902
+ 'groupid' => $attributeGroupID,
903
+ 'groupname' => $attributeGroupName,
904
+ 'html' => ($attribute->getIsHtmlAllowedOnFront() && $attribute->getIsWysiwygEnabled()) ? true : false,
905
+ 'source_model' => $attribute->getSourceModel()
906
+ );
907
+
908
+ if(!isset($attributeData['frontend_type']) || is_null($attributeData['frontend_type']))
909
+ {
910
+ $attributeData['frontend_type'] = '';
911
+ }
912
+
913
+ if($attributeData['source_model'])
914
+ {
915
+ if(isset($this->optionCache[$store->getId().'-'.$attribute->getId()]))
916
+ {
917
+ $attributeData['source'] = $this->optionCache[$store->getId().'-'.$attribute->getId()];
918
+ }
919
+ else
920
+ {
921
+ try
922
+ {
923
+ $attributeData['source'] = Mage::getModel( $attributeData['source_model'] );
924
+
925
+ if($attributeData['source'])
926
+ {
927
+ $attributeData['source']->setAttribute($attribute);
928
+
929
+ $this->optionCache[$store->getId().'-'.$attribute->getId()] = $attributeData['source'];
930
+ }
931
+ }
932
+ catch(Exception $e)
933
+ {
934
+
935
+ }
936
+ }
937
+ }
938
+ else
939
+ {
940
+ $attributeData['source'] = $attribute->getSource();
941
+ }
942
+
943
+ $attributeSet[] = $attributeData;
944
+ $attributeCodes[] = $attributeCode;
945
+ }
946
+ }
947
+
948
+ }
949
+
950
+ $adapter = Mage::getModel('core/resource')->getConnection(Mage_Core_Model_Resource::DEFAULT_READ_RESOURCE);
951
+
952
+ $attrTypeSelects = array();
953
+
954
+ foreach ($attributeTypes as $table => $_attributes)
955
+ {
956
+ $attrTypeSelect = $adapter->select()
957
+ ->from(array('default_value' => $table), array('attribute_id'))
958
+ ->where('default_value.attribute_id IN (?)', array_keys($_attributes))
959
+ ->where('default_value.entity_type_id = :entity_type_id')
960
+ ->where('default_value.entity_id = :entity_id')
961
+ ->where('default_value.store_id = 0');
962
+
963
+
964
+ if($store->getId() == Mage_Catalog_Model_Abstract::DEFAULT_STORE_ID)
965
+ {
966
+ $attrTypeSelect->columns(array('attr_value' => new Zend_Db_Expr('CAST(value AS CHAR)')), 'default_value');
967
+ $attrTypeSelect->where('default_value.value IS NOT NULL');
968
+ }
969
+ else
970
+ {
971
+ $attrTypeSelect->joinLeft(
972
+ array('store_value' => $table),
973
+ 'store_value.attribute_id = default_value.attribute_id AND store_value.entity_type_id = default_value.entity_type_id AND store_value.entity_id = default_value.entity_id AND store_value.store_id = :store_id ',
974
+ array('attr_value' => new Zend_Db_Expr('CAST(COALESCE(store_value.value, default_value.value) AS CHAR)'))
975
+ );
976
+ $attrTypeSelect->where('store_value.value IS NOT NULL OR default_value.value IS NOT NULL');
977
+ }
978
+
979
+ $attrTypeSelects[] = $attrTypeSelect;
980
+ }
981
+
982
+ $attributeValues = array();
983
+
984
+ $attrSelect = $adapter->select()->union($attrTypeSelects, Zend_Db_Select::SQL_UNION_ALL);
985
+
986
+ $attrArgs = array(
987
+ 'entity_type_id' => 4,
988
+ 'entity_id' => $product_id,
989
+ 'store_id' => $store->getId()
990
+ );
991
+
992
+ $attributeRows = $adapter->fetchPairs($attrSelect, $attrArgs);
993
+ foreach ($attributeRows as $attributeId => $attributeValue)
994
+ {
995
+ $attributeCode = $attributeCodeIDMap[$attributeId];
996
+ $attributeValues[$attributeCode] = $attributeValue;
997
+ }
998
+
999
+ foreach($attributeSet as $attributeData)
1000
+ {
1001
+ if(isset($attributeValues[$attributeData['code']]))
1002
+ $attributeValue = $attributeValues[$attributeData['code']];
1003
+ else
1004
+ $attributeValue = null;
1005
+
1006
+ if(isset($attributeData['source']) &&
1007
+ $attributeData['source_model'] == 'eav/entity_attribute_source_boolean')
1008
+ {
1009
+ $attributeData['backend_type'] = 'boolean';
1010
+
1011
+ if(isset($attributeValue) && $attributeValue)
1012
+ $attributeValue = -1;
1013
+ else
1014
+ $attributeValue = 0;
1015
+ }
1016
+
1017
+ else if($attributeData['html'])
1018
+ {
1019
+ $attributeValue = Mage::helper('codistosync')->processCmsContent($attributeValue);
1020
+ }
1021
+
1022
+ else if( in_array($attributeData['frontend_type'], array( 'select', 'multiselect' ) ) )
1023
+ {
1024
+ if(is_array($attributeValue))
1025
+ {
1026
+ if(isset($attributeData['source']) &&
1027
+ method_exists( $attributeData['source'], 'getOptionText') )
1028
+ {
1029
+ $attributeValueSet = array();
1030
+
1031
+ foreach($attributeValue as $attributeOptionId)
1032
+ {
1033
+ if(isset($this->optionTextCache[$store->getId().'-'.$attributeData['id'].'-'.$attributeOptionId]))
1034
+ {
1035
+ $attributeValueSet[] = $this->optionTextCache[$store->getId().'-'.$attributeData['id'].'-'.$attributeOptionId];
1036
+ }
1037
+ else
1038
+ {
1039
+ try
1040
+ {
1041
+ $attributeText = $attributeData['source']->getOptionText($attributeOptionId);
1042
+
1043
+ $this->optionTextCache[$store->getId().'-'.$attributeData['id'].'-'.$attributeOptionId] = $attributeText;
1044
+
1045
+ $attributeValueSet[] = $attributeText;
1046
+ }
1047
+ catch(Exception $e)
1048
+ {
1049
+
1050
+ }
1051
+ }
1052
+ }
1053
+
1054
+ $attributeValue = $attributeValueSet;
1055
+ }
1056
+ }
1057
+ else
1058
+ {
1059
+ if(isset($attributeData['source']) &&
1060
+ method_exists( $attributeData['source'], 'getOptionText') )
1061
+ {
1062
+ if(isset($this->optionTextCache[$store->getId().'-'.$attributeData['id'].'-'.$attributeValue]))
1063
+ {
1064
+ $attributeValue = $this->optionTextCache[$store->getId().'-'.$attributeData['id'].'-'.$attributeValue];
1065
+ }
1066
+ else
1067
+ {
1068
+ try
1069
+ {
1070
+ $attributeText = $attributeData['source']->getOptionText($attributeValue);
1071
+
1072
+ $this->optionTextCache[$store->getId().'-'.$attributeData['id'].'-'.$attributeValue] = $attributeText;
1073
+
1074
+ $attributeValue = $attributeText;
1075
+ }
1076
+ catch(Exception $e)
1077
+ {
1078
+ $attributeValue = null;
1079
+ }
1080
+ }
1081
+ }
1082
+ }
1083
+ }
1084
+
1085
+ if(isset($attributeValue) && !is_null($attributeValue))
1086
+ {
1087
+ if($attributeData['html'])
1088
+ {
1089
+ $insertHTMLSQL->execute(array($product_id, $attributeData['label'], $attributeValue));
1090
+ }
1091
+
1092
+ $insertAttributeSQL->execute(array($attributeData['id'], $attributeData['name'], $attributeData['label'], $attributeData['backend_type'], $attributeData['frontend_type']));
1093
+
1094
+ if($attributeData['groupid'])
1095
+ {
1096
+ $insertAttributeGroupSQL->execute(array($attributeData['groupid'], $attributeData['groupname']));
1097
+ $insertAttributeGroupMapSQL->execute(array($attributeData['groupid'], $attributeData['id']));
1098
+ }
1099
+
1100
+ if(is_array($attributeValue))
1101
+ $attributeValue = implode(',', $attributeValue);
1102
+
1103
+ $insertProductAttributeSQL->execute(array($product_id, $attributeData['id'], $attributeValue));
1104
+ }
1105
+ }
1106
+
1107
+ $hasImage = false;
1108
+ $product->load('media_gallery');
1109
+
1110
+ $primaryImage = isset($productData['image']) ? $productData['image'] : '';
1111
+
1112
+ foreach ($product->getMediaGallery('images') as $image) {
1113
+
1114
+ $imgURL = $product->getMediaConfig()->getMediaUrl($image['file']);
1115
+
1116
+ $enabled = ($image['disabled'] == 0 ? -1 : 0);
1117
+
1118
+ if($image['file'] == $primaryImage)
1119
+ {
1120
+ $tag = '';
1121
+ $sequence = 0;
1122
+ }
1123
+ else
1124
+ {
1125
+ $tag = $image['label'];
1126
+ if(!$tag)
1127
+ $tag = '';
1128
+ $sequence = $image['position'];
1129
+ if(!$sequence)
1130
+ $sequence = 1;
1131
+ else
1132
+ $sequence++;
1133
+ }
1134
+
1135
+ $insertImageSQL->execute(array($product_id, $imgURL, $tag, $sequence, $enabled));
1136
+
1137
+ $hasImage = true;
1138
+
1139
+ }
1140
+
1141
+ if($type == 'simple' &&
1142
+ !$hasImage)
1143
+ {
1144
+ $mediaAttributeModel = Mage::getResourceSingleton('catalog/product_attribute_backend_media');
1145
+ $mediaConfig = Mage::getSingleton('catalog/product_media_config');
1146
+
1147
+ $baseSequence = 0;
1148
+
1149
+ if(!isset($parentids))
1150
+ {
1151
+ $configurableparentids = Mage::getModel('catalog/product_type_configurable')->getParentIdsByChild($product_id);
1152
+ $groupedparentids = Mage::getModel('catalog/product_type_grouped')->getParentIdsByChild($product_id);
1153
+ $bundleparentids = Mage::getModel('bundle/product_type')->getParentIdsByChild($product_id);
1154
+
1155
+ $parentids = array_unique(array_merge($configurableparentids, $groupedparentids, $bundleparentids));
1156
+ }
1157
+
1158
+ foreach ($parentids as $parentid) {
1159
+
1160
+ $baseImagePath = Mage::getResourceSingleton('catalog/product')->getAttributeRawValue($parentid, 'image', $store->getId());
1161
+
1162
+ if(method_exists($mediaAttributeModel, 'loadGallerySet'))
1163
+ {
1164
+ $mediaGallery = $mediaAttributeModel->loadGallerySet(array($parentid), $store->getId());
1165
+ }
1166
+ else
1167
+ {
1168
+ $parentProduct = Mage::getModel('catalog/product')
1169
+ ->setData(array('entity_id' => $parentid, 'type_id' => 'simple' ));
1170
+
1171
+ $attributes = $parentProduct->getTypeInstance(true)->getSetAttributes($parentProduct);
1172
+ $media_gallery = $attributes['media_gallery'];
1173
+ $backend = $media_gallery->getBackend();
1174
+ $backend->afterLoad($parentProduct);
1175
+
1176
+ $mediaGallery = $parentProduct->getMediaGallery('images');
1177
+ }
1178
+
1179
+ $maxSequence = 0;
1180
+ $baseImageFound = false;
1181
+
1182
+ foreach ($mediaGallery as $image) {
1183
+
1184
+ $imgURL = $mediaConfig->getMediaUrl($image['file']);
1185
+
1186
+ $enabled = ($image['disabled'] == 0 ? -1 : 0);
1187
+
1188
+ if(!$baseImageFound && ($image['file'] == $baseImagePath))
1189
+ {
1190
+ $tag = '';
1191
+ $sequence = 0;
1192
+ $baseImageFound = true;
1193
+ }
1194
+ else
1195
+ {
1196
+ $tag = $image['label'];
1197
+ if(!$tag)
1198
+ $tag = '';
1199
+ $sequence = $image['position'];
1200
+ if(!$sequence)
1201
+ $sequence = 1;
1202
+ else
1203
+ $sequence++;
1204
+
1205
+ $sequence += $baseSequence;
1206
+
1207
+ $maxSequence = max($sequence, $maxSequence);
1208
+ }
1209
+
1210
+ $insertImageSQL->execute(array($product_id, $imgURL, $tag, $sequence, $enabled));
1211
+ }
1212
+
1213
+ $baseSequence = $maxSequence;
1214
+
1215
+ if($baseImageFound)
1216
+ break;
1217
+ }
1218
+ }
1219
+
1220
+
1221
+ // process simple product question/answers
1222
+ $clearProductQuestionSQL->execute(array($product_id));
1223
+
1224
+ $options = $product->getProductOptionsCollection();
1225
+
1226
+ foreach($options as $option)
1227
+ {
1228
+ $optionId = $option->getOptionId();
1229
+ $optionName = $option->getTitle();
1230
+ $optionType = $option->getType();
1231
+ $optionSortOrder = $option->getSortOrder();
1232
+
1233
+ if($optionId && $optionName)
1234
+ {
1235
+ if(!$optionType)
1236
+ $optionType = '';
1237
+
1238
+ if(!$optionSortOrder)
1239
+ $optionSortOrder = 0;
1240
+
1241
+ $insertProductQuestionSQL->execute(array($optionId, $product_id, $optionName, $optionType, $optionSortOrder));
1242
+
1243
+ $values = $option->getValuesCollection();
1244
+
1245
+ foreach($values as $value)
1246
+ {
1247
+ $valueName = $value->getTitle();
1248
+ if(!$valueName)
1249
+ $valueName = '';
1250
+
1251
+ $valuePriceModifier = '';
1252
+ if($value->getPriceType() == 'fixed')
1253
+ {
1254
+ $valuePriceModifier = 'Price + '.$value->getPrice();
1255
+ }
1256
+
1257
+ if($value->getPriceType() == 'percent')
1258
+ {
1259
+ $valuePriceModifier = 'Price * '.($value->getPrice() / 100.0);
1260
+ }
1261
+
1262
+ $valueSkuModifier = $value->getSku();
1263
+ if(!$valueSkuModifier)
1264
+ $valueSkuModifier = '';
1265
+
1266
+ $valueSortOrder = $value->getSortOrder();
1267
+ if(!$valueSortOrder)
1268
+ $valueSortOrder = 0;
1269
+
1270
+ $insertProductAnswerSQL->execute(array($optionId, $valueName, $valuePriceModifier, $valueSkuModifier, $valueSortOrder));
1271
+ }
1272
+ }
1273
+ }
1274
+
1275
+ if($type == 'simple')
1276
+ {
1277
+ $this->productsProcessed[] = $product_id;
1278
+
1279
+ if($product_id > $this->currentEntityId)
1280
+ $this->currentEntityId = $product_id;
1281
+ }
1282
+ }
1283
+
1284
+ public function SyncOrderData($args)
1285
+ {
1286
+ $insertOrdersSQL = $args['preparedStatement'];
1287
+
1288
+ $orderData = $args['row'];
1289
+
1290
+ $insertOrdersSQL->execute(array($orderData['codisto_orderid'], ($orderData['status'])?$orderData['status']:'processing', $orderData['pay_date'], $orderData['ship_date'], $orderData['carrier'], $orderData['track_number']));
1291
+
1292
+ $this->ordersProcessed[] = $orderData['entity_id'];
1293
+ $this->currentEntityId = $orderData['entity_id'];
1294
+ }
1295
+
1296
+ public function SyncChunk($syncDb, $simpleCount, $configurableCount, $storeId, $first)
1297
+ {
1298
+ $store = Mage::app()->getStore($storeId);
1299
+
1300
+ $db = $this->GetSyncDb($syncDb);
1301
+
1302
+ $insertCategory = $db->prepare('INSERT OR REPLACE INTO Category(ExternalReference, Name, ParentExternalReference, LastModified, Enabled, Sequence) VALUES(?,?,?,?,?,?)');
1303
+ $insertCategoryProduct = $db->prepare('INSERT OR IGNORE INTO CategoryProduct(ProductExternalReference, CategoryExternalReference, Sequence) VALUES(?,?,?)');
1304
+ $insertProduct = $db->prepare('INSERT INTO Product(ExternalReference, Type, Code, Name, Price, ListPrice, TaxClass, Description, Enabled, StockControl, StockLevel, Weight, InStore) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)');
1305
+ $checkProduct = $db->prepare('SELECT CASE WHEN EXISTS(SELECT 1 FROM Product WHERE ExternalReference = ?) THEN 1 ELSE 0 END');
1306
+ $insertSKU = $db->prepare('INSERT OR IGNORE INTO SKU(ExternalReference, Code, ProductExternalReference, Name, StockControl, StockLevel, Price, Enabled, InStore) VALUES(?,?,?,?,?,?,?,?,?)');
1307
+ $insertSKULink = $db->prepare('INSERT OR REPLACE INTO SKULink (SKUExternalReference, ProductExternalReference, Price) VALUES (?, ?, ?)');
1308
+ $insertSKUMatrix = $db->prepare('INSERT INTO SKUMatrix(SKUExternalReference, ProductExternalReference, Code, OptionName, OptionValue, ProductOptionExternalReference, ProductOptionValueExternalReference) VALUES(?,?,?,?,?,?,?)');
1309
+ $insertImage = $db->prepare('INSERT INTO ProductImage(ProductExternalReference, URL, Tag, Sequence, Enabled) VALUES(?,?,?,?,?)');
1310
+ $insertProductOptionValue = $db->prepare('INSERT INTO ProductOptionValue (ExternalReference, Sequence) VALUES (?,?)');
1311
+ $insertProductHTML = $db->prepare('INSERT OR IGNORE INTO ProductHTML(ProductExternalReference, Tag, HTML) VALUES (?, ?, ?)');
1312
+ $clearAttribute = $db->prepare('DELETE FROM ProductAttributeValue WHERE ProductExternalReference = ?');
1313
+ $insertAttribute = $db->prepare('INSERT OR REPLACE INTO Attribute(ID, Code, Label, Type, Input) VALUES (?, ?, ?, ?, ?)');
1314
+ $insertAttributeGroup = $db->prepare('INSERT OR REPLACE INTO AttributeGroup(ID, Name) VALUES(?, ?)');
1315
+ $insertAttributeGroupMap = $db->prepare('INSERT OR IGNORE INTO AttributeGroupMap(GroupID, AttributeID) VALUES(?,?)');
1316
+ $insertProductAttribute = $db->prepare('INSERT OR IGNORE INTO ProductAttributeValue(ProductExternalReference, AttributeID, Value) VALUES (?, ?, ?)');
1317
+ $clearProductQuestion = $db->prepare('DELETE FROM ProductQuestionAnswer WHERE ProductQuestionExternalReference IN (SELECT ExternalReference FROM ProductQuestion WHERE ProductExternalReference = ?1); DELETE FROM ProductQuestion WHERE ProductExternalReference = ?1');
1318
+ $insertProductQuestion = $db->prepare('INSERT OR REPLACE INTO ProductQuestion(ExternalReference, ProductExternalReference, Name, Type, Sequence) VALUES (?, ?, ?, ?, ?)');
1319
+ $insertProductAnswer = $db->prepare('INSERT INTO ProductQuestionAnswer(ProductQuestionExternalReference, Value, PriceModifier, SKUModifier, Sequence) VALUES (?, ?, ?, ?, ?)');
1320
+ $insertOrders = $db->prepare('INSERT OR REPLACE INTO [Order] (ID, Status, PaymentDate, ShipmentDate, Carrier, TrackingNumber) VALUES (?, ?, ?, ?, ?, ?)');
1321
+
1322
+ $db->exec('BEGIN EXCLUSIVE TRANSACTION');
1323
+
1324
+ $qry = $db->query('SELECT entity_id FROM Progress');
1325
+
1326
+ $this->currentEntityId = $qry->fetchColumn();
1327
+ if(!$this->currentEntityId)
1328
+ $this->currentEntityId = 0;
1329
+
1330
+ $qry->closeCursor();
1331
+
1332
+ $qry = $db->query('SELECT State FROM Progress');
1333
+
1334
+ $state = $qry->fetchColumn();
1335
+
1336
+ $qry->closeCursor();
1337
+
1338
+ $tablePrefix = Mage::getConfig()->getTablePrefix();
1339
+
1340
+ if(!$state)
1341
+ {
1342
+ // Configuration
1343
+ $config = array(
1344
+ 'baseurl' => Mage::getBaseUrl(),
1345
+ 'skinurl' => Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_SKIN),
1346
+ 'mediaurl' => Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_MEDIA),
1347
+ 'jsurl' => Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_JS),
1348
+ 'storeurl' => Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_WEB),
1349
+ 'theme' => Mage::getDesign()->getTheme('frontend')
1350
+ );
1351
+
1352
+ $imagepdf = Mage::getStoreConfig('sales/identity/logo', $store);
1353
+ $imagehtml = Mage::getStoreConfig('sales/identity/logo_html', $store);
1354
+
1355
+ $path = null;
1356
+ if($imagepdf) {
1357
+ $path = Mage::getBaseDir('media') . '/sales/store/logo/' . $imagepdf;
1358
+ }
1359
+ if($imagehtml) {
1360
+ $path = Mage::getBaseDir('media') . '/sales/store/logo_html/' . $imagehtml;
1361
+ }
1362
+
1363
+ if($path) {
1364
+
1365
+ //Invoice and Packing Slip image location isn't accessible from frontend place into DB
1366
+ $data = file_get_contents($path);
1367
+ $base64 = base64_encode($data);
1368
+
1369
+ $config['logobase64'] = $base64;
1370
+ $config['logourl'] = $path; //still stuff url in so we can get the MIME type to determine extra conversion on the other side
1371
+
1372
+ }
1373
+
1374
+ else {
1375
+
1376
+ $package = Mage::getDesign()->getPackageName();
1377
+ $theme = Mage::getDesign()->getTheme('frontend');
1378
+
1379
+ $config['logourl'] = Mage::getBaseUrl(Mage_Core_Model_Store::URL_TYPE_SKIN) . 'frontend/' .
1380
+ $package . '/' . $theme . '/' . Mage::getStoreConfig('design/header/logo_src', $store);
1381
+
1382
+ }
1383
+
1384
+ $insertConfiguration = $db->prepare('INSERT INTO Configuration(configuration_key, configuration_value) VALUES(?,?)');
1385
+
1386
+ // build configuration table
1387
+ foreach ($config as $key => $value) {
1388
+ $insertConfiguration->execute(array($key, $value));
1389
+ }
1390
+
1391
+ $insertConfiguration->execute(array('currency', $store->getBaseCurrencyCode()));
1392
+ $insertConfiguration->execute(array('defaultcountry', Mage::getStoreConfig('tax/defaults/country', $store)));
1393
+
1394
+ $state = 'simple';
1395
+ }
1396
+
1397
+ $this->productsProcessed = array();
1398
+ $this->ordersProcessed = array();
1399
+
1400
+ $coreResource = Mage::getSingleton('core/resource');
1401
+
1402
+ $catalogWebsiteName = $coreResource->getTableName('catalog/product_website');
1403
+ $storeName = $coreResource->getTableName('core/store');
1404
+
1405
+ if($state == 'simple')
1406
+ {
1407
+ // Simple Products not participating as configurable skus
1408
+ $simpleProducts = $this->getProductCollection()
1409
+ ->addAttributeToSelect(array('entity_id', 'sku', 'name', 'image', 'description', 'short_description', 'price', 'special_price', 'special_from_date', 'special_to_date', 'status', 'tax_class_id', 'weight'), 'left')
1410
+ ->addAttributeToFilter('type_id', array('eq' => 'simple'))
1411
+ ->addAttributeToFilter('entity_id', array('gt' => (int)$this->currentEntityId));
1412
+
1413
+ $simpleProducts->getSelect()
1414
+ ->columns(array('codisto_in_store' => new Zend_Db_Expr('CASE WHEN `e`.entity_id IN (SELECT product_id FROM `'.$catalogWebsiteName.'` WHERE website_id IN (SELECT website_id FROM `'.$storeName.'` WHERE store_id = '.$storeId.' OR EXISTS(SELECT 1 FROM `'.$storeName.'` WHERE store_id = '.$storeId.' AND website_id = 0))) THEN -1 ELSE 0 END')))
1415
+ ->order('entity_id')
1416
+ ->limit($simpleCount);
1417
+ $simpleProducts->setOrder('entity_id', 'ASC');
1418
+
1419
+ Mage::getSingleton('core/resource_iterator')->walk($simpleProducts->getSelect(), array(array($this, 'SyncSimpleProductData')),
1420
+ array(
1421
+ 'type' => 'simple',
1422
+ 'db' => $db,
1423
+ 'preparedStatement' => $insertProduct,
1424
+ 'preparedcheckproductStatement' => $checkProduct,
1425
+ 'preparedcategoryproductStatement' => $insertCategoryProduct,
1426
+ 'preparedimageStatement' => $insertImage,
1427
+ 'preparedproducthtmlStatement' => $insertProductHTML,
1428
+ 'preparedclearattributeStatement' => $clearAttribute,
1429
+ 'preparedattributeStatement' => $insertAttribute,
1430
+ 'preparedattributegroupStatement' => $insertAttributeGroup,
1431
+ 'preparedattributegroupmapStatement' => $insertAttributeGroupMap,
1432
+ 'preparedproductattributeStatement' => $insertProductAttribute,
1433
+ 'preparedclearproductquestionStatement' => $clearProductQuestion,
1434
+ 'preparedproductquestionStatement' => $insertProductQuestion,
1435
+ 'preparedproductanswerStatement' => $insertProductAnswer,
1436
+ 'store' => $store ));
1437
+
1438
+ if(!empty($this->productsProcessed))
1439
+ {
1440
+ $db->exec('INSERT OR REPLACE INTO Progress (Sentinel, State, entity_id) VALUES (1, \'simple\', '.$this->currentEntityId.')');
1441
+ }
1442
+ else
1443
+ {
1444
+ $state = 'configurable';
1445
+ $this->currentEntityId = 0;
1446
+ }
1447
+ }
1448
+
1449
+ if($state == 'configurable')
1450
+ {
1451
+ // Configurable products
1452
+ $configurableProducts = $this->getProductCollection()
1453
+ ->addAttributeToSelect(array('entity_id', 'sku', 'name', 'image', 'description', 'short_description', 'price', 'special_price', 'special_from_date', 'special_to_date', 'status', 'tax_class_id', 'weight'), 'left')
1454
+ ->addAttributeToFilter('type_id', array('eq' => 'configurable'))
1455
+ ->addAttributeToFilter('entity_id', array('gt' => (int)$this->currentEntityId));
1456
+
1457
+ $configurableProducts->getSelect()
1458
+ ->columns(array('codisto_in_store' => new Zend_Db_Expr('CASE WHEN `e`.entity_id IN (SELECT product_id FROM `'.$catalogWebsiteName.'` WHERE website_id IN (SELECT website_id FROM `'.$storeName.'` WHERE store_id = '.$storeId.' OR EXISTS(SELECT 1 FROM `'.$storeName.'` WHERE store_id = '.$storeId.' AND website_id = 0))) THEN -1 ELSE 0 END')))
1459
+ ->order('entity_id')
1460
+ ->limit($configurableCount);
1461
+ $configurableProducts->setOrder('entity_id', 'ASC');
1462
+
1463
+ Mage::getSingleton('core/resource_iterator')->walk($configurableProducts->getSelect(), array(array($this, 'SyncConfigurableProductData')),
1464
+ array(
1465
+ 'type' => 'configurable',
1466
+ 'db' => $db,
1467
+ 'preparedStatement' => $insertProduct,
1468
+ 'preparedcheckproductStatement' => $checkProduct,
1469
+ 'preparedskuStatement' => $insertSKU,
1470
+ 'preparedskulinkStatement' => $insertSKULink,
1471
+ 'preparedskumatrixStatement' => $insertSKUMatrix,
1472
+ 'preparedcategoryproductStatement' => $insertCategoryProduct,
1473
+ 'preparedimageStatement' => $insertImage,
1474
+ 'preparedproducthtmlStatement' => $insertProductHTML,
1475
+ 'preparedclearattributeStatement' => $clearAttribute,
1476
+ 'preparedattributeStatement' => $insertAttribute,
1477
+ 'preparedattributegroupStatement' => $insertAttributeGroup,
1478
+ 'preparedattributegroupmapStatement' => $insertAttributeGroupMap,
1479
+ 'preparedproductattributeStatement' => $insertProductAttribute,
1480
+ 'preparedclearproductquestionStatement' => $clearProductQuestion,
1481
+ 'preparedproductquestionStatement' => $insertProductQuestion,
1482
+ 'preparedproductanswerStatement' => $insertProductAnswer,
1483
+ 'store' => $store )
1484
+ );
1485
+
1486
+ if(!empty($this->productsProcessed))
1487
+ {
1488
+ $db->exec('INSERT OR REPLACE INTO Progress (Sentinel, State, entity_id) VALUES (1, \'configurable\', '.$this->currentEntityId.')');
1489
+ }
1490
+ else
1491
+ {
1492
+ $state = 'grouped';
1493
+ $this->currentEntityId = 0;
1494
+ }
1495
+ }
1496
+
1497
+ if($state == 'grouped')
1498
+ {
1499
+ // Grouped products
1500
+ $groupedProducts = $this->getProductCollection()
1501
+ ->addAttributeToSelect(array('entity_id', 'sku', 'name', 'image', 'description', 'short_description', 'price', 'special_price', 'special_from_date', 'special_to_date', 'status', 'tax_class_id', 'weight'), 'left')
1502
+ ->addAttributeToFilter('type_id', array('eq' => 'grouped'))
1503
+ ->addAttributeToFilter('entity_id', array('gt' => (int)$this->currentEntityId));
1504
+
1505
+ $groupedProducts->getSelect()
1506
+ ->columns(array('codisto_in_store' => new Zend_Db_Expr('CASE WHEN `e`.entity_id IN (SELECT product_id FROM `'.$catalogWebsiteName.'` WHERE website_id IN (SELECT website_id FROM `'.$storeName.'` WHERE store_id = '.$storeId.' OR EXISTS(SELECT 1 FROM `'.$storeName.'` WHERE store_id = '.$storeId.' AND website_id = 0))) THEN -1 ELSE 0 END')))
1507
+ ->order('entity_id')
1508
+ ->limit($configurableCount);
1509
+ $groupedProducts->setOrder('entity_id', 'ASC');
1510
+
1511
+ Mage::getSingleton('core/resource_iterator')->walk($groupedProducts->getSelect(), array(array($this, 'SyncGroupedProductData')),
1512
+ array(
1513
+ 'type' => 'grouped',
1514
+ 'db' => $db,
1515
+ 'preparedStatement' => $insertProduct,
1516
+ 'preparedcheckproductStatement' => $checkProduct,
1517
+ 'preparedskuStatement' => $insertSKU,
1518
+ 'preparedskulinkStatement' => $insertSKULink,
1519
+ 'preparedskumatrixStatement' => $insertSKUMatrix,
1520
+ 'preparedcategoryproductStatement' => $insertCategoryProduct,
1521
+ 'preparedimageStatement' => $insertImage,
1522
+ 'preparedproducthtmlStatement' => $insertProductHTML,
1523
+ 'preparedclearattributeStatement' => $clearAttribute,
1524
+ 'preparedattributeStatement' => $insertAttribute,
1525
+ 'preparedattributegroupStatement' => $insertAttributeGroup,
1526
+ 'preparedattributegroupmapStatement' => $insertAttributeGroupMap,
1527
+ 'preparedproductattributeStatement' => $insertProductAttribute,
1528
+ 'preparedclearproductquestionStatement' => $clearProductQuestion,
1529
+ 'preparedproductquestionStatement' => $insertProductQuestion,
1530
+ 'preparedproductanswerStatement' => $insertProductAnswer,
1531
+ 'store' => $store )
1532
+ );
1533
+
1534
+ if(!empty($this->productsProcessed))
1535
+ {
1536
+ $db->exec('INSERT OR REPLACE INTO Progress (Sentinel, State, entity_id) VALUES (1, \'grouped\', '.$this->currentEntityId.')');
1537
+ }
1538
+ else
1539
+ {
1540
+ $state = 'orders';
1541
+ $this->currentEntityId = 0;
1542
+ }
1543
+ }
1544
+
1545
+ if($state == 'orders')
1546
+ {
1547
+ if($this->currentEntityId == 0)
1548
+ {
1549
+ $connection = $coreResource->getConnection(Mage_Core_Model_Resource::DEFAULT_WRITE_RESOURCE);
1550
+ try
1551
+ {
1552
+ $connection->addColumn(
1553
+ $tablePrefix . 'sales_flat_order',
1554
+ 'codisto_orderid',
1555
+ 'varchar(10)'
1556
+ );
1557
+ }
1558
+ catch(Exception $e)
1559
+ {
1560
+ }
1561
+ }
1562
+
1563
+ $orderStoreId = $storeId;
1564
+ if($storeId == 0)
1565
+ {
1566
+ $stores = Mage::getModel('core/store')->getCollection()
1567
+ ->addFieldToFilter('is_active', array('neq' => 0))
1568
+ ->addFieldToFilter('store_id', array( 'gt' => 0))
1569
+ ->setOrder('store_id', 'ASC');
1570
+ $stores->setPageSize(1)->setCurPage(1);
1571
+ $orderStoreId = $stores->getFirstItem()->getId();
1572
+ }
1573
+
1574
+ $invoiceName = $coreResource->getTableName('sales/invoice');
1575
+ $shipmentName = $coreResource->getTableName('sales/shipment');
1576
+ $shipmentTrackName = $coreResource->getTableName('sales/shipment_track');
1577
+
1578
+ $ts = Mage::getModel('core/date')->gmtTimestamp();
1579
+ $ts -= 7776000; // 90 days
1580
+
1581
+ $orders = Mage::getModel('sales/order')->getCollection()
1582
+ ->addFieldToSelect(array('codisto_orderid', 'status'))
1583
+ ->addAttributeToFilter('entity_id', array('gt' => (int)$this->currentEntityId ))
1584
+ ->addAttributeToFilter('main_table.store_id', array('eq' => $orderStoreId ))
1585
+ ->addAttributeToFilter('main_table.updated_at', array('gteq' => date('Y-m-d H:i:s', $ts)))
1586
+ ->addAttributeToFilter('main_table.codisto_orderid', array('notnull' => true));
1587
+ $orders->getSelect()->joinLeft( array('i' => $invoiceName), 'i.order_id = main_table.entity_id AND i.state = 2', array('pay_date' => 'MIN(i.created_at)'));
1588
+ $orders->getSelect()->joinLeft( array('s' => $shipmentName), 's.order_id = main_table.entity_id', array('ship_date' => 'MIN(s.created_at)'));
1589
+ $orders->getSelect()->joinLeft( array('t' => $shipmentTrackName), 't.order_id = main_table.entity_id', array('carrier' => 'GROUP_CONCAT(COALESCE(t.title, \'\') SEPARATOR \',\')', 'track_number' => 'GROUP_CONCAT(COALESCE(t.track_number, \'\') SEPARATOR \',\')'));
1590
+ $orders->getSelect()->group(array('main_table.entity_id', 'main_table.codisto_orderid', 'main_table.status'));
1591
+ $orders->getSelect()->limit(1000);
1592
+ $orders->setOrder('entity_id', 'ASC');
1593
+
1594
+ Mage::getSingleton('core/resource_iterator')->walk($orders->getSelect(), array(array($this, 'SyncOrderData')),
1595
+ array(
1596
+ 'db' => $db,
1597
+ 'preparedStatement' => $insertOrders,
1598
+ 'store' => $store )
1599
+ );
1600
+
1601
+ if(!empty($this->ordersProcessed))
1602
+ {
1603
+ $db->exec('INSERT OR REPLACE INTO Progress (Sentinel, State, entity_id) VALUES (1, \'orders\', '.$this->currentEntityId.')');
1604
+ }
1605
+ else
1606
+ {
1607
+ $state = 'productoption';
1608
+ $this->currentEntityId = 0;
1609
+ }
1610
+ }
1611
+
1612
+ if($state == 'productoption')
1613
+ {
1614
+ $db->exec('DELETE FROM ProductOptionValue');
1615
+
1616
+ $insertProductOptionValue = $db->prepare('INSERT INTO ProductOptionValue (ExternalReference, Sequence) VALUES (?,?)');
1617
+
1618
+ $options = Mage::getResourceModel('eav/entity_attribute_option_collection')
1619
+ ->setPositionOrder('asc', true)
1620
+ ->load();
1621
+
1622
+ $insertProductOptionValue->execute(array(0, 0));
1623
+
1624
+ foreach($options as $opt){
1625
+ $sequence = $opt->getSortOrder();
1626
+ $optId = $opt->getId();
1627
+ $insertProductOptionValue->execute(array($optId, $sequence));
1628
+ }
1629
+
1630
+ $state = 'categories';
1631
+ }
1632
+
1633
+ if($state == 'categories')
1634
+ {
1635
+ // Categories
1636
+ $categories = Mage::getModel('catalog/category', array('disable_flat' => true))->getCollection()
1637
+ ->addAttributeToSelect(array('name', 'image', 'is_active', 'updated_at', 'parent_id', 'position'), 'left');
1638
+
1639
+ Mage::getSingleton('core/resource_iterator')->walk($categories->getSelect(), array(array($this, 'SyncCategoryData')), array( 'db' => $db, 'preparedStatement' => $insertCategory, 'store' => $store ));
1640
+
1641
+ $db->exec('INSERT OR REPLACE INTO Progress (Sentinel, State, entity_id) VALUES (1, \'complete\', 0)');
1642
+ }
1643
+
1644
+ $db->exec('COMMIT TRANSACTION');
1645
+
1646
+ if((empty($this->productsProcessed) && empty($this->ordersProcessed)) || $first)
1647
+ {
1648
+ return 'complete';
1649
+ }
1650
+ else
1651
+ {
1652
+ return 'pending';
1653
+ }
1654
+ }
1655
+
1656
+ public function ProductTotals($storeId) {
1657
+
1658
+ $store = Mage::app()->getStore($storeId);
1659
+
1660
+ $configurableProducts = $this->getProductCollection()
1661
+ ->addAttributeToSelect(array('entity_id'), 'left')
1662
+ ->addAttributeToFilter('type_id', array('eq' => 'configurable'));
1663
+
1664
+ $configurablecount = $configurableProducts->getSize();
1665
+
1666
+ $simpleProducts = $this->getProductCollection()
1667
+ ->addAttributeToSelect(array('entity_id'), 'left')
1668
+ ->addAttributeToFilter('type_id', array('eq' => 'simple'));
1669
+
1670
+ $simplecount = $simpleProducts->getSize();
1671
+
1672
+ return array('simplecount' => $simplecount, 'configurablecount' => $configurablecount);
1673
+ }
1674
+
1675
+ public function SyncStaticBlocks($syncDb, $storeId)
1676
+ {
1677
+ $db = $this->GetSyncDb($syncDb);
1678
+
1679
+ $db->exec('BEGIN EXCLUSIVE TRANSACTION');
1680
+
1681
+ $db->exec('DELETE FROM StaticBlock');
1682
+
1683
+ $insertStaticBlock = $db->prepare('INSERT OR IGNORE INTO StaticBlock (BlockID, Title, Identifier, Content) VALUES (?, ?, ?, ?)');
1684
+
1685
+ $staticBlocks = Mage::getModel('cms/block')->getCollection()->addStoreFilter($storeId);
1686
+
1687
+ foreach($staticBlocks as $block)
1688
+ {
1689
+ $BlockID = $block->getId();
1690
+ $Title = $block->getTitle();
1691
+ $Identifier = $block->getIdentifier();
1692
+ $Content = Mage::helper('codistosync')->processCmsContent($block->getContent());
1693
+
1694
+ $insertStaticBlock->bindParam(1, $BlockID);
1695
+ $insertStaticBlock->bindParam(2, $Title);
1696
+ $insertStaticBlock->bindParam(3, $Identifier);
1697
+ $insertStaticBlock->bindParam(4, $Content);
1698
+ $insertStaticBlock->execute();
1699
+ }
1700
+
1701
+ $db->exec('COMMIT TRANSACTION');
1702
+ }
1703
+
1704
+ public function SyncTax($syncDb, $storeId)
1705
+ {
1706
+ $db = $this->GetSyncDb($syncDb);
1707
+
1708
+ $db->exec('BEGIN EXCLUSIVE TRANSACTION');
1709
+
1710
+ $db->exec('DELETE FROM TaxClass');
1711
+ $db->exec('DELETE FROM TaxCalculation');
1712
+ $db->exec('DELETE FROM TaxCalculationRule');
1713
+ $db->exec('DELETE FROM TaxCalculationRate');
1714
+
1715
+ $taxClasses = Mage::getModel('tax/class')->getCollection()
1716
+ ->addFieldToSelect(array('class_id', 'class_type', 'class_name'))
1717
+ ->addFieldToFilter('class_type', array('eq' => 'PRODUCT'));
1718
+
1719
+ $insertTaxClass = $db->prepare('INSERT OR IGNORE INTO TaxClass (ID, Type, Name) VALUES (?, ?, ?)');
1720
+
1721
+ foreach($taxClasses as $taxClass)
1722
+ {
1723
+ $TaxID = $taxClass->getId();
1724
+ $TaxName = $taxClass->getClassName();
1725
+ $TaxType = $taxClass->getClassType();
1726
+
1727
+ $insertTaxClass->bindParam(1, $TaxID);
1728
+ $insertTaxClass->bindParam(2, $TaxType);
1729
+ $insertTaxClass->bindParam(3, $TaxName);
1730
+ $insertTaxClass->execute();
1731
+ }
1732
+
1733
+ $ebayGroup = Mage::getModel('customer/group');
1734
+ $ebayGroup->load('eBay', 'customer_group_code');
1735
+ if(!$ebayGroup->getId())
1736
+ $ebayGroup->load(1);
1737
+
1738
+ $customerTaxClassId = $ebayGroup->getTaxClassId();
1739
+
1740
+ $taxCalcs = Mage::getModel('tax/calculation')->getCollection();
1741
+ if($customerTaxClassId)
1742
+ $taxCalcs->addFieldToFilter('customer_tax_class_id', array('eq' => $customerTaxClassId));
1743
+
1744
+ $insertTaxCalc = $db->prepare('INSERT OR IGNORE INTO TaxCalculation (ID, TaxRateID, TaxRuleID, ProductTaxClassID, CustomerTaxClassID) VALUES (?, ?, ?, ?, ?)');
1745
+
1746
+ $TaxRuleIDs = array();
1747
+
1748
+ foreach($taxCalcs as $taxCalc)
1749
+ {
1750
+ $TaxCalcID = $taxCalc->getId();
1751
+ $TaxRateID = $taxCalc->getTaxCalculationRateId();
1752
+ $TaxRuleID = $taxCalc->getTaxCalculationRuleId();
1753
+ $ProductClass = $taxCalc->getProductTaxClassId();
1754
+ $CustomerClass = $taxCalc->getCustomerTaxClassId();
1755
+
1756
+ $insertTaxCalc->bindParam(1, $TaxCalcID);
1757
+ $insertTaxCalc->bindParam(2, $TaxRateID);
1758
+ $insertTaxCalc->bindParam(3, $TaxRuleID);
1759
+ $insertTaxCalc->bindParam(4, $ProductClass);
1760
+ $insertTaxCalc->bindParam(5, $CustomerClass);
1761
+ $insertTaxCalc->execute();
1762
+
1763
+ $TaxRuleIDs[] = $TaxRuleID;
1764
+ }
1765
+
1766
+ $taxRules = Mage::getModel('tax/calculation_rule')->getCollection()
1767
+ ->addFieldToFilter('tax_calculation_rule_id', array( 'in' => $TaxRuleIDs ));
1768
+
1769
+ $insertTaxRule = $db->prepare('INSERT OR IGNORE INTO TaxCalculationRule (ID, Code, Priority, Position, CalculateSubTotal) VALUES (?, ?, ?, ?, ?)');
1770
+
1771
+ foreach($taxRules as $taxRule)
1772
+ {
1773
+ $TaxRuleID = $taxRule->getId();
1774
+ $TaxRuleCode = $taxRule->getCode();
1775
+ $TaxRulePriority = $taxRule->getPriority();
1776
+ $TaxRulePosition = $taxRule->getPosition();
1777
+ $TaxRuleCalcSubTotal = $taxRule->getCalculateSubtotal();
1778
+
1779
+ $insertTaxRule->bindParam(1, $TaxRuleID);
1780
+ $insertTaxRule->bindParam(2, $TaxRuleCode);
1781
+ $insertTaxRule->bindParam(3, $TaxRulePriority);
1782
+ $insertTaxRule->bindParam(4, $TaxRulePosition);
1783
+ $insertTaxRule->bindParam(5, $TaxRuleCalcSubTotal);
1784
+ $insertTaxRule->execute();
1785
+ }
1786
+
1787
+ $regionName = Mage::getSingleton('core/resource')->getTableName('directory/country_region');
1788
+
1789
+ $taxRates = Mage::getModel('tax/calculation_rate')->getCollection();
1790
+ $taxRates->getSelect()->joinLeft( array('region' => $regionName), 'region.region_id = main_table.tax_region_id', array('tax_region_code' => 'region.code', 'tax_region_name' => 'region.default_name'));
1791
+
1792
+ $insertTaxRate = $db->prepare('INSERT OR IGNORE INTO TaxCalculationRate (ID, Country, RegionID, RegionName, RegionCode, PostCode, Code, Rate, IsRange, ZipFrom, ZipTo) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ? ,?)');
1793
+
1794
+ foreach($taxRates as $taxRate)
1795
+ {
1796
+ $TaxRateID = $taxRate->getId();
1797
+ $TaxCountry = $taxRate->getTaxCountryId();
1798
+ $TaxRegionID = $taxRate->getTaxRegionId();
1799
+ $TaxRegionName = $taxRate->getTaxRegionName();
1800
+ $TaxRegionCode = $taxRate->getTaxRegionCode();
1801
+ $TaxPostCode = $taxRate->getTaxPostcode();
1802
+ $TaxCode = $taxRate->getCode();
1803
+ $TaxRate = $taxRate->getRate();
1804
+ $TaxZipIsRange = $taxRate->getZipIsRange();
1805
+ $TaxZipFrom = $taxRate->getZipFrom();
1806
+ $TaxZipTo = $taxRate->getZipTo();
1807
+
1808
+ $insertTaxRate->execute(array(
1809
+ $TaxRateID,
1810
+ $TaxCountry,
1811
+ $TaxRegionID,
1812
+ $TaxRegionName,
1813
+ $TaxRegionCode,
1814
+ $TaxPostCode,
1815
+ $TaxCode,
1816
+ $TaxRate,
1817
+ $TaxZipIsRange,
1818
+ $TaxZipFrom,
1819
+ $TaxZipTo
1820
+ ));
1821
+ }
1822
+
1823
+ $db->exec('COMMIT TRANSACTION');
1824
+ }
1825
+
1826
+ public function SyncStores($syncDb, $storeId)
1827
+ {
1828
+ $db = $this->GetSyncDb($syncDb);
1829
+
1830
+ $db->exec('BEGIN EXCLUSIVE TRANSACTION');
1831
+ $db->exec('DELETE FROM Store');
1832
+ $db->exec('DELETE FROM StoreMerchant');
1833
+
1834
+ $stores = Mage::getModel('core/store')->getCollection();
1835
+
1836
+ $insertStore = $db->prepare('INSERT OR REPLACE INTO Store (ID, Code, Name, Currency) VALUES (?, ?, ?, ?)');
1837
+ $insertStoreMerchant = $db->prepare('INSERT OR REPLACE INTO StoreMerchant (StoreID, MerchantID) VALUES (?, ?)');
1838
+
1839
+ $StoreID = 0;
1840
+ $StoreCode = 'admin';
1841
+ $StoreName = '';
1842
+ $StoreCurrency = Mage::app()->getStore($StoreID)->getCurrentCurrencyCode();
1843
+
1844
+ $insertStore->execute(array($StoreID, $StoreCode, $StoreName, $StoreCurrency));
1845
+
1846
+ $defaultMerchantList = Mage::getStoreConfig('codisto/merchantid', 0);
1847
+ if($defaultMerchantList)
1848
+ {
1849
+ $merchantlist = Zend_Json::decode($defaultMerchantList);
1850
+ if(!is_array($merchantlist))
1851
+ $merchantlist = array($merchantlist);
1852
+
1853
+ foreach($merchantlist as $MerchantID)
1854
+ {
1855
+ $insertStoreMerchant->execute(array($StoreID, $MerchantID));
1856
+ }
1857
+ }
1858
+
1859
+ foreach($stores as $store)
1860
+ {
1861
+ $StoreID = $store->getId();
1862
+
1863
+ if($StoreID == 0)
1864
+ continue;
1865
+
1866
+ $StoreCode = $store->getCode();
1867
+ $StoreName = $store->getName();
1868
+ $StoreCurrency = $store->getCurrentCurrencyCode();
1869
+
1870
+ $insertStore->execute(array($StoreID, $StoreCode, $StoreName, $StoreCurrency));
1871
+
1872
+ $storeMerchantList = $store->getConfig('codisto/merchantid');
1873
+ if($storeMerchantList && $storeMerchantList != $defaultMerchantList)
1874
+ {
1875
+ $merchantlist = Zend_Json::decode($storeMerchantList);
1876
+ if(!is_array($merchantlist))
1877
+ $merchantlist = array($merchantlist);
1878
+
1879
+ foreach($merchantlist as $MerchantID)
1880
+ {
1881
+ $insertStoreMerchant->execute(array($StoreID, $MerchantID));
1882
+ }
1883
+ }
1884
+ }
1885
+
1886
+ $db->exec('COMMIT TRANSACTION');
1887
+ }
1888
+
1889
+ public function SyncOrders($syncDb, $orders, $storeId)
1890
+ {
1891
+ $store = Mage::app()->getStore($storeId);
1892
+
1893
+ $db = $this->GetSyncDb($syncDb);
1894
+
1895
+ $insertOrders = $db->prepare('INSERT OR REPLACE INTO [Order] (ID, Status, PaymentDate, ShipmentDate, Carrier, TrackingNumber) VALUES (?, ?, ?, ?, ?, ?)');
1896
+
1897
+ $coreResource = Mage::getSingleton('core/resource');
1898
+
1899
+ $invoiceName = $coreResource->getTableName('sales/invoice');
1900
+ $shipmentName = $coreResource->getTableName('sales/shipment');
1901
+ $shipmentTrackName = $coreResource->getTableName('sales/shipment_track');
1902
+
1903
+ $db->exec('BEGIN EXCLUSIVE TRANSACTION');
1904
+
1905
+ $orders = Mage::getModel('sales/order')->getCollection()
1906
+ ->addFieldToSelect(array('codisto_orderid', 'status'))
1907
+ ->addAttributeToFilter('codisto_orderid', array('in' => $orders ));
1908
+
1909
+ $orders->getSelect()->joinLeft( array('i' => $invoiceName), 'i.order_id = main_table.entity_id AND i.state = 2', array('pay_date' => 'MIN(i.created_at)'));
1910
+ $orders->getSelect()->joinLeft( array('s' => $shipmentName), 's.order_id = main_table.entity_id', array('ship_date' => 'MIN(s.created_at)'));
1911
+ $orders->getSelect()->joinLeft( array('t' => $shipmentTrackName), 't.order_id = main_table.entity_id', array('carrier' => 'GROUP_CONCAT(COALESCE(t.title, \'\') SEPARATOR \',\')', 'track_number' => 'GROUP_CONCAT(COALESCE(t.track_number, \'\') SEPARATOR \',\')'));
1912
+ $orders->getSelect()->group(array('main_table.entity_id', 'main_table.codisto_orderid', 'main_table.status'));
1913
+
1914
+ $orders->setOrder('entity_id', 'ASC');
1915
+
1916
+ Mage::getSingleton('core/resource_iterator')->walk($orders->getSelect(), array(array($this, 'SyncOrderData')), array( 'db' => $db, 'preparedStatement' => $insertOrders, 'store' => $store ));
1917
+
1918
+ $db->exec('COMMIT TRANSACTION');
1919
+ }
1920
+
1921
+ private function GetSyncDb($syncDb)
1922
+ {
1923
+ $db = new PDO('sqlite:' . $syncDb);
1924
+
1925
+ Mage::helper('codistosync')->prepareSqliteDatabase($db);
1926
+
1927
+ $db->exec('BEGIN EXCLUSIVE TRANSACTION');
1928
+ $db->exec('CREATE TABLE IF NOT EXISTS Progress(entity_id integer NOT NULL, State text NOT NULL, Sentinel integer NOT NULL PRIMARY KEY AUTOINCREMENT, CHECK(Sentinel=1))');
1929
+ $db->exec('CREATE TABLE IF NOT EXISTS Category(ExternalReference text NOT NULL PRIMARY KEY, ParentExternalReference text NOT NULL, '.
1930
+ 'Name text NOT NULL, LastModified datetime NOT NULL, Enabled bit NOT NULL, Sequence integer NOT NULL)');
1931
+ $db->exec('CREATE TABLE IF NOT EXISTS CategoryProduct (CategoryExternalReference text NOT NULL, ProductExternalReference text NOT NULL, Sequence integer NOT NULL, PRIMARY KEY(CategoryExternalReference, ProductExternalReference))');
1932
+ $db->exec('CREATE TABLE IF NOT EXISTS Product (ExternalReference text NOT NULL PRIMARY KEY, Type text NOT NULL, Code text NULL, Name text NOT NULL, Price real NOT NULL, ListPrice real NOT NULL, TaxClass text NOT NULL, Description text NOT NULL, '.
1933
+ 'Enabled bit NOT NULL, '.
1934
+ 'StockControl bit NOT NULL, StockLevel integer NOT NULL, '.
1935
+ 'Weight real NULL, '.
1936
+ 'InStore bit NOT NULL)');
1937
+
1938
+ $db->exec('CREATE TABLE IF NOT EXISTS ProductOptionValue (ExternalReference text NOT NULL, Sequence integer NOT NULL)');
1939
+ $db->exec('CREATE INDEX IF NOT EXISTS IX_ProductOptionValue_ExternalReference ON ProductOptionValue(ExternalReference)');
1940
+
1941
+ $db->exec('CREATE TABLE IF NOT EXISTS ProductQuestion (ExternalReference text NOT NULL PRIMARY KEY, ProductExternalReference text NOT NULL, Name text NOT NULL, Type text NOT NULL, Sequence integer NOT NULL)');
1942
+ $db->exec('CREATE INDEX IF NOT EXISTS IX_ProductQuestion_ProductExternalReference ON ProductQuestion(ProductExternalReference)');
1943
+ $db->exec('CREATE TABLE IF NOT EXISTS ProductQuestionAnswer (ProductQuestionExternalReference text NOT NULL, Value text NOT NULL, PriceModifier text NOT NULL, SKUModifier text NOT NULL, Sequence integer NOT NULL)');
1944
+ $db->exec('CREATE INDEX IF NOT EXISTS IX_ProductQuestionAnswer_ProductQuestionExternalReference ON ProductQuestionAnswer(ProductQuestionExternalReference)');
1945
+
1946
+ $db->exec('CREATE TABLE IF NOT EXISTS SKU (ExternalReference text NOT NULL PRIMARY KEY, Code text NULL, ProductExternalReference text NOT NULL, Name text NOT NULL, StockControl bit NOT NULL, StockLevel integer NOT NULL, Price real NOT NULL, Enabled bit NOT NULL, InStore bit NOT NULL)');
1947
+ $db->exec('CREATE INDEX IF NOT EXISTS IX_SKU_ProductExternalReference ON SKU(ProductExternalReference)');
1948
+ $db->exec('CREATE TABLE IF NOT EXISTS SKUMatrix (SKUExternalReference text NOT NULL, ProductExternalReference text NOT NULL, Code text NULL, OptionName text NOT NULL, OptionValue text NOT NULL, ProductOptionExternalReference text NOT NULL, ProductOptionValueExternalReference text NOT NULL)');
1949
+ $db->exec('CREATE INDEX IF NOT EXISTS IX_SKUMatrix_SKUExternalReference ON SKUMatrix(SKUExternalReference)');
1950
+
1951
+ $db->exec('CREATE TABLE IF NOT EXISTS SKULink (SKUExternalReference text NOT NULL, ProductExternalReference text NOT NULL, Price real NOT NULL, PRIMARY KEY (SKUExternalReference, ProductExternalReference))');
1952
+
1953
+ $db->exec('CREATE TABLE IF NOT EXISTS ProductImage (ProductExternalReference text NOT NULL, URL text NOT NULL, Tag text NOT NULL DEFAULT \'\', Sequence integer NOT NULL, Enabled bit NOT NULL DEFAULT -1)');
1954
+ $db->exec('CREATE INDEX IF NOT EXISTS IX_ProductImage_ProductExternalReference ON ProductImage(ProductExternalReference)');
1955
+
1956
+ $db->exec('CREATE TABLE IF NOT EXISTS ProductHTML (ProductExternalReference text NOT NULL, Tag text NOT NULL, HTML text NOT NULL, PRIMARY KEY (ProductExternalReference, Tag))');
1957
+ $db->exec('CREATE INDEX IF NOT EXISTS IX_ProductHTML_ProductExternalReference ON ProductHTML(ProductExternalReference)');
1958
+
1959
+ $db->exec('CREATE TABLE IF NOT EXISTS Attribute (ID integer NOT NULL PRIMARY KEY, Code text NOT NULL, Label text NOT NULL, Type text NOT NULL, Input text NOT NULL)');
1960
+ $db->exec('CREATE TABLE IF NOT EXISTS AttributeGroupMap (AttributeID integer NOT NULL, GroupID integer NOT NULL, PRIMARY KEY(AttributeID, GroupID))');
1961
+ $db->exec('CREATE TABLE IF NOT EXISTS AttributeGroup (ID integer NOT NULL PRIMARY KEY, Name text NOT NULL)');
1962
+ $db->exec('CREATE TABLE IF NOT EXISTS ProductAttributeValue (ProductExternalReference text NOT NULL, AttributeID integer NOT NULL, Value any, PRIMARY KEY (ProductExternalReference, AttributeID))');
1963
+
1964
+ $db->exec('CREATE TABLE IF NOT EXISTS TaxClass (ID integer NOT NULL PRIMARY KEY, Type text NOT NULL, Name text NOT NULL)');
1965
+ $db->exec('CREATE TABLE IF NOT EXISTS TaxCalculation(ID integer NOT NULL PRIMARY KEY, TaxRateID integer NOT NULL, TaxRuleID integer NOT NULL, ProductTaxClassID integer NOT NULL, CustomerTaxClassID integer NOT NULL)');
1966
+ $db->exec('CREATE TABLE IF NOT EXISTS TaxCalculationRule(ID integer NOT NULL PRIMARY KEY, Code text NOT NULL, Priority integer NOT NULL, Position integer NOT NULL, CalculateSubTotal bit NOT NULL)');
1967
+ $db->exec('CREATE TABLE IF NOT EXISTS TaxCalculationRate(ID integer NOT NULL PRIMARY KEY, Country text NOT NULL, RegionID integer NOT NULL, RegionName text NULL, RegionCode text NULL, PostCode text NOT NULL, Code text NOT NULL, Rate real NOT NULL, IsRange bit NULL, ZipFrom text NULL, ZipTo text NULL)');
1968
+
1969
+
1970
+ $db->exec('CREATE TABLE IF NOT EXISTS Store(ID integer NOT NULL PRIMARY KEY, Code text NOT NULL, Name text NOT NULL, Currency text NOT NULL)');
1971
+ $db->exec('CREATE TABLE IF NOT EXISTS StoreMerchant(StoreID integer NOT NULL, MerchantID integer NOT NULL, PRIMARY KEY (StoreID, MerchantID))');
1972
+
1973
+ $db->exec('CREATE TABLE IF NOT EXISTS [Order](ID integer NOT NULL PRIMARY KEY, Status text NOT NULL, PaymentDate datetime NULL, ShipmentDate datetime NULL, Carrier text NOT NULL, TrackingNumber text NOT NULL)');
1974
+
1975
+ $db->exec('CREATE TABLE IF NOT EXISTS StaticBlock(BlockID integer NOT NULL PRIMARY KEY, Title text NOT NULL, Identifier text NOT NULL, Content text NOT NULL)');
1976
+
1977
+ $db->exec('CREATE TABLE IF NOT EXISTS Configuration (configuration_id integer, configuration_title text, configuration_key text, configuration_value text, configuration_description text, configuration_group_id integer, sort_order integer, last_modified datetime, date_added datetime, use_function text, set_function text)');
1978
+
1979
+ try
1980
+ {
1981
+ $db->exec('SELECT 1 FROM [Order] WHERE Carrier IS NULL LIMIT 1');
1982
+ }
1983
+ catch(Exception $e)
1984
+ {
1985
+ $db->exec('CREATE TABLE NewOrder (ID integer NOT NULL PRIMARY KEY, Status text NOT NULL, PaymentDate datetime NULL, ShipmentDate datetime NULL, Carrier text NOT NULL, TrackingNumber text NOT NULL)');
1986
+ $db->exec('INSERT INTO NewOrder SELECT ID, Status, PaymentDate, ShipmentDate, \'Unknown\', TrackingNumber FROM [Order]');
1987
+ $db->exec('DROP TABLE [Order]');
1988
+ $db->exec('ALTER TABLE NewOrder RENAME TO [Order]');
1989
+ }
1990
+
1991
+ try
1992
+ {
1993
+ $db->exec('SELECT 1 FROM ProductAttributeValue WHERE ProductExternalReference IS NULL LIMIT 1');
1994
+ }
1995
+ catch(Exception $e)
1996
+ {
1997
+ $db->exec('CREATE TABLE NewProductAttributeValue (ProductExternalReference integer NOT NULL, AttributeID integer NOT NULL, Value any, PRIMARY KEY (ProductExternalReference, AttributeID))');
1998
+ $db->exec('INSERT INTO NewProductAttributeValue SELECT ProductID, AttributeID, Value FROM ProductAttributeValue');
1999
+ $db->exec('DROP TABLE ProductAttributeValue');
2000
+ $db->exec('ALTER TABLE NewProductAttributeValue RENAME TO ProductAttributeValue');
2001
+ }
2002
+
2003
+ try
2004
+ {
2005
+ $db->exec('SELECT 1 FROM Store WHERE MerchantID IS NULL LIMIT 1');
2006
+
2007
+ $db->exec('CREATE TABLE NewStore(ID integer NOT NULL PRIMARY KEY, Code text NOT NULL, Name text NOT NULL)');
2008
+ $db->exec('INSERT INTO NewStore SELECT ID, Code, Name FROM Store');
2009
+ $db->exec('DROP TABLE Store');
2010
+ $db->exec('ALTER TABLE NewStore RENAME TO Store');
2011
+ }
2012
+ catch(Exception $e)
2013
+ {
2014
+
2015
+ }
2016
+
2017
+ try
2018
+ {
2019
+ $db->exec('SELECT 1 FROM ProductImage WHERE Enabled IS NULL LIMIT 1');
2020
+ }
2021
+ catch(Exception $e)
2022
+ {
2023
+ try
2024
+ {
2025
+ $db->exec('ALTER TABLE ProductImage ADD COLUMN Enabled bit NOT NULL DEFAULT -1');
2026
+ }
2027
+ catch(Exception $e2)
2028
+ {
2029
+ }
2030
+ }
2031
+
2032
+ try
2033
+ {
2034
+ $db->exec('SELECT ProductExternalReference FROM ProductOptionValue LIMIT 1');
2035
+
2036
+ $db->exec('CREATE TABLE IF NOT EXISTS TmpProductOptionValue (ExternalReference text NOT NULL, Sequence integer NOT NULL)');
2037
+ $db->exec('CREATE INDEX IF NOT EXISTS IX_ProductOptionValue_ExternalReference_Sequence ON ProductOptionValue(ExternalReference, Sequence)');
2038
+ $db->exec('INSERT INTO TmpProductOptionValue (ExternalReference, Sequence) SELECT DISTINCT ExternalReference, Sequence FROM ProductOptionValue');
2039
+ $db->exec('DROP TABLE ProductOptionValue');
2040
+ $db->exec('ALTER TABLE TmpProductOptionValue RENAME TO ProductOptionValue');
2041
+ $db->exec('CREATE INDEX IF NOT EXISTS IX_ProductOptionValue_ExternalReference ON ProductOptionValue(ExternalReference)');
2042
+ }
2043
+ catch (Exception $e)
2044
+ {
2045
+
2046
+ }
2047
+
2048
+ try
2049
+ {
2050
+ $db->exec('SELECT ProductExternalReference FROM SKUMatrix LIMIT 1');
2051
+
2052
+ $db->exec('ALTER TABLE SKUMatrix ADD COLUMN ProductExternalReference text NOT NULL DEFAULT \'\'');
2053
+ $db->exec('UPDATE SKUMatrix SET ProductExternalReference = (SELECT ProductExternalReference FROM SKU WHERE SKUExternalReference = SKUMatrix.SKUExternalReference)');
2054
+ }
2055
+ catch (Exception $e)
2056
+ {
2057
+
2058
+ }
2059
+
2060
+ try
2061
+ {
2062
+ $db->exec('SELECT InStore FROM Product LIMIT 1');
2063
+ }
2064
+ catch(Exception $e)
2065
+ {
2066
+ try
2067
+ {
2068
+ $db->exec('ALTER TABLE Product ADD COLUMN InStore bit NOT NULL DEFAULT -1');
2069
+ $db->exec('ALTER TABLE SKU ADD COLUMN InStore bit NOT NULL DEFAULT -1');
2070
+ }
2071
+ catch(Exception $e2)
2072
+ {
2073
+ }
2074
+ }
2075
+
2076
+ try
2077
+ {
2078
+ $db->exec('SELECT Type FROM Product LIMIT 1');
2079
+ }
2080
+ catch(Exception $e)
2081
+ {
2082
+ try
2083
+ {
2084
+ $db->exec('ALTER TABLE Product ADD COLUMN Type text NOT NULL DEFAULT \'s\'');
2085
+ $db->exec('UPDATE Product SET Type = \'c\' WHERE ExternalReference IN (SELECT ProductExternalReference FROM SKULink) OR ExternalReference IN (SELECT ProductExternalReference FROM SKU)');
2086
+ }
2087
+ catch(Exception $e2)
2088
+ {
2089
+ }
2090
+ }
2091
+
2092
+ try
2093
+ {
2094
+ $db->exec('SELECT Input FROM Attribute LIMIT 1');
2095
+ }
2096
+ catch(Exception $e)
2097
+ {
2098
+ try
2099
+ {
2100
+ $db->exec('ALTER TABLE Attribute ADD COLUMN Input text NOT NULL DEFAULT \'text\'');
2101
+ }
2102
+ catch (Exception $e2)
2103
+ {
2104
+ }
2105
+
2106
+ }
2107
+
2108
+ $db->exec('COMMIT TRANSACTION');
2109
+
2110
+ return $db;
2111
+ }
2112
+
2113
+ private function GetTemplateDb($templateDb)
2114
+ {
2115
+ $db = new PDO('sqlite:' . $templateDb);
2116
+
2117
+ Mage::helper('codistosync')->prepareSqliteDatabase($db);
2118
+
2119
+ $db->exec('BEGIN EXCLUSIVE TRANSACTION');
2120
+ $db->exec('CREATE TABLE IF NOT EXISTS File(Name text NOT NULL PRIMARY KEY, Content blob NOT NULL, LastModified datetime NOT NULL, Changed bit NOT NULL DEFAULT -1)');
2121
+ $db->exec('COMMIT TRANSACTION');
2122
+
2123
+ return $db;
2124
+ }
2125
+
2126
+ private function getProductCollection()
2127
+ {
2128
+ $process = Mage::helper('catalog/product_flat')->getProcess();
2129
+ $status = $process->getStatus();
2130
+ $process->setStatus(Mage_Index_Model_Process::STATUS_RUNNING);
2131
+
2132
+ $collection = Mage::getResourceModel('catalog/product_collection');
2133
+
2134
+ $process->setStatus($status);
2135
+
2136
+ return $collection;
2137
+ }
2138
+
2139
+ private function getExTaxPrice($product, $pricein, $store)
2140
+ {
2141
+ if($this->useTaxHelper)
2142
+ {
2143
+ $price = Mage::helper('tax')->getPrice($product, $pricein, false, null, null, null, $store, null, false);
2144
+ }
2145
+ else
2146
+ {
2147
+ if(!$this->rateRequest)
2148
+ $this->rateRequest = $this->taxCalculation->getRateRequest(null, null, null, $store);
2149
+
2150
+ $taxClassId = $product->getTaxClassId();
2151
+ $percent = $this->taxCalculation->getRate($this->rateRequest->setProductClassId($taxClassId));
2152
+
2153
+ $price = $pricein / (1.0+($percent/100.0));
2154
+ }
2155
+
2156
+ return $price;
2157
+ }
2158
+ }
app/code/community/Codisto/Sync/Test/Config/AdminHtml.php ADDED
@@ -0,0 +1,66 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ @session_start();
3
+ class Codisto_Sync_Test_Config_AdminHtml extends EcomDev_PHPUnit_Test_Case_Config
4
+ {
5
+ public function setUp()
6
+ {
7
+
8
+
9
+ $app = Mage::app('default');
10
+
11
+ }
12
+
13
+ /**
14
+ * Test that adminhtml.xml layout file is present
15
+ *
16
+ * @test
17
+ */
18
+
19
+ public function testLayoutPresent()
20
+ {
21
+ //$this->assertLayoutFileDefined("adminhtml", "adminhtml.xml");
22
+
23
+ /*
24
+ assertLayoutFileDefined() asserts that configuration has definition of the layout file
25
+ ◦ string $area the area of layout file. Possible values are frontend and adminhtml
26
+ ◦ string $expectedFileName expected layout file name, for instance catalog.xml
27
+ ◦ string $layoutUpdate if layout update name is specified, then it will restrict
28
+ assertion by it. [optional]
29
+
30
+ */
31
+ }
32
+
33
+ /**
34
+ * Test that CodistoConnect menu has been added and contains correct entries
35
+ *
36
+ * @test
37
+ */
38
+ public function testCodistoConnectMenu()
39
+ {
40
+ /*
41
+ <menu>
42
+ <codisto translate="title">
43
+ <title>eBay | Codisto</title>
44
+ <sort_order>99</sort_order>
45
+ <children>
46
+ <subitem translate="title">
47
+ <title>Manage Listings</title>
48
+ <sort_order>1</sort_order>
49
+ <action>adminhtml/codisto/index</action>
50
+ </subitem>
51
+ <subitem1 translate="title">
52
+ <title>Getting Started</title>
53
+ <sort_order>2</sort_order>
54
+ <action>adminhtml/codisto/intro</action>
55
+ </subitem1>
56
+ <subitem2 translate="title">
57
+ <title>Settings</title>
58
+ <sort_order>3</sort_order>
59
+ <action>adminhtml/codisto/settings</action>
60
+ </subitem2>
61
+ </children>
62
+ </codisto>
63
+ </menu>
64
+ */
65
+ }
66
+ }
app/code/community/Codisto/Sync/Test/Config/Config.php ADDED
@@ -0,0 +1,162 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ @session_start();
3
+
4
+ class Codisto_Sync_Test_Config_Config extends EcomDev_PHPUnit_Test_Case_Config
5
+ {
6
+ public function setUp()
7
+ {
8
+ $app = Mage::app('default');
9
+ }
10
+
11
+ /**
12
+ * Test that CodistoConnect menu has been added and contains correct entries
13
+ *
14
+ * @test
15
+ */
16
+ public function testCodistoModuleCodePool()
17
+ {
18
+ $this->assertModuleCodePool("community");
19
+ }
20
+
21
+ /**
22
+ * Test that CodistoConnect configuration dependencies are specified correctly
23
+ *
24
+ * @test
25
+ */
26
+ public function testCodistoModuleDependencies()
27
+ {
28
+ $this->assertModuleDepends("Mage_Payment");
29
+ }
30
+
31
+ /**
32
+ * Test that the current version is >= 1.1.25 (when unit tests were first added)
33
+ *
34
+ * @test
35
+ */
36
+ public function testCodistoConnectVersion()
37
+ {
38
+ $this->assertModuleVersionGreaterThanOrEquals("1.1.25");
39
+ }
40
+
41
+ /**
42
+ * Test aliases are in place
43
+ *
44
+ * @test
45
+ */
46
+ public function testModels()
47
+ {
48
+ //Model Aliases
49
+ $this->assertModelAlias("codistosync/codisto_sync_model", "Codisto_Sync_Model_Codisto_Sync_Model");
50
+ $this->assertModelAlias("ebaypayment/codisto_sync_ebaypayment_model", "Codisto_Sync_Ebaypayment_Model_Codisto_Sync_Ebaypayment_Model");
51
+ }
52
+
53
+ /**
54
+ * Test Resource nodes contain correct values
55
+ *
56
+ * @test
57
+ */
58
+ public function testResources() {
59
+ //$this->assertResourceModelAlias("codisto_setup/setup", "Codisto_Sync_Model_Resource_Mysql4_Setup");
60
+ }
61
+
62
+ /**
63
+ * Test Helper functions are wired up correctly
64
+ *
65
+ * @test
66
+ */
67
+ public function testHelpers() {
68
+ $this->assertHelperAlias("codisto-sync/codisto_sync_helper", "Codisto_Sync_Helper_Codisto_Sync_Helper");
69
+ $this->assertHelperAlias("codisto-sync", "Codisto_Sync_Helper_Data");
70
+ }
71
+
72
+
73
+ /**
74
+ * Test fieldsets contain correct values
75
+ *
76
+ * @test
77
+ */
78
+ public function testFieldSets() {
79
+ $this->assertConfigNodeValue("global/fieldsets/sales_convert_quote/codisto_orderid/to_order", "*");
80
+ $this->assertConfigNodeValue("global/fieldsets/sales_convert_order/codisto_orderid/to_quote", "*");
81
+ }
82
+
83
+ /**
84
+ * Test events are wired up correctly
85
+ *
86
+ * @test
87
+ */
88
+ public function testEventNodes()
89
+ {
90
+ $events = array(
91
+ "payment_info_block_prepare_specific_information" => array("type" => "singleton",
92
+ "method" => "paymentInfoBlockPrepareSpecificInformation"),
93
+
94
+ "sales_order_shipment_save_after" => array("type" => "singleton",
95
+ "method" => "salesOrderShipmentSaveAfter"),
96
+
97
+ "sales_order_invoice_save_commit_after" => array("namespace" => "codisto_save_invoice",
98
+ "method" => "salesOrderInvoiceSaveAfter"),
99
+
100
+ "checkout_submit_all_after" => array("namespace" => "codisto_stockmovements",
101
+ "method" => "checkoutAllSubmitAfter"),
102
+
103
+ "cataloginventory_stock_revert_products_sale" => array("namespace" => "codisto_stockmovements",
104
+ "method" => "stockRevertProductsSale"),
105
+
106
+ "catalog_product_import_finish_before" => array("namespace" => "codisto_stockmovements",
107
+ "method" => "catalogProductImportFinishBefore"),
108
+
109
+ "sales_order_item_cancel" => array("namespace" => "codisto_stockmovements",
110
+ "method" => "cancelOrderItem",
111
+ "extra" => array ( array("path" => "inventory/type", "value" => "disabled"))),
112
+
113
+ "tax_settings_change_after" => array("namespace" => "codisto_taxsync",
114
+ "type" => "singleton",
115
+ "method" => "taxSettingsChangeAfter"),
116
+
117
+ "core_block_abstract_prepare_layout_after" => array("namespace" => "codisto_admin",
118
+ "type" => "singleton",
119
+ "method" => "addProductTab"),
120
+ );
121
+
122
+ //Assert type, class and method values are expected
123
+ foreach ($events as $key => $value) {
124
+
125
+ $namespace = "codisto";
126
+ if(array_key_exists("namespace", $value)) {
127
+ $namespace = $value["namespace"];
128
+ }
129
+
130
+ if(array_key_exists("type", $value)) {
131
+ $this->assertConfigNodeValue("global/events/" . $key . "/observers/". $namespace . "/type",
132
+ $value["type"]);
133
+ }
134
+
135
+ //default class
136
+ $class = "Codisto_Sync_Model_Observer";
137
+ if(array_key_exists("class", $value)) {
138
+ $class = $value["class"];
139
+ }
140
+ $this->assertConfigNodeValue("global/events/". $key . "/observers/". $namespace . "/class",
141
+ $class);
142
+
143
+
144
+ $this->assertConfigNodeValue("global/events/". $key . "/observers/". $namespace . "/method",
145
+ $value["method"]);
146
+
147
+ //Any extra meta data to check in the nodes relative to observers child node
148
+ if(array_key_exists("extra", $value)) {
149
+
150
+ for($i = 0; $i < count($value["extra"]); $i ++) {
151
+
152
+ $path = $value["extra"][$i]["path"];
153
+ $val = $value["extra"][$i]["value"];
154
+
155
+ $this->assertConfigNodeValue("global/events/". $key . "/observers/" . $path,
156
+ $val);
157
+ }
158
+ }
159
+
160
+ }
161
+ }
162
+ }
app/code/community/Codisto/Sync/Test/Config/Config/expectations/testCodistoCoreConfig.yaml ADDED
@@ -0,0 +1,5 @@
 
 
 
 
 
1
+ module:
2
+ version: 1.1.25
3
+ code_pool: community
4
+ depends:
5
+ - Mage_Payment
app/code/community/Codisto/Sync/Test/Controller/Router.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ @session_start();
3
+ class Codisto_Sync_Test_Controller_Router extends EcomDev_PHPUnit_Test_Case_Controller
4
+ {
5
+ public function setUp()
6
+ {
7
+ $app = Mage::app('default');
8
+ }
9
+
10
+ /**
11
+ * Test getAllHeaders returns list of headers sanitized accordingly
12
+ *
13
+ * @test
14
+ */
15
+
16
+ public function testgetAllHeaders()
17
+ {
18
+
19
+ }
20
+
21
+ }
app/code/community/Codisto/Sync/Test/Controllers/CodistoController.php ADDED
@@ -0,0 +1,35 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ @session_start();
3
+ class Codisto_Sync_Test_Controllers_CodistoController extends EcomDev_PHPUnit_Test_Case_Controller
4
+ {
5
+ public function setUp()
6
+ {
7
+ $app = Mage::app('default');
8
+ }
9
+
10
+ public function testIntroAction()
11
+ {
12
+ $this->dispatch('adminhtml/codisto/intro');
13
+
14
+ //Make sure there is an endpoint
15
+ $this->assertRequestRoute('adminhtml/codisto/intro');
16
+
17
+ }
18
+
19
+ public function testSettingsAction()
20
+ {
21
+ $this->dispatch('adminhtml/codisto/settings');
22
+ $this->assertRequestRoute('adminhtml/codisto/settings');
23
+ $this->assertResponseBodyContains('eBay Account');
24
+ }
25
+
26
+ public function testIndexAction()
27
+ {
28
+
29
+ $this->dispatch('adminhtml/codisto/index');
30
+
31
+ //Make sure there is an endpoint
32
+ $this->assertRequestRoute('adminhtml/codisto/index');
33
+
34
+ }
35
+ }
app/code/community/Codisto/Sync/Test/Controllers/IndexController.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ @session_start();
3
+ class Codisto_Sync_Test_Controllers_IndexController extends EcomDev_PHPUnit_Test_Case_Controller
4
+ {
5
+ public function setUp()
6
+ {
7
+ $app = Mage::app('default');
8
+ }
9
+ }
app/code/community/Codisto/Sync/Test/Controllers/SyncController.php ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ @session_start();
3
+ class Codisto_Sync_Test_Controllers_SyncController extends EcomDev_PHPUnit_Test_Case_Controller
4
+ {
5
+ public function setUp()
6
+ {
7
+ $app = Mage::app('default');
8
+ }
9
+ }
app/code/community/Codisto/Sync/Test/Model/Paymentmethod.php ADDED
@@ -0,0 +1,29 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Codisto_Sync_Test_Model_Paymentmethod extends EcomDev_PHPUnit_Test_Case
4
+ {
5
+
6
+ protected $_syncObject;
7
+
8
+ public function setUp()
9
+ {
10
+ @session_start();
11
+
12
+ $app = Mage::app('default');
13
+
14
+ }
15
+
16
+ /**
17
+ * Test ebaypayment method is a valid payment method
18
+ *
19
+ * @test
20
+ */
21
+
22
+ public function testeBayPaymentMethodExists()
23
+ {
24
+ //Get a list of payment methods ... confirm that eBay payment method is registered
25
+ $payments = Mage::getSingleton('payment/config')->getActiveMethods();
26
+ $this->assertEquals(true, array_key_exists('ebay', $payments));
27
+ }
28
+
29
+ }
app/code/community/Codisto/Sync/Test/Model/Sync.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Codisto_Sync_Test_Model_Sync extends EcomDev_PHPUnit_Test_Case
4
+ {
5
+
6
+ protected $_syncObject;
7
+
8
+ public function setUp()
9
+ {
10
+ @session_start();
11
+ #Suppress errors for Cannot send session cookie - headers already sent PHPUnit
12
+ #parent::setUp();
13
+
14
+ $app = Mage::app('default');
15
+ $this->_syncObject = Mage::getModel('codistosync/sync');
16
+
17
+ }
18
+
19
+ /*
20
+ Placeholder test to silence warnings about no tests in this file
21
+ */
22
+ public function testSyncStub()
23
+ {
24
+ $this->assertEquals(true, true);
25
+ }
26
+
27
+ }
28
+
app/code/community/Codisto/Sync/Test/README ADDED
@@ -0,0 +1,2 @@
 
 
1
+ #https://github.com/AOEpeople/EcomDev_PHPUnit
2
+ #http://www.ecomdev.org/wp-content/uploads/2011/05/EcomDev_PHPUnit-0.2.0-Manual.pdf
app/code/community/Codisto/Sync/controllers/CodistoController.php ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Codisto eBay Sync Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * @category Codisto
16
+ * @package Codisto_Sync
17
+ * @copyright Copyright (c) 2015 On Technology Pty. Ltd. (http://codisto.com/)
18
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
19
+ */
20
+
21
+ class Codisto_Sync_CodistoController extends Mage_Adminhtml_Controller_Action
22
+ {
23
+ public $_publicActions = array('index', 'intro', 'settings', 'orders');
24
+
25
+ public function indexAction()
26
+ {
27
+ $url = preg_replace('/\/ebaytab(?:\/index)?(\/key\/)?/', '/ebaytab$1', Mage::getModel('adminhtml/url')->getUrl('codisto/ebaytab'));
28
+
29
+ $this->renderPane($url, 'codisto-bulk-editor');
30
+ }
31
+
32
+ public function ordersAction()
33
+ {
34
+ $url = preg_replace('/\/ebaytab(?:\/index)?(\/key\/)?/', '/orders$1', Mage::getModel('adminhtml/url')->getUrl('codisto/ebaytab'));
35
+
36
+ $action = $this->getRequest()->getQuery('action');
37
+ if($action)
38
+ $url = $url . '?action='. $action;
39
+
40
+ $this->renderPane($url, 'codisto-bulk-editor');
41
+ }
42
+
43
+ public function categoriesAction()
44
+ {
45
+ $url = preg_replace('/\/ebaytab(?:\/index)?(\/key\/)?/', '/ebaytab/categories$1', Mage::getModel('adminhtml/url')->getUrl('codisto/ebaytab'));
46
+
47
+ $this->renderPane($url, 'codisto-bulk-editor');
48
+ }
49
+
50
+ public function importAction()
51
+ {
52
+ $url = preg_replace('/\/ebaytab(?:\/index)?(\/key\/)?/', '/ebaytab/importlistings$1', Mage::getModel('adminhtml/url')->getUrl('codisto/ebaytab'). '?v=2');
53
+
54
+ $this->renderPane($url, 'codisto-bulk-editor');
55
+ }
56
+
57
+ public function introAction()
58
+ {
59
+ $url = preg_replace('/\/ebaytab(?:\/index)?(\/key\/)?/', '/ebaytab$1', Mage::getModel('adminhtml/url')->getUrl('codisto/ebaytab')) . '?intro=1';
60
+
61
+ $this->renderPane($url, 'codisto-bulk-editor');
62
+ }
63
+
64
+ public function attributemappingAction()
65
+ {
66
+ $url = preg_replace('/\/ebaytab(?:\/index)?(\/key\/)?/', '/ebaytab/attributemapping$1', Mage::getModel('adminhtml/url')->getUrl('codisto/ebaytab'));
67
+
68
+ $this->renderPane($url, 'codisto-attributemapping');
69
+ }
70
+
71
+ public function settingsAction()
72
+ {
73
+ $url = preg_replace('/\/ebaytab(?:\/index)?(\/key\/)?/', '/settings$1', Mage::getModel('adminhtml/url')->getUrl('codisto/ebaytab'));
74
+
75
+ $this->renderPane($url, 'codisto-settings');
76
+ }
77
+
78
+ private function renderPane($url, $class)
79
+ {
80
+ $this->loadLayout();
81
+
82
+ $block = $this->getLayout()->createBlock('core/text', 'green-block')->setText('<div id="codisto-control-panel-wrapper"><iframe id="codisto-control-panel" class="codisto-iframe '. htmlspecialchars($class) .'" src="'. htmlspecialchars($url) . '" frameborder="0" onmousewheel=""></iframe></div>');
83
+ $this->_addContent($block);
84
+
85
+ $this->renderLayout();
86
+ }
87
+
88
+ protected function _isAllowed()
89
+ {
90
+ return Mage::getSingleton('admin/session')->isAllowed('codisto');
91
+ }
92
+ }
app/code/community/Codisto/Sync/controllers/IndexController.php ADDED
@@ -0,0 +1,1989 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Codisto eBay Sync Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * @category Codisto
16
+ * @package Codisto_Sync
17
+ * @copyright Copyright (c) 2015 On Technology Pty. Ltd. (http://codisto.com/)
18
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
19
+ */
20
+
21
+ class Codisto_Sync_IndexController extends Mage_Core_Controller_Front_Action
22
+ {
23
+ public function calcAction()
24
+ {
25
+ set_time_limit(0);
26
+ ignore_user_abort(false);
27
+
28
+ $output = '';
29
+
30
+ try
31
+ {
32
+ $request = $this->getRequest();
33
+ $response = $this->getResponse();
34
+
35
+ $storeId = $request->getQuery('storeid') == null ? 0 : (int)$request->getQuery('storeid');
36
+
37
+ if($storeId == 0)
38
+ {
39
+ // jump the storeid to first non admin store
40
+ $stores = Mage::getModel('core/store')->getCollection()
41
+ ->addFieldToFilter('is_active', array('neq' => 0))
42
+ ->addFieldToFilter('store_id', array('gt' => 0))
43
+ ->setOrder('store_id', 'ASC');
44
+
45
+ $firstStore = $stores->getFirstItem();
46
+ if(is_object($firstStore) && $firstStore->getId())
47
+ $storeId = $firstStore->getId();
48
+ }
49
+
50
+ $store = Mage::app()->getStore($storeId);
51
+
52
+ $currencyCode = $request->getPost('CURRENCY');
53
+ if(!$currencyCode)
54
+ $currencyCode = $store->getCurrentCurrencyCode();
55
+
56
+ $place = $request->getPost('PLACE');
57
+ if(!$place)
58
+ $place = '';
59
+ $postalcode = $request->getPost('POSTALCODE');
60
+ $division = $request->getPost('DIVISION');
61
+ $countrycode = $request->getPost('COUNTRYCODE');
62
+ $regionid = null;
63
+ $regioncode = null;
64
+
65
+ if($countrycode == 'AU')
66
+ {
67
+ $pc = $postalcode{0};
68
+
69
+ if ($pc == 2 || $pc == 1) {
70
+ $regiontext = 'NSW';
71
+ } else if ($pc == 3 || $pc == 8) {
72
+ $regiontext = 'VIC';
73
+ } else if ($pc == 4) {
74
+ $regiontext = 'QLD';
75
+ } else if ($pc == 5) {
76
+ $regiontext = 'SA';
77
+ } else if ($pc == 6) {
78
+ $regiontext = 'WA';
79
+ } else if ($pc == 7) {
80
+ $regiontext = 'TAS';
81
+ }
82
+
83
+ $pc3 = $postalcode{0} . $postalcode{1};
84
+ if ($pc3 == '08' || $pc3 == '09') {
85
+ $regiontext = 'NT';
86
+ }
87
+
88
+ if ($postalcode == '0872') {
89
+ $regiontext = 'SA';
90
+ } else if ($postalcode == '2611' || $postalcode == '3500' || $postalcode == '3585' || $postalcode == '3586' || $postalcode == '3644' || $postalcode == '3707') {
91
+ $regiontext = 'NSW';
92
+ } else if ($postalcode == '2620') {
93
+ $regiontext = 'ACT';
94
+ }
95
+
96
+ if (intval($postalcode) >= 2600 && intval($postalcode) <= 2618) {
97
+ $regiontext = 'ACT';
98
+ }
99
+
100
+ $region = Mage::getModel('directory/region')->loadByCode($regiontext, $countrycode);
101
+ if($region)
102
+ {
103
+ $regionid = $region->getId();
104
+ $regioncode = $region->getCode();
105
+ }
106
+ }
107
+ else
108
+ {
109
+ $region = Mage::getModel('directory/region')->loadByName($division, $countrycode);
110
+ if($region)
111
+ {
112
+ $regionid = $region->getId();
113
+ $regioncode = $region->getCode();
114
+ }
115
+ }
116
+
117
+ $total = 0;
118
+ $itemqty = 0;
119
+ $totalweight = 0;
120
+
121
+ $quote = Mage::getModel('sales/quote');
122
+ $quote->setIsSuperMode(true);
123
+
124
+ for($inputidx = 0; ; $inputidx++)
125
+ {
126
+ if(!$request->getPost('PRODUCTCODE('.$inputidx.')'))
127
+ break;
128
+
129
+ $productid = (int)$request->getPost('PRODUCTID('.$inputidx.')');
130
+ if(!$productid)
131
+ {
132
+ $productcode = $request->getPost('PRODUCTCODE('.$inputidx.')');
133
+ $productid = Mage::getModel('catalog/product')->getIdBySku($productcode);
134
+ }
135
+ else
136
+ {
137
+ $sku = Mage::getResourceSingleton('catalog/product')->getProductsSku(array($productid));
138
+ if(empty($sku))
139
+ {
140
+ $productcode = $request->getPost('PRODUCTCODE('.$inputidx.')');
141
+ $productid = Mage::getModel('catalog/product')->getIdBySku($productcode);
142
+ }
143
+ }
144
+
145
+ $productqty = $request->getPost('PRODUCTQUANTITY('.$inputidx.')');
146
+ if(!$productqty && $productqty !=0)
147
+ $productqty = 1;
148
+
149
+ $productprice = floatval($request->getPost('PRODUCTPRICE('.$inputidx.')'));
150
+ $productpriceincltax = floatval($request->getPost('PRODUCTPRICEINCTAX('.$inputidx.')'));
151
+ $producttax = floatval($request->getPost('PRODUCTTAX('.$inputidx.')'));
152
+
153
+ if($productid)
154
+ {
155
+ $product = Mage::getModel('catalog/product')->load($productid);
156
+
157
+ if($product)
158
+ {
159
+ $product->setIsSuperMode(true);
160
+
161
+ $taxpercent = $productprice == 0 ? 0 : round($productpriceincltax / $productprice - 1.0, 2) * 100;
162
+
163
+ $item = Mage::getModel('sales/quote_item');
164
+ $item->setStoreId($store->getId());
165
+ $item->setQuote($quote);
166
+
167
+ $item->setData('product', $product);
168
+ $item->setProductId($productid);
169
+ $item->setProductType('simple');
170
+ $item->setIsRecurring(false);
171
+ $item->setTaxClassId($product->getTaxClassId());
172
+ $item->setBaseCost($product->getCost());
173
+ $item->setSku($product->getSku());
174
+ $item->setName($product->getName());
175
+ $item->setIsVirtual(0);
176
+ $item->setIsQtyDecimal(0);
177
+ $item->setNoDiscount(true);
178
+ $item->setWeight($product->getWeight());
179
+ $item->setData('qty', $productqty);
180
+ $item->setPrice($productprice);
181
+ $item->setBasePrice($productprice);
182
+ $item->setCustomPrice($productprice);
183
+ $item->setDiscountPercent(0);
184
+ $item->setDiscountAmount(0);
185
+ $item->setBaseDiscountAmount(0);
186
+ $item->setTaxPercent($taxpercent);
187
+ $item->setTaxAmount($producttax);
188
+ $item->setBaseTaxAmount($producttax);
189
+ $item->setRowTotal($productprice * $productqty);
190
+ $item->setBaseRowTotal($productprice * $productqty);
191
+ $item->setRowTotalWithDiscount($productprice * $productqty);
192
+ $item->setRowWeight($product->getWeight() * $productqty);
193
+ $item->setOriginalCustomPrice($productprice);
194
+ $item->setPriceInclTax($productpriceincltax);
195
+ $item->setBasePriceInclTax($productpriceincltax);
196
+ $item->setRowTotalInclTax($productpriceincltax * $productqty);
197
+ $item->setBaseRowTotalInclTax($productpriceincltax * $productqty);
198
+ $item->setWeeeTaxApplied(serialize(array()));
199
+
200
+ $total += $productpriceincltax;
201
+ $itemqty += $productqty;
202
+ $totalweight += $product->getWeight();
203
+
204
+ $quote->getItemsCollection()->addItem($item);
205
+ }
206
+ }
207
+ }
208
+
209
+ $quote->save();
210
+
211
+ $checkoutSession = Mage::getSingleton('checkout/session');
212
+ $checkoutSession->replaceQuote($quote);
213
+ $checkoutSession->setData('destination_type', 'residence');
214
+
215
+ $currency = Mage::getModel('directory/currency')->load($currencyCode);
216
+
217
+ $shippingRequest = Mage::getModel('shipping/rate_request');
218
+ $shippingRequest->setAllItems($quote->getAllItems());
219
+ $shippingRequest->setDestCountryId($countrycode);
220
+ if($regionid)
221
+ $shippingRequest->setDestRegionId($regionid);
222
+ if($regioncode)
223
+ $shippingRequest->setDestRegionCode($regioncode);
224
+ if($place)
225
+ $shippingRequest->setDestCity($place);
226
+ $shippingRequest->setDestPostcode($postalcode);
227
+ $shippingRequest->setPackageValue($total);
228
+ $shippingRequest->setPackageValueWithDiscount($total);
229
+ $shippingRequest->setPackageWeight($totalweight);
230
+ $shippingRequest->setPackageQty($itemqty);
231
+ $shippingRequest->setPackagePhysicalValue($total);
232
+ $shippingRequest->setFreeMethodWeight(0);
233
+ $shippingRequest->setStoreId($store->getId());
234
+ $shippingRequest->setWebsiteId($store->getWebsiteId());
235
+ $shippingRequest->setFreeShipping(0);
236
+ $shippingRequest->setBaseCurrency($currency);
237
+ $shippingRequest->setPackageCurrency($currency);
238
+ $shippingRequest->setBaseSubtotalInclTax($total);
239
+
240
+ $shippingResult = Mage::getModel('shipping/shipping')->collectRates($shippingRequest)->getResult();
241
+
242
+ $shippingRates = $shippingResult->getAllRates();
243
+
244
+ $outputidx = 0;
245
+ foreach($shippingRates as $shippingRate)
246
+ {
247
+ if($shippingRate instanceof Mage_Shipping_Model_Rate_Result_Method)
248
+ {
249
+ $isPickup = $shippingRate->getPrice() == 0 &&
250
+ (preg_match('/(?:^|\W|_)pick\s*up(?:\W|_|$)/i', strval($shippingRate->getMethod())) ||
251
+ preg_match('/(?:^|\W|_)pick\s*up(?:\W|_|$)/i', strval($shippingRate->getCarrierTitle())) ||
252
+ preg_match('/(?:^|\W|_)pick\s*up(?:\W|_|$)/i', strval($shippingRate->getMethodTitle())));
253
+
254
+ if(!$isPickup)
255
+ {
256
+ $output .= 'FREIGHTNAME('.$outputidx.')='.rawurlencode($shippingRate->getMethodTitle()).'&FREIGHTCHARGEINCTAX('.$outputidx.')='.$shippingRate->getPrice().'&';
257
+ $outputidx++;
258
+ }
259
+ }
260
+ }
261
+
262
+ try
263
+ {
264
+ $quote
265
+ ->setIsActive(false)
266
+ ->delete();
267
+ }
268
+ catch(Exception $e)
269
+ {
270
+
271
+ }
272
+
273
+ }
274
+ catch(Exception $e)
275
+ {
276
+
277
+ }
278
+
279
+ $response->clearAllHeaders();
280
+ //@codingStandardsIgnoreStart
281
+ if(function_exists('http_response_code'))
282
+ http_response_code(200);
283
+ //@codingStandardsIgnoreEnd
284
+ $response->setHttpResponseCode(200);
285
+ $response->setRawHeader('HTTP/1.0 200 OK');
286
+ $response->setRawHeader('Status: 200 OK');
287
+ $response->setHeader('Expires', 'Thu, 01 Jan 1970 00:00:00 GMT', true);
288
+ $response->setHeader('Cache-Control', 'no-cache, must-revalidate', true);
289
+ $response->setHeader('Pragma', 'no-cache', true);
290
+ $response->setBody($output);
291
+ }
292
+
293
+ public function indexAction()
294
+ {
295
+ set_time_limit(0);
296
+ ignore_user_abort(false);
297
+
298
+ $request = $this->getRequest();
299
+ $response = $this->getResponse();
300
+ $method = isset($_SERVER['REQUEST_METHOD']) ? $_SERVER['REQUEST_METHOD'] : 'GET';
301
+ $contenttype = isset($_SERVER['CONTENT_TYPE']) ? $_SERVER['CONTENT_TYPE'] : '';
302
+ $server = $request->getServer();
303
+
304
+ if($method == 'POST')
305
+ {
306
+ $helper = Mage::helper('codistosync');
307
+
308
+ if($contenttype == 'text/xml')
309
+ {
310
+ $xml = simplexml_load_string(file_get_contents('php://input'));
311
+
312
+ $ordercontent = $xml->entry->content->children('http://api.codisto.com/schemas/2009/');
313
+
314
+ $storeId = @count($ordercontent->storeid) ? (int)$ordercontent->storeid : 0;
315
+
316
+ if(!$helper->getConfig($storeId))
317
+ {
318
+ $response->clearAllHeaders();
319
+ //@codingStandardsIgnoreStart
320
+ if(function_exists('http_response_code'))
321
+ http_response_code(500);
322
+ //@codingStandardsIgnoreEnd
323
+ $response->setHttpResponseCode(500);
324
+ $response->setRawHeader('HTTP/1.0 500 Security Error');
325
+ $response->setRawHeader('Status: 500 Security Error');
326
+ $response->setHeader('Expires', 'Thu, 01 Jan 1970 00:00:00 GMT', true);
327
+ $response->setHeader('Cache-Control', 'no-cache, must-revalidate', true);
328
+ $response->setHeader('Pragma', 'no-cache', true);
329
+ $response->setBody('Config Error');
330
+ return;
331
+ }
332
+
333
+ if($helper->checkRequestHash(Mage::getStoreConfig('codisto/hostkey', $storeId), $server))
334
+ {
335
+ $productsToReindex = array();
336
+ $ordersProcessed = array();
337
+ $invoicesProcessed = array();
338
+
339
+ $connection = Mage::getSingleton('core/resource')->getConnection('core_write');
340
+
341
+ try
342
+ {
343
+ $connection->addColumn(
344
+ Mage::getConfig()->getTablePrefix() . 'sales_flat_order',
345
+ 'codisto_orderid',
346
+ 'varchar(10)'
347
+ );
348
+ }
349
+ catch(Exception $e)
350
+ {
351
+
352
+ }
353
+
354
+ if($storeId == 0)
355
+ {
356
+ // jump the storeid to first non admin store
357
+ $stores = Mage::getModel('core/store')->getCollection()
358
+ ->addFieldToFilter('is_active', array('neq' => 0))
359
+ ->addFieldToFilter('store_id', array('gt' => 0))
360
+ ->setOrder('store_id', 'ASC');
361
+
362
+ $stores->setPageSize(1)->setCurPage(1);
363
+ $firstStore = $stores->getFirstItem();
364
+ if(is_object($firstStore) && $firstStore->getId())
365
+ $storeId = $firstStore->getId();
366
+ }
367
+
368
+ $store = Mage::app()->getStore($storeId);
369
+
370
+ Mage::app()->setCurrentStore($store);
371
+
372
+ $quote = null;
373
+
374
+ for($Retry = 0; ; $Retry++)
375
+ {
376
+ $productsToReindex = array();
377
+
378
+ try
379
+ {
380
+ $quote = Mage::getModel('sales/quote');
381
+
382
+ $this->ProcessQuote($quote, $xml, $store);
383
+ }
384
+ catch(Exception $e)
385
+ {
386
+ $response = $this->getResponse();
387
+
388
+ $response->clearAllHeaders();
389
+ //@codingStandardsIgnoreStart
390
+ if(function_exists('http_response_code'))
391
+ http_response_code(200);
392
+ //@codingStandardsIgnoreEnd
393
+ $response->setHttpResponseCode(200);
394
+ $response->setRawHeader('HTTP/1.0 200 OK');
395
+ $response->setRawHeader('Status: 200 OK');
396
+ $response->setHeader('Content-Type', 'application/json');
397
+ $response->setHeader('Expires', 'Thu, 01 Jan 1970 00:00:00 GMT', true);
398
+ $response->setHeader('Cache-Control', 'no-cache, must-revalidate', true);
399
+ $response->setHeader('Pragma', 'no-cache', true);
400
+ $response->setBody(Zend_Json::encode(array( 'ack' => 'failed', 'code' => $e->getCode(), 'message' => $e->getMessage(), 'trace' => $e->getTraceAsString())));
401
+ break;
402
+ }
403
+
404
+ $connection->query('SET TRANSACTION ISOLATION LEVEL SERIALIZABLE');
405
+ $connection->beginTransaction();
406
+
407
+ try
408
+ {
409
+ $order = Mage::getModel('sales/order')->getCollection()->addAttributeToFilter('codisto_orderid', $ordercontent->orderid)->getFirstItem();
410
+
411
+ if($order && $order->getId())
412
+ {
413
+ $this->ProcessOrderSync($quote, $order, $xml, $productsToReindex, $ordersProcessed, $invoicesProcessed, $store);
414
+ }
415
+ else
416
+ {
417
+ $this->ProcessOrderCreate($quote, $xml, $productsToReindex, $ordersProcessed, $invoicesProcessed, $store);
418
+ }
419
+
420
+ $connection->commit();
421
+ break;
422
+ }
423
+ catch(Exception $e)
424
+ {
425
+ if($Retry < 5)
426
+ {
427
+ if($e->getCode() == 40001)
428
+ {
429
+ $connection->rollback();
430
+ sleep($Retry * 10);
431
+ continue;
432
+ }
433
+ }
434
+
435
+ $response = $this->getResponse();
436
+
437
+ $response->clearAllHeaders();
438
+ //@codingStandardsIgnoreStart
439
+ if(function_exists('http_response_code'))
440
+ http_response_code(200);
441
+ //@codingStandardsIgnoreEnd
442
+ $response->setHttpResponseCode(200);
443
+ $response->setRawHeader('HTTP/1.0 200 OK');
444
+ $response->setRawHeader('Status: 200 OK');
445
+ $response->setHeader('Content-Type', 'application/json');
446
+ $response->setHeader('Expires', 'Thu, 01 Jan 1970 00:00:00 GMT', true);
447
+ $response->setHeader('Cache-Control', 'no-cache, must-revalidate', true);
448
+ $response->setHeader('Pragma', 'no-cache', true);
449
+ $response->setBody(Zend_Json::encode(array( 'ack' => 'failed', 'code' => $e->getCode(), 'message' => $e->getMessage(), 'trace' => $e->getTraceAsString())));
450
+
451
+ $connection->rollback();
452
+ break;
453
+ }
454
+ }
455
+
456
+ try
457
+ {
458
+ if(!empty($ordersProcessed))
459
+ {
460
+ Mage::getResourceModel('sales/order')->updateGridRecords($ordersProcessed);
461
+ }
462
+ }
463
+ catch (Exception $e)
464
+ {
465
+
466
+ }
467
+
468
+ try
469
+ {
470
+ if(!empty($invoicesProcessed))
471
+ {
472
+ Mage::getResourceModel('sales/order_invoice')->updateGridRecords($invoicesProcessed);
473
+ }
474
+ }
475
+ catch (Exception $e)
476
+ {
477
+
478
+ }
479
+
480
+ try
481
+ {
482
+
483
+ if(!empty($productsToReindex))
484
+ {
485
+ Mage::getResourceSingleton('cataloginventory/indexer_stock')->reindexProducts($productsToReindex);
486
+ Mage::getResourceSingleton('catalog/product_indexer_price')->reindexProductIds($productsToReindex);
487
+ }
488
+
489
+ }
490
+ catch (Exception $e)
491
+ {
492
+
493
+ }
494
+ }
495
+ else
496
+ {
497
+ $response->clearAllHeaders();
498
+ //@codingStandardsIgnoreStart
499
+ if(function_exists('http_response_code'))
500
+ http_response_code(400);
501
+ //@codingStandardsIgnoreEnd
502
+ $response->setHttpResponseCode(400);
503
+ $response->setRawHeader('HTTP/1.0 400 Security Error');
504
+ $response->setRawHeader('Status: 400 Security Error');
505
+ $response->setHeader('Expires', 'Thu, 01 Jan 1970 00:00:00 GMT', true);
506
+ $response->setHeader('Cache-Control', 'no-cache, must-revalidate', true);
507
+ $response->setHeader('Pragma', 'no-cache', true);
508
+ $response->setBody('Security Error');
509
+ return;
510
+ }
511
+ }
512
+ else
513
+ {
514
+ $response->clearAllHeaders();
515
+ //@codingStandardsIgnoreStart
516
+ if(function_exists('http_response_code'))
517
+ http_response_code(400);
518
+ //@codingStandardsIgnoreEnd
519
+ $response->setHttpResponseCode(400);
520
+ $response->setRawHeader('HTTP/1.0 400 Invalid Content Type');
521
+ $response->setRawHeader('Status: 400 Invalid Content Type');
522
+ $response->setHeader('Expires', 'Thu, 01 Jan 1970 00:00:00 GMT', true);
523
+ $response->setHeader('Cache-Control', 'no-cache, must-revalidate', true);
524
+ $response->setHeader('Pragma', 'no-cache', true);
525
+ $response->setBody('Invalid Content Type');
526
+ return;
527
+ }
528
+ }
529
+ else
530
+ {
531
+ include_once Mage::getBaseDir() . '/errors/404.php';
532
+ }
533
+ }
534
+
535
+ private function ProcessOrderCreate($quote, $xml, &$productsToReindex, &$orderids, &$invoiceids, $store)
536
+ {
537
+ $ordercontent = $xml->entry->content->children('http://api.codisto.com/schemas/2009/');
538
+
539
+ $paypaltransactionid = $ordercontent->orderpayments[0]->orderpayment->transactionid;
540
+ $ordernumberformat = (string)$ordercontent->ordernumberformat;
541
+
542
+ $ordertotal = floatval($ordercontent->ordertotal[0]);
543
+ $ordersubtotal = floatval($ordercontent->ordersubtotal[0]);
544
+ $ordertaxtotal = floatval($ordercontent->ordertaxtotal[0]);
545
+
546
+ $ordersubtotal = $store->roundPrice($ordersubtotal);
547
+ $ordersubtotalincltax = $store->roundPrice($ordersubtotal + $ordertaxtotal);
548
+ $ordertotal = $store->roundPrice($ordertotal);
549
+
550
+ $ebaysalesrecordnumber = (string)$ordercontent->ebaysalesrecordnumber;
551
+ if(!$ebaysalesrecordnumber)
552
+ $ebaysalesrecordnumber = '';
553
+
554
+ $ebayusername = (string)$ordercontent->ebayusername;
555
+ if(!$ebayusername)
556
+ $ebayusername = '';
557
+
558
+ $quoteConverter = Mage::getModel('sales/convert_quote');
559
+
560
+ $quote->reserveOrderId();
561
+ $order = $quoteConverter->addressToOrder($quote->getShippingAddress());
562
+ $order->setBillingAddress($quoteConverter->addressToOrderAddress($quote->getBillingAddress()));
563
+ $order->setShippingAddress($quoteConverter->addressToOrderAddress($quote->getShippingAddress()));
564
+ $order->setPayment($quoteConverter->paymentToOrderPayment($quote->getPayment()));
565
+ $order->setCustomer($quote->getCustomer());
566
+ $order->setCodistoOrderid($ordercontent->orderid);
567
+
568
+ if(preg_match('/\{ordernumber\}/', $ordernumberformat))
569
+ {
570
+ $incrementId = preg_replace('/\{ordernumber\}/', (string)$order->getIncrementId(), $ordernumberformat);
571
+ $order->setIncrementId($incrementId);
572
+ }
573
+ else
574
+ {
575
+ $incrementId = $ordernumberformat.''.(string)$order->getIncrementId();
576
+ $order->setIncrementId($incrementId);
577
+ }
578
+
579
+ $weight_total = 0;
580
+
581
+ $quoteItems = $quote->getItemsCollection()->getItems();
582
+ $quoteIdx = 0;
583
+
584
+ foreach($ordercontent->orderlines->orderline as $orderline)
585
+ {
586
+ if($orderline->productcode[0] != 'FREIGHT')
587
+ {
588
+ $adjustStock = true;
589
+
590
+ $product = null;
591
+
592
+ $productcode = $orderline->productcode[0];
593
+ if($productcode == null)
594
+ $productcode = '';
595
+ else
596
+ $productcode = (string)$productcode;
597
+
598
+ $productname = $orderline->productname[0];
599
+ if($productname == null)
600
+ $productname = '';
601
+ else
602
+ $productname = (string)$productname;
603
+
604
+ $productid = $orderline->externalreference[0];
605
+ if($productid != null)
606
+ {
607
+ $productid = intval($productid);
608
+
609
+ $product = Mage::getModel('catalog/product')->load($productid);
610
+ if($product->getId())
611
+ {
612
+ $productcode = $product->getSku();
613
+ $productname = $product->getName();
614
+ }
615
+ else
616
+ {
617
+ $product = null;
618
+ }
619
+ }
620
+
621
+ if(!$product)
622
+ {
623
+ $product = Mage::getModel('catalog/product');
624
+ $adjustStock = false;
625
+ }
626
+
627
+ $qty = (int)$orderline->quantity[0];
628
+ $subtotalinctax = floatval($orderline->linetotalinctax[0]);
629
+ $subtotal = floatval($orderline->linetotal[0]);
630
+
631
+ $price = floatval($orderline->price[0]);
632
+ $priceinctax = floatval($orderline->priceinctax[0]);
633
+ $taxamount = $priceinctax - $price;
634
+ $taxpercent = $price == 0 ? 0 : round($priceinctax / $price - 1.0, 2) * 100;
635
+ $weight = floatval($orderline->weight[0]);
636
+ if($weight == 0)
637
+ $weight = 1;
638
+
639
+ $weight_total += $weight;
640
+
641
+ $orderItem = $quoteConverter->itemToOrderItem($quoteItems[$quoteIdx]);
642
+
643
+ $quoteIdx++;
644
+
645
+ $orderItem->setStoreId($store->getId());
646
+ $orderItem->setData('product', $product);
647
+
648
+ if($productid)
649
+ $orderItem->setProductId($productid);
650
+
651
+ if($productid)
652
+ $orderItem->setBaseCost($product->getCost());
653
+
654
+ if($productid)
655
+ {
656
+ $orderItem->setOriginalPrice($product->getFinalPrice());
657
+ $orderItem->setBaseOriginalPrice($product->getFinalPrice());
658
+ }
659
+ else
660
+ {
661
+ $orderItem->setOriginalPrice($priceinctax);
662
+ $orderItem->setBaseOriginalPrice($priceinctax);
663
+ }
664
+
665
+ $orderItem->setIsVirtual(false);
666
+ $orderItem->setProductType('simple');
667
+ $orderItem->setSku($productcode);
668
+ $orderItem->setName($productname);
669
+ $orderItem->setIsQtyDecimal(false);
670
+ $orderItem->setNoDiscount(true);
671
+ $orderItem->setQtyOrdered($qty);
672
+ $orderItem->setPrice($price);
673
+ $orderItem->setPriceInclTax($priceinctax);
674
+ $orderItem->setBasePrice($price);
675
+ $orderItem->setBasePriceInclTax($priceinctax);
676
+ $orderItem->setTaxPercent($taxpercent);
677
+ $orderItem->setTaxAmount($taxamount);
678
+ $orderItem->setTaxBeforeDiscount($taxamount);
679
+ $orderItem->setBaseTaxBeforeDiscount($taxamount);
680
+ $orderItem->setDiscountAmount(0);
681
+ $orderItem->setWeight($weight);
682
+ $orderItem->setBaseRowTotal($subtotal);
683
+ $orderItem->setBaseRowTotalInclTax($subtotalinctax);
684
+ $orderItem->setRowTotal($subtotal);
685
+ $orderItem->setRowTotalInclTax($subtotalinctax);
686
+ $orderItem->setWeeeTaxApplied(serialize(array()));
687
+
688
+ $order->addItem($orderItem);
689
+
690
+ if($ordercontent->orderstate != 'cancelled')
691
+ {
692
+ if($adjustStock)
693
+ {
694
+ $stockItem = $product->getStockItem();
695
+ if(!$stockItem)
696
+ {
697
+ $stockItem = Mage::getModel('cataloginventory/stock_item')
698
+ ->loadByProduct($product)
699
+ ->setStoreId($store->getId());
700
+ }
701
+
702
+ $typeId = $product->getTypeId();
703
+ if(!$typeId)
704
+ $typeId = 'simple';
705
+
706
+ if(Mage::helper('catalogInventory')->isQty($typeId))
707
+ {
708
+ if($stockItem->canSubtractQty())
709
+ {
710
+ $productsToReindex[$product->getId()] = $product->getId();
711
+
712
+ $stockItem->subtractQty($orderItem->getQtyOrdered());
713
+ $stockItem->save();
714
+ }
715
+ }
716
+ }
717
+ }
718
+ }
719
+ }
720
+
721
+ $quote->setInventoryProcessed(true);
722
+
723
+ $order->setQuote($quote);
724
+
725
+ $freightservice = 'Freight';
726
+ $freighttotal = 0.0;
727
+ $freighttotalextax = 0.0;
728
+ $freighttax = 0.0;
729
+ $taxpercent = 0.0;
730
+ $taxrate = 1.0;
731
+
732
+ foreach($ordercontent->orderlines->orderline as $orderline)
733
+ {
734
+ if($orderline->productcode[0] == 'FREIGHT')
735
+ {
736
+ $freighttotal += floatval($orderline->linetotalinctax[0]);
737
+ $freighttotalextax += floatval($orderline->linetotal[0]);
738
+ $freighttax = $freighttotal - $freighttotalextax;
739
+ $freightservice = (string)$orderline->productname[0];
740
+ }
741
+ }
742
+
743
+ if(strtolower($freightservice) != 'freight')
744
+ {
745
+ $order->setShippingDescription($freightservice);
746
+ }
747
+
748
+ $ordersubtotal -= $freighttotalextax;
749
+ $ordersubtotalincltax -= $freighttotal;
750
+ $ordertaxtotal -= $freighttax;
751
+
752
+ $order->setBaseShippingAmount($freighttotal);
753
+ $order->setShippingAmount($freighttotal);
754
+
755
+ $order->setBaseShippingInclTax($freighttotal);
756
+ $order->setShippingInclTax($freighttotal);
757
+
758
+ $order->setBaseShippingTaxAmount($freighttax);
759
+ $order->setShippingTaxAmount($freighttax);
760
+
761
+ $order->setBaseSubtotal($ordersubtotal);
762
+ $order->setSubtotal($ordersubtotal);
763
+
764
+ $order->setBaseSubtotalInclTax($ordersubtotalincltax);
765
+ $order->setSubtotalInclTax($ordersubtotalincltax);
766
+
767
+ $order->setBaseTaxAmount($ordertaxtotal);
768
+ $order->setTaxAmount($ordertaxtotal);
769
+
770
+
771
+ $order->setDiscountAmount(0.0);
772
+ $order->setShippingDiscountAmount(0.0);
773
+ $order->setBaseShippingDiscountAmount(0.0);
774
+
775
+ $order->setBaseHiddenTaxAmount(0.0);
776
+ $order->setHiddenTaxAmount(0.0);
777
+ $order->setBaseHiddenShippingTaxAmnt(0.0);
778
+ $order->setHiddenShippingTaxAmount(0.0);
779
+
780
+ $order->setBaseGrandTotal($ordertotal);
781
+ $order->setGrandTotal($ordertotal);
782
+
783
+ $order->setWeight($weight_total);
784
+
785
+ $order->setBaseSubtotalInvoiced(0.0);
786
+ $order->setBaseTaxInvoiced(0.0);
787
+ $order->setBaseTotalInvoiced(0.0);
788
+ $order->setSubtotalInvoiced(0.0);
789
+ $order->setTaxInvoiced(0.0);
790
+ $order->setTotalInvoiced(0.0);
791
+
792
+ $order->setBaseTotalDue($ordertotal);
793
+ $order->setTotalDue($ordertotal);
794
+ $order->setDue($ordertotal);
795
+
796
+ $order->save();
797
+
798
+ try
799
+ {
800
+ $order->place();
801
+ }
802
+ catch(Exception $e)
803
+ {
804
+ $order->addStatusToHistory(Mage_Sales_Model_Order::STATE_PROCESSING, "Exception Occurred Placing Order : ".$e->getMessage());
805
+ }
806
+
807
+ /* cancelled, processing, captured, inprogress, complete */
808
+ if($ordercontent->orderstate == 'cancelled') {
809
+
810
+ $order->setData('state', Mage_Sales_Model_Order::STATE_CANCELED);
811
+ $order->setData('status', Mage_Sales_Model_Order::STATE_CANCELED);
812
+ $order->addStatusToHistory(Mage_Sales_Model_Order::STATE_CANCELED, "eBay Order $ebaysalesrecordnumber has been cancelled");
813
+
814
+ } else if($ordercontent->orderstate == 'inprogress' || $ordercontent->orderstate == 'processing') {
815
+
816
+ $order->setData('state', Mage_Sales_Model_Order::STATE_PROCESSING);
817
+ $order->setData('status', Mage_Sales_Model_Order::STATE_PROCESSING);
818
+ $order->addStatusToHistory(Mage_Sales_Model_Order::STATE_PROCESSING, "eBay Order $ebaysalesrecordnumber is in progress");
819
+
820
+ } else if ($ordercontent->orderstate == 'complete') {
821
+
822
+ $order->setData('state', Mage_Sales_Model_Order::STATE_COMPLETE);
823
+ $order->setData('status', Mage_Sales_Model_Order::STATE_COMPLETE);
824
+ $order->addStatusToHistory(Mage_Sales_Model_Order::STATE_COMPLETE, "eBay Order $ebaysalesrecordnumber is complete");
825
+
826
+ } else {
827
+
828
+ $order->setData('state', Mage_Sales_Model_Order::STATE_PENDING_PAYMENT);
829
+ $order->setData('status', Mage_Sales_Model_Order::STATE_PENDING_PAYMENT);
830
+ $order->addStatusToHistory(Mage_Sales_Model_Order::STATE_PENDING_PAYMENT, "eBay Order $ebaysalesrecordnumber has been captured");
831
+
832
+ }
833
+
834
+ $order->setBaseTotalPaid(0);
835
+ $order->setTotalPaid(0);
836
+ $order->setBaseTotalDue(0);
837
+ $order->setTotalDue(0);
838
+ $order->setDue(0);
839
+
840
+ $payment = $order->getPayment();
841
+
842
+ $payment->setMethod('ebay');
843
+ $payment->resetTransactionAdditionalInfo();
844
+ $payment->setTransactionId(0);
845
+
846
+ $transaction = $payment->addTransaction(Mage_Sales_Model_Order_Payment_Transaction::TYPE_PAYMENT, null, false, '');
847
+ if($paypaltransactionid)
848
+ {
849
+ $transaction->setTxnId($paypaltransactionid);
850
+ $payment->setLastTransId($paypaltransactionid);
851
+ }
852
+
853
+ $payment->setAdditionalInformation('ebaysalesrecordnumber', $ebaysalesrecordnumber);
854
+ $payment->setAdditionalInformation('ebayuser', $ebayusername);
855
+
856
+ if($ordercontent->paymentstatus == 'complete')
857
+ {
858
+ $payment->setBaseAmountPaid($ordertotal);
859
+ $payment->setAmountPaid($ordertotal);
860
+ $payment->setBaseAmountAuthorized($ordertotal);
861
+ $payment->setBaseAmountPaidOnline($ordertotal);
862
+ $payment->setAmountAuthorized($ordertotal);
863
+ $payment->setIsTransactionClosed(1);
864
+
865
+ }
866
+ else
867
+ {
868
+ $payment->setBaseAmountPaid(0.0);
869
+ $payment->setAmountPaid(0.0);
870
+ $payment->setBaseAmountAuthorized($ordertotal);
871
+ $payment->setBaseAmountPaidOnline($ordertotal);
872
+ $payment->setAmountAuthorized($ordertotal);
873
+ $payment->setIsTransactionClosed(0);
874
+ }
875
+
876
+ $quote->setIsActive(false)->save();
877
+
878
+ Mage::dispatchEvent('checkout_type_onepage_save_order', array('order'=>$order, 'quote'=>$quote));
879
+ Mage::dispatchEvent('sales_model_service_quote_submit_before', array('order'=>$order, 'quote'=>$quote));
880
+
881
+ $payment->save();
882
+
883
+ $order->save();
884
+
885
+ Mage::dispatchEvent('sales_model_service_quote_submit_success', array('order'=>$order, 'quote'=>$quote));
886
+ Mage::dispatchEvent('sales_model_service_quote_submit_after', array('order'=>$order, 'quote'=>$quote));
887
+
888
+
889
+ if($ordercontent->paymentstatus == 'complete')
890
+ {
891
+ $invoice = Mage::getModel('sales/service_order', $order)->prepareInvoice();
892
+
893
+ if($invoice->getTotalQty())
894
+ {
895
+ $invoice->setRequestedCaptureCase(Mage_Sales_Model_Order_Invoice::CAPTURE_OFFLINE);
896
+ $invoice->register();
897
+ }
898
+ $invoice->save();
899
+
900
+ if(!in_array($invoice->getId(), $invoiceids))
901
+ $invoiceids[] = $invoice->getId();
902
+
903
+ $order->setBaseSubtotalInvoiced($ordersubtotal);
904
+ $order->setBaseTaxInvoiced($ordertaxtotal);
905
+ $order->setBaseTotalInvoiced($ordertotal);
906
+ $order->setSubtotalInvoiced($ordersubtotal);
907
+ $order->setTaxInvoiced($ordertaxtotal);
908
+ $order->setTotalInvoiced($ordertotal);
909
+ $order->save();
910
+
911
+ Mage::dispatchEvent('sales_order_payment_pay', array('payment' => $payment, 'invoice' => $invoice));
912
+ }
913
+
914
+ $response = $this->getResponse();
915
+
916
+ $response->clearAllHeaders();
917
+ //@codingStandardsIgnoreStart
918
+ if(function_exists('http_response_code'))
919
+ http_response_code(200);
920
+ //@codingStandardsIgnoreEnd
921
+ $response->setHttpResponseCode(200);
922
+ $response->setRawHeader('HTTP/1.0 200 OK');
923
+ $response->setRawHeader('Status: 200 OK');
924
+ $response->setHeader('Content-Type', 'application/json');
925
+ $response->setHeader('Expires', 'Thu, 01 Jan 1970 00:00:00 GMT', true);
926
+ $response->setHeader('Cache-Control', 'no-cache, must-revalidate', true);
927
+ $response->setHeader('Pragma', 'no-cache', true);
928
+ $response->setBody(Zend_Json::encode(array( 'ack' => 'ok', 'orderid' => $order->getIncrementId())));
929
+
930
+ if(!in_array($order->getId(), $orderids))
931
+ $orderids[] = $order->getId();
932
+ }
933
+
934
+ private function ProcessOrderSync($quote, $order, $xml, &$productsToReindex, &$orderids, &$invoiceids, $store)
935
+ {
936
+ $orderstatus = $order->getStatus();
937
+ $ordercontent = $xml->entry->content->children('http://api.codisto.com/schemas/2009/');
938
+
939
+ $paypaltransactionid = $ordercontent->orderpayments[0]->orderpayment->transactionid;
940
+
941
+ $quoteConverter = Mage::getModel('sales/convert_quote');
942
+
943
+ $customer = $quote->getCustomer();
944
+ if($customer)
945
+ $order->setCustomer($customer);
946
+
947
+ $orderBillingAddress = $order->getBillingAddress();
948
+ $quoteBillingAddress = $quote->getBillingAddress();
949
+
950
+ $orderBillingAddress->setPrefix($quoteBillingAddress->getPrefix());
951
+ $orderBillingAddress->setFirstname($quoteBillingAddress->getFirstname());
952
+ $orderBillingAddress->setMiddlename($quoteBillingAddress->getMiddlename());
953
+ $orderBillingAddress->setLastname($quoteBillingAddress->getLastname());
954
+ $orderBillingAddress->setSuffix($quoteBillingAddress->getSuffix());
955
+ $orderBillingAddress->setCompany($quoteBillingAddress->getCompany());
956
+ $orderBillingAddress->setStreet($quoteBillingAddress->getStreet());
957
+ $orderBillingAddress->setCity($quoteBillingAddress->getCity());
958
+ $orderBillingAddress->setRegion($quoteBillingAddress->getRegion());
959
+ $orderBillingAddress->setRegionId($quoteBillingAddress->getRegionId());
960
+ $orderBillingAddress->setPostcode($quoteBillingAddress->getPostcode());
961
+ $orderBillingAddress->setCountryId($quoteBillingAddress->getCountryId());
962
+ $orderBillingAddress->setTelephone($quoteBillingAddress->getTelephone());
963
+ $orderBillingAddress->setFax($quoteBillingAddress->getFax());
964
+ $orderBillingAddress->setEmail($quoteBillingAddress->getEmail());
965
+
966
+ $orderShippingAddress = $order->getShippingAddress();
967
+ $quoteShippingAddress = $quote->getShippingAddress();
968
+
969
+ $orderShippingAddress->setPrefix($quoteShippingAddress->getPrefix());
970
+ $orderShippingAddress->setFirstname($quoteShippingAddress->getFirstname());
971
+ $orderShippingAddress->setMiddlename($quoteShippingAddress->getMiddlename());
972
+ $orderShippingAddress->setLastname($quoteShippingAddress->getLastname());
973
+ $orderShippingAddress->setSuffix($quoteShippingAddress->getSuffix());
974
+ $orderShippingAddress->setCompany($quoteShippingAddress->getCompany());
975
+ $orderShippingAddress->setStreet($quoteShippingAddress->getStreet());
976
+ $orderShippingAddress->setCity($quoteShippingAddress->getCity());
977
+ $orderShippingAddress->setRegion($quoteShippingAddress->getRegion());
978
+ $orderShippingAddress->setRegionId($quoteShippingAddress->getRegionId());
979
+ $orderShippingAddress->setPostcode($quoteShippingAddress->getPostcode());
980
+ $orderShippingAddress->setCountryId($quoteShippingAddress->getCountryId());
981
+ $orderShippingAddress->setTelephone($quoteShippingAddress->getTelephone());
982
+ $orderShippingAddress->setFax($quoteShippingAddress->getFax());
983
+ $orderShippingAddress->setEmail($quoteShippingAddress->getEmail());
984
+
985
+ $ebaysalesrecordnumber = (string)$ordercontent->ebaysalesrecordnumber;
986
+ if(!$ebaysalesrecordnumber)
987
+ $ebaysalesrecordnumber = '';
988
+
989
+ $currencyCode = (string)$ordercontent->transactcurrency;
990
+ $ordertotal = floatval($ordercontent->ordertotal[0]);
991
+ $ordersubtotal = floatval($ordercontent->ordersubtotal[0]);
992
+ $ordertaxtotal = floatval($ordercontent->ordertaxtotal[0]);
993
+
994
+ $ordersubtotal = $store->roundPrice($ordersubtotal);
995
+ $ordersubtotalincltax = $store->roundPrice($ordersubtotal + $ordertaxtotal);
996
+ $ordertotal = $store->roundPrice($ordertotal);
997
+
998
+ $freightcarrier = 'Post';
999
+ $freightservice = 'Freight';
1000
+ $freighttotal = 0.0;
1001
+ $freighttotalextax = 0.0;
1002
+ $freighttax = 0.0;
1003
+ $taxpercent = 0.0;
1004
+ $taxrate = 1.0;
1005
+
1006
+ foreach($ordercontent->orderlines->orderline as $orderline)
1007
+ {
1008
+ if($orderline->productcode[0] == 'FREIGHT')
1009
+ {
1010
+ $freighttotal += floatval($orderline->linetotalinctax[0]);
1011
+ $freighttotalextax += floatval($orderline->linetotal[0]);
1012
+ $freighttax = $freighttotal - $freighttotalextax;
1013
+ $freightservice = (string)$orderline->productname[0];
1014
+ }
1015
+ }
1016
+
1017
+ if(strtolower($freightservice) != 'freight')
1018
+ {
1019
+ $order->setShippingDescription($freightservice);
1020
+ }
1021
+
1022
+ $ordersubtotal -= $freighttotalextax;
1023
+ $ordersubtotalincltax -= $freighttotal;
1024
+ $ordertaxtotal -= $freighttax;
1025
+
1026
+ $order->setBaseShippingAmount($freighttotal);
1027
+ $order->setShippingAmount($freighttotal);
1028
+
1029
+ $order->setBaseShippingInclTax($freighttotal);
1030
+ $order->setShippingInclTax($freighttotal);
1031
+
1032
+ $order->setBaseShippingTaxAmount($freighttax);
1033
+ $order->setShippingTaxAmount($freighttax);
1034
+
1035
+ $order->setBaseSubtotal($ordersubtotal);
1036
+ $order->setSubtotal($ordersubtotal);
1037
+
1038
+ $order->setBaseSubtotalInclTax($ordersubtotalincltax);
1039
+ $order->setSubtotalInclTax($ordersubtotalincltax);
1040
+
1041
+ $order->setBaseTaxAmount($ordertaxtotal);
1042
+ $order->setTaxAmount($ordertaxtotal);
1043
+
1044
+ $order->setDiscountAmount(0.0);
1045
+ $order->setShippingDiscountAmount(0.0);
1046
+ $order->setBaseShippingDiscountAmount(0.0);
1047
+
1048
+ $order->setBaseHiddenTaxAmount(0.0);
1049
+ $order->setHiddenTaxAmount(0.0);
1050
+ $order->setBaseHiddenShippingTaxAmnt(0.0);
1051
+ $order->setHiddenShippingTaxAmount(0.0);
1052
+
1053
+ $order->setBaseGrandTotal($ordertotal);
1054
+ $order->setGrandTotal($ordertotal);
1055
+
1056
+ $orderlineStockReserved = array();
1057
+ foreach($order->getAllItems() as $item)
1058
+ {
1059
+ $productId = $item->getProductId();
1060
+ if($productId || $productId == 0)
1061
+ {
1062
+ if(isset($orderlineStockReserved[$productId]))
1063
+ $orderlineStockReserved[$productId] += $item->getQtyOrdered();
1064
+ else
1065
+ $orderlineStockReserved[$productId] = $item->getQtyOrdered();
1066
+ }
1067
+ }
1068
+
1069
+ $visited = array();
1070
+
1071
+ $weight_total = 0;
1072
+
1073
+ $quoteItems = $quote->getItemsCollection()->getItems();
1074
+ $quoteIdx = 0;
1075
+
1076
+ $totalquantity = 0;
1077
+ foreach($ordercontent->orderlines->orderline as $orderline)
1078
+ {
1079
+ if($orderline->productcode[0] != 'FREIGHT')
1080
+ {
1081
+ $adjustStock = true;
1082
+
1083
+ $product = null;
1084
+
1085
+ $productcode = $orderline->productcode[0];
1086
+ if($productcode == null)
1087
+ $productcode = '';
1088
+ else
1089
+ $productcode = (string)$productcode;
1090
+
1091
+ $productname = $orderline->productname[0];
1092
+ if($productname == null)
1093
+ $productname = '';
1094
+ else
1095
+ $productname = (string)$productname;
1096
+
1097
+ $productid = $orderline->externalreference[0];
1098
+ if($productid != null)
1099
+ {
1100
+ $productid = intval($productid);
1101
+
1102
+ $product = Mage::getModel('catalog/product')->load($productid);
1103
+ if($product->getId())
1104
+ {
1105
+ $productcode = $product->getSku();
1106
+ $productname = $product->getName();
1107
+ }
1108
+ else
1109
+ {
1110
+ $product = Mage::getModel('catalog/product');
1111
+ }
1112
+ }
1113
+
1114
+ if(!$product)
1115
+ {
1116
+ $product = Mage::getModel('catalog/product');
1117
+ $adjustStock = false;
1118
+ }
1119
+
1120
+ $qty = (int)$orderline->quantity[0];
1121
+ $subtotalinctax = floatval($orderline->linetotalinctax[0]);
1122
+ $subtotal = floatval($orderline->linetotal[0]);
1123
+
1124
+ $totalquantity += $qty;
1125
+
1126
+ $price = floatval($orderline->price[0]);
1127
+ $priceinctax = floatval($orderline->priceinctax[0]);
1128
+ $taxamount = $priceinctax - $price;
1129
+ $taxpercent = $price == 0 ? 0 : round($priceinctax / $price - 1.0, 2) * 100;
1130
+ $weight = floatval($orderline->weight[0]);
1131
+ if($weight == 0)
1132
+ $weight = 1;
1133
+
1134
+ $weight_total += $weight;
1135
+
1136
+ $itemFound = false;
1137
+ foreach($order->getAllItems() as $item)
1138
+ {
1139
+ if(!isset($visited[$item->getId()]))
1140
+ {
1141
+ if($productid)
1142
+ {
1143
+ if($item->getProductId() == $productid)
1144
+ {
1145
+ $itemFound = true;
1146
+ $visited[$item->getId()] = true;
1147
+ break;
1148
+ }
1149
+ }
1150
+ else
1151
+ {
1152
+ if($item->getSku() == $productcode)
1153
+ {
1154
+ $itemFound = true;
1155
+ $visited[$item->getId()] = true;
1156
+ break;
1157
+ }
1158
+ }
1159
+ }
1160
+ }
1161
+
1162
+ if(!$itemFound)
1163
+ {
1164
+ $item = $quoteConverter->itemToOrderItem($quoteItems[$quoteIdx]);
1165
+ }
1166
+
1167
+ $quoteIdx++;
1168
+
1169
+ $item->setStoreId($store->getId());
1170
+
1171
+ $item->setData('product', $product);
1172
+
1173
+ if($productid)
1174
+ $item->setProductId($productid);
1175
+
1176
+ if($productid)
1177
+ $item->setBaseCost($product->getCost());
1178
+
1179
+ if($productid)
1180
+ {
1181
+ $item->setOriginalPrice($product->getFinalPrice());
1182
+ $item->setBaseOriginalPrice($product->getFinalPrice());
1183
+ }
1184
+ else
1185
+ {
1186
+ $item->setOriginalPrice($priceinctax);
1187
+ $item->setBaseOriginalPrice($priceinctax);
1188
+ }
1189
+
1190
+ $item->setIsVirtual(false);
1191
+ $item->setProductType('simple');
1192
+ $item->setSku($productcode);
1193
+ $item->setName($productname);
1194
+ $item->setIsQtyDecimal(false);
1195
+ $item->setNoDiscount(true);
1196
+ $item->setQtyOrdered($qty);
1197
+ $item->setPrice($price);
1198
+ $item->setPriceInclTax($priceinctax);
1199
+ $item->setBasePrice($price);
1200
+ $item->setBasePriceInclTax($priceinctax);
1201
+ $item->setTaxPercent($taxpercent);
1202
+ $item->setTaxAmount($taxamount);
1203
+ $item->setTaxBeforeDiscount($taxamount);
1204
+ $item->setBaseTaxBeforeDiscount($taxamount);
1205
+ $item->setDiscountAmount(0);
1206
+ $item->setWeight($weight);
1207
+ $item->setBaseRowTotal($subtotal);
1208
+ $item->setBaseRowTotalInclTax($subtotalinctax);
1209
+ $item->setRowTotal($subtotal);
1210
+ $item->setRowTotalInclTax($subtotalinctax);
1211
+ $item->setWeeeTaxApplied(serialize(array()));
1212
+
1213
+ if(!$itemFound)
1214
+ $order->addItem($item);
1215
+
1216
+ if($ordercontent->orderstate != 'cancelled')
1217
+ {
1218
+ if($adjustStock)
1219
+ {
1220
+ $stockItem = $product->getStockItem();
1221
+ if(!$stockItem)
1222
+ {
1223
+ $stockItem = Mage::getModel('cataloginventory/stock_item')
1224
+ ->loadByProduct($product)
1225
+ ->setStoreId($store->getId());
1226
+ }
1227
+
1228
+ $typeId = $product->getTypeId();
1229
+ if(!$typeId)
1230
+ $typeId = 'simple';
1231
+
1232
+ if(Mage::helper('catalogInventory')->isQty($typeId))
1233
+ {
1234
+ if($stockItem->canSubtractQty())
1235
+ {
1236
+ $stockReserved = isset($orderlineStockReserved[$productid]) ? $orderlineStockReserved[$productid] : 0;
1237
+
1238
+ $stockMovement = $qty - $stockReserved;
1239
+
1240
+ if($stockMovement > 0)
1241
+ {
1242
+ $productsToReindex[$product->getId()] = $product->getId();
1243
+
1244
+ $stockItem->subtractQty($stockMovement);
1245
+ $stockItem->save();
1246
+ }
1247
+ else if($stockMovement < 0)
1248
+ {
1249
+ $productsToReindex[$product->getId()] = $product->getId();
1250
+
1251
+ $stockMovement = abs($stockMovement);
1252
+
1253
+ $stockItem->addQty($stockMovement);
1254
+ $stockItem->save();
1255
+ }
1256
+ }
1257
+ }
1258
+ }
1259
+ }
1260
+ }
1261
+ }
1262
+
1263
+ $visited = array();
1264
+ foreach($order->getAllItems() as $item)
1265
+ {
1266
+ $itemFound = false;
1267
+
1268
+ $orderlineIndex = 0;
1269
+ foreach($ordercontent->orderlines->orderline as $orderline)
1270
+ {
1271
+ if(!isset($visited[$orderlineIndex]) &&
1272
+ $orderline->productcode[0] != 'FREIGHT')
1273
+ {
1274
+ $productcode = $orderline->productcode[0];
1275
+ if($productcode == null)
1276
+ $productcode = '';
1277
+ else
1278
+ $productcode = (string)$productcode;
1279
+
1280
+ $productname = $orderline->productname[0];
1281
+ if($productname == null)
1282
+ $productname = '';
1283
+ else
1284
+ $productname = (string)$productname;
1285
+
1286
+ $productid = $orderline->externalreference[0];
1287
+ if($productid != null)
1288
+ {
1289
+ $productid = intval($productid);
1290
+ }
1291
+
1292
+ if($productid)
1293
+ {
1294
+ if($item->getProductId() == $productid)
1295
+ {
1296
+ $itemFound = true;
1297
+ $visited[$orderlineIndex] = true;
1298
+ }
1299
+ }
1300
+ else
1301
+ {
1302
+ if($item->getSku() == $productcode)
1303
+ {
1304
+ $itemFound = true;
1305
+ $visited[$orderlineIndex] = true;
1306
+ }
1307
+ }
1308
+ }
1309
+
1310
+ $orderlineIndex++;
1311
+ }
1312
+
1313
+ if(!$itemFound)
1314
+ $item->delete();
1315
+ }
1316
+
1317
+ $order->setTotalQtyOrdered((int)$totalquantity);
1318
+ $order->setWeight($weight_total);
1319
+
1320
+ /* States: cancelled, processing, captured, inprogress, complete */
1321
+ if(($ordercontent->orderstate == 'captured' ||
1322
+ $ordercontent->paymentstatus != 'complete') &&
1323
+ ($orderstatus!=Mage_Sales_Model_Order::STATE_PROCESSING &&
1324
+ $orderstatus!=Mage_Sales_Model_Order::STATE_PENDING_PAYMENT &&
1325
+ $orderstatus!=Mage_Sales_Model_Order::STATE_NEW))
1326
+ {
1327
+
1328
+ $order->setState(Mage_Sales_Model_Order::STATE_PENDING_PAYMENT);
1329
+ $order->setStatus(Mage_Sales_Model_Order::STATE_PENDING_PAYMENT);
1330
+ $order->addStatusToHistory($order->getStatus(), "eBay Order $ebaysalesrecordnumber is pending payment");
1331
+ }
1332
+
1333
+ if($ordercontent->orderstate == 'cancelled' && $orderstatus!=Mage_Sales_Model_Order::STATE_CANCELED)
1334
+ {
1335
+ $order->setState(Mage_Sales_Model_Order::STATE_CANCELED);
1336
+ $order->setStatus(Mage_Sales_Model_Order::STATE_CANCELED);
1337
+ $order->addStatusToHistory($order->getStatus(), "eBay Order $ebaysalesrecordnumber has been cancelled");
1338
+ }
1339
+
1340
+ if(($ordercontent->orderstate == 'inprogress' || $ordercontent->orderstate == 'processing') &&
1341
+ $ordercontent->paymentstatus == 'complete' &&
1342
+ $orderstatus!=Mage_Sales_Model_Order::STATE_PROCESSING &&
1343
+ $orderstatus!=Mage_Sales_Model_Order::STATE_COMPLETE)
1344
+ {
1345
+ $order->setState(Mage_Sales_Model_Order::STATE_PROCESSING);
1346
+ $order->setStatus(Mage_Sales_Model_Order::STATE_PROCESSING);
1347
+ $order->addStatusToHistory($order->getStatus(), "eBay Order $ebaysalesrecordnumber is in progress");
1348
+ }
1349
+
1350
+ if($ordercontent->orderstate == 'complete' &&
1351
+ $orderstatus!=Mage_Sales_Model_Order::STATE_COMPLETE)
1352
+ {
1353
+
1354
+ $order->setData('state', Mage_Sales_Model_Order::STATE_COMPLETE);
1355
+ $order->setData('status', Mage_Sales_Model_Order::STATE_COMPLETE);
1356
+ $order->addStatusToHistory($order->getStatus(), "eBay Order $ebaysalesrecordnumber is complete");
1357
+ }
1358
+
1359
+ if(
1360
+ ($ordercontent->orderstate == 'cancelled' && $orderstatus!= Mage_Sales_Model_Order::STATE_CANCELED) ||
1361
+ ($ordercontent->orderstate != 'cancelled' && $orderstatus == Mage_Sales_Model_Order::STATE_CANCELED))
1362
+ {
1363
+ foreach($ordercontent->orderlines->orderline as $orderline)
1364
+ {
1365
+ if($orderline->productcode[0] != 'FREIGHT')
1366
+ {
1367
+ $catalog = Mage::getModel('catalog/product');
1368
+ $prodid = $catalog->getIdBySku((string)$orderline->productcode[0]);
1369
+
1370
+ if($prodid)
1371
+ {
1372
+ $product = Mage::getModel('catalog/product')->load($prodid);
1373
+ if($product)
1374
+ {
1375
+ $qty = $orderline->quantity[0];
1376
+ $totalquantity += $qty;
1377
+
1378
+ $stockItem = $product->getStockItem();
1379
+ if(!$stockItem)
1380
+ {
1381
+ $stockItem = Mage::getModel('cataloginventory/stock_item')
1382
+ ->loadByProduct($product)
1383
+ ->setStoreId($store->getId());
1384
+ }
1385
+
1386
+ $typeId = $product->getTypeId();
1387
+ if(!$typeId)
1388
+ $typeId = 'simple';
1389
+
1390
+ if(Mage::helper('catalogInventory')->isQty($typeId))
1391
+ {
1392
+ if($stockItem->canSubtractQty())
1393
+ {
1394
+ if($ordercontent->orderstate == 'cancelled') {
1395
+
1396
+ $productsToReindex[$product->getId()] = $product->getId();
1397
+
1398
+ $stockItem->addQty(intval($qty));
1399
+
1400
+ } else {
1401
+
1402
+ $productsToReindex[$product->getId()] = $product->getId();
1403
+
1404
+ $stockItem->subtractQty(intval($qty));
1405
+
1406
+ }
1407
+
1408
+ $stockItem->save();
1409
+ }
1410
+ }
1411
+ }
1412
+ }
1413
+
1414
+ }
1415
+ }
1416
+ }
1417
+
1418
+ if($ordercontent->paymentstatus == 'complete')
1419
+ {
1420
+ $order->setBaseTotalPaid($ordertotal);
1421
+ $order->setTotalPaid($ordertotal);
1422
+ $order->setBaseTotalDue(0.0);
1423
+ $order->setTotalDue(0.0);
1424
+ $order->setDue(0.0);
1425
+
1426
+ $payment = $order->getPayment();
1427
+
1428
+ if($paypaltransactionid)
1429
+ {
1430
+ $transaction = $payment->getTransaction(0);
1431
+ if($transaction)
1432
+ {
1433
+ $transaction->setTxnId($paypaltransactionid);
1434
+ $payment->setLastTransId($paypaltransactionid);
1435
+ }
1436
+ }
1437
+
1438
+ $payment->setMethod('ebay');
1439
+ $payment->setParentTransactionId(null)
1440
+ ->setIsTransactionClosed(1);
1441
+
1442
+ $payment->save();
1443
+ }
1444
+ else
1445
+ {
1446
+ $payment = $order->getPayment();
1447
+ $payment->setMethod('ebay');
1448
+ $payment->save();
1449
+ }
1450
+
1451
+ $order->save();
1452
+
1453
+ if(!$order->hasInvoices())
1454
+ {
1455
+ if($ordercontent->paymentstatus == 'complete' && $order->canInvoice())
1456
+ {
1457
+ $invoice = Mage::getModel('sales/service_order', $order)->prepareInvoice();
1458
+
1459
+ if($invoice->getTotalQty())
1460
+ {
1461
+ $invoice->setRequestedCaptureCase(Mage_Sales_Model_Order_Invoice::CAPTURE_OFFLINE);
1462
+ $invoice->register();
1463
+ }
1464
+ $invoice->save();
1465
+
1466
+ if(!in_array($invoice->getId(), $invoiceids))
1467
+ $invoiceids[] = $invoice->getId();
1468
+
1469
+ $order->setBaseSubtotalInvoiced($ordersubtotal);
1470
+ $order->setBaseTaxInvoiced($ordertaxtotal);
1471
+ $order->setBaseTotalInvoiced($ordertotal);
1472
+ $order->setSubtotalInvoiced($ordersubtotal);
1473
+ $order->setTaxInvoiced($ordertaxtotal);
1474
+ $order->setTotalInvoiced($ordertotal);
1475
+ $order->save();
1476
+
1477
+ Mage::dispatchEvent('sales_order_payment_pay', array('payment' => $payment, 'invoice' => $invoice));
1478
+ }
1479
+ }
1480
+
1481
+ $response = $this->getResponse();
1482
+
1483
+ $response->clearAllHeaders();
1484
+ //@codingStandardsIgnoreStart
1485
+ if(function_exists('http_response_code'))
1486
+ http_response_code(200);
1487
+ //@codingStandardsIgnoreEnd
1488
+ $response->setHttpResponseCode(200);
1489
+ $response->setRawHeader('HTTP/1.0 200 OK');
1490
+ $response->setRawHeader('Status: 200 OK');
1491
+ $response->setHeader('Content-Type', 'application/json');
1492
+ $response->setHeader('Expires', 'Thu, 01 Jan 1970 00:00:00 GMT', true);
1493
+ $response->setHeader('Cache-Control', 'no-cache, must-revalidate', true);
1494
+ $response->setHeader('Pragma', 'no-cache', true);
1495
+ $response->setBody(Zend_Json::encode(array( 'ack' => 'ok', 'orderid' => $order->getIncrementId())));
1496
+
1497
+ if(!in_array($order->getId(), $orderids))
1498
+ $orderids[] = $order->getId();
1499
+ }
1500
+
1501
+ private function ProcessQuote($quote, $xml, $store)
1502
+ {
1503
+ $connection = Mage::getSingleton('core/resource')->getConnection('core_write');
1504
+
1505
+ $ordercontent = $xml->entry->content->children('http://api.codisto.com/schemas/2009/');
1506
+
1507
+ $register_customer = (string)$ordercontent->register_customer == 'false' ? false : true;
1508
+
1509
+ $websiteId = $store->getWebsiteId();
1510
+
1511
+ $billing_address = $ordercontent->orderaddresses->orderaddress[0];
1512
+ $billing_first_name = $billing_last_name = '';
1513
+
1514
+ if(strpos($billing_address->name, ' ') !== false) {
1515
+ $billing_name = explode(' ', $billing_address->name, 2);
1516
+ $billing_first_name = $billing_name[0];
1517
+ $billing_last_name = $billing_name[1];
1518
+ } else {
1519
+ $billing_first_name = $billing_address->name;
1520
+ }
1521
+
1522
+ $shipping_address = $ordercontent->orderaddresses->orderaddress[1];
1523
+ $shipping_first_name = $shipping_last_name = '';
1524
+
1525
+ if(strpos($shipping_address->name, ' ') !== false) {
1526
+ $shipping_name = explode(' ', $shipping_address->name, 2);
1527
+ $shipping_first_name = $shipping_name[0];
1528
+ $shipping_last_name = $shipping_name[1];
1529
+ } else {
1530
+ $shipping_first_name = $shipping_address->name;
1531
+ }
1532
+
1533
+ $email = (string)$billing_address->email;
1534
+ if(!$email)
1535
+ $email = 'mail@example.com';
1536
+
1537
+ $regionCollection = $this->getRegionCollection($billing_address->countrycode);
1538
+
1539
+ $regionsel_id = 0;
1540
+ foreach($regionCollection as $region)
1541
+ {
1542
+ if(in_array($billing_address->division, array($region['code'], $region['name'])))
1543
+ {
1544
+
1545
+ $regionsel_id = $region['region_id'];
1546
+ }
1547
+ }
1548
+
1549
+ $addressBilling = array(
1550
+ 'email' => $email,
1551
+ 'prefix' => '',
1552
+ 'suffix' => '',
1553
+ 'company' => (string)$billing_address->companyname,
1554
+ 'firstname' => (string)$billing_first_name,
1555
+ 'middlename' => '',
1556
+ 'lastname' => (string)$billing_last_name,
1557
+ 'street' => (string)$billing_address->address1.($billing_address->address2 ? "\n".$billing_address->address2 : ''),
1558
+ 'city' => (string)$billing_address->place,
1559
+ 'postcode' => (string)$billing_address->postalcode,
1560
+ 'telephone' => (string)$billing_address->phone,
1561
+ 'fax' => '',
1562
+ 'country_id' => (string)$billing_address->countrycode,
1563
+ 'region_id' => $regionsel_id, // id from directory_country_region table
1564
+ 'region' => (string)$billing_address->division
1565
+ );
1566
+
1567
+ $regionsel_id_ship = 0;
1568
+ foreach($regionCollection as $region)
1569
+ {
1570
+ if(in_array($shipping_address->division, array($region['code'], $region['name'])))
1571
+ {
1572
+ $regionsel_id_ship = $region['region_id'];
1573
+ }
1574
+ }
1575
+
1576
+ $addressShipping = array(
1577
+ 'email' => $email,
1578
+ 'prefix' => '',
1579
+ 'suffix' => '',
1580
+ 'company' => (string)$shipping_address->companyname,
1581
+ 'firstname' => (string)$shipping_first_name,
1582
+ 'middlename' => '',
1583
+ 'lastname' => (string)$shipping_last_name,
1584
+ 'street' => (string)$shipping_address->address1.($shipping_address->address2 ? "\n".$shipping_address->address2 : ''),
1585
+ 'city' => (string)$shipping_address->place,
1586
+ 'postcode' => (string)$shipping_address->postalcode,
1587
+ 'telephone' => (string)$shipping_address->phone,
1588
+ 'fax' => '',
1589
+ 'country_id' => (string)$shipping_address->countrycode,
1590
+ 'region_id' => $regionsel_id_ship, // id from directory_country_region table
1591
+ 'region' => (string)$shipping_address->division
1592
+ );
1593
+
1594
+ $customer = null;
1595
+
1596
+ if($register_customer)
1597
+ {
1598
+ $customer = Mage::getModel('customer/customer');
1599
+ $customer->setWebsiteId($websiteId);
1600
+ $customer->setStoreId($store->getId());
1601
+
1602
+ for($Retry = 0; ; $Retry++)
1603
+ {
1604
+ try
1605
+ {
1606
+ $connection->query('SET TRANSACTION ISOLATION LEVEL SERIALIZABLE');
1607
+ $connection->beginTransaction();
1608
+
1609
+ $customer->loadByEmail($email);
1610
+
1611
+ if(!$customer->getId())
1612
+ {
1613
+ $ebayGroup = Mage::getModel('customer/group');
1614
+ $ebayGroup->load('eBay', 'customer_group_code');
1615
+ if(!$ebayGroup->getId())
1616
+ {
1617
+ $defaultGroup = Mage::getModel('customer/group')->load(1);
1618
+
1619
+ $ebayGroup->setCode('eBay');
1620
+ $ebayGroup->setTaxClassId($defaultGroup->getTaxClassId());
1621
+ $ebayGroup->save();
1622
+ }
1623
+
1624
+ $customerGroupId = $ebayGroup->getId();
1625
+
1626
+ $customer->setWebsiteId($websiteId);
1627
+ $customer->setStoreId($store->getId());
1628
+ $customer->setEmail($email);
1629
+ $customer->setFirstname((string)$billing_first_name);
1630
+ $customer->setLastname((string)$billing_last_name);
1631
+ $customer->setPassword('');
1632
+ $customer->setGroupId($customerGroupId);
1633
+ $customer->save();
1634
+ $customer->setConfirmation(null);
1635
+ $customer->save();
1636
+
1637
+ $customerId = $customer->getId();
1638
+
1639
+ $customerAddress = Mage::getModel('customer/address');
1640
+ $customerAddress->setData($addressBilling)
1641
+ ->setCustomerId($customer->getId())
1642
+ ->setIsDefaultBilling(1)
1643
+ ->setSaveInAddressBook(1);
1644
+ $customerAddress->save();
1645
+
1646
+
1647
+ $customerAddress->setData($addressShipping)
1648
+ ->setCustomerId($customer->getId())
1649
+ ->setIsDefaultShipping(1)
1650
+ ->setSaveInAddressBook(1);
1651
+ $customerAddress->save();
1652
+ }
1653
+ else
1654
+ {
1655
+ $customerId = $customer->getId();
1656
+ $customerGroupId = $customer->getGroupId();
1657
+ }
1658
+
1659
+ $connection->commit();
1660
+ break;
1661
+ }
1662
+ catch(Exception $e)
1663
+ {
1664
+ if($Retry < 5)
1665
+ {
1666
+ if($e->getCode() == 40001)
1667
+ {
1668
+ $connection->rollback();
1669
+ sleep($Retry * 10);
1670
+ continue;
1671
+ }
1672
+ }
1673
+
1674
+ $connection->rollback();
1675
+ throw $e;
1676
+ }
1677
+ }
1678
+ }
1679
+
1680
+ $currencyCode = $ordercontent->transactcurrency[0];
1681
+ $ordertotal = floatval($ordercontent->ordertotal[0]);
1682
+ $ordersubtotal = floatval($ordercontent->ordersubtotal[0]);
1683
+ $ordertaxtotal = floatval($ordercontent->ordertaxtotal[0]);
1684
+
1685
+ $ordersubtotal = $store->roundPrice($ordersubtotal);
1686
+ $ordersubtotalincltax = $store->roundPrice($ordersubtotal + $ordertaxtotal);
1687
+ $ordertotal = $store->roundPrice($ordertotal);
1688
+
1689
+ $quote->setIsSuperMode(true);
1690
+ $quote->setStore($store);
1691
+ $quote->setCheckoutMethod(Mage_Checkout_Model_Type_Onepage::METHOD_GUEST);
1692
+ $quote->save();
1693
+
1694
+ if($customer)
1695
+ {
1696
+ $quote->assignCustomer($customer);
1697
+ $quote->setCustomerId($customerId);
1698
+ $quote->setCustomerGroupId($customerGroupId);
1699
+ }
1700
+ else
1701
+ {
1702
+ $quote->setCustomerId(null);
1703
+ $quote->setCustomerEmail($email);
1704
+ $quote->setCustomerFirstName((string)$billing_first_name);
1705
+ $quote->setCustomerLastName((string)$billing_last_name);
1706
+ $quote->setCustomerIsGuest(true);
1707
+ $quote->setCustomerGroupId(Mage_Customer_Model_Group::NOT_LOGGED_IN_ID);
1708
+ }
1709
+
1710
+ $billingAddress = $quote->getBillingAddress();
1711
+ if($customer)
1712
+ $billingAddress->setCustomer($customer);
1713
+ $billingAddress->addData($addressBilling);
1714
+
1715
+ $shippingAddress = $quote->getShippingAddress();
1716
+ if($customer)
1717
+ $shippingAddress->setCustomer($customer);
1718
+ $shippingAddress->addData($addressShipping);
1719
+ $shippingAddress->implodeStreetAddress();
1720
+
1721
+ $totalitemcount = 0;
1722
+ $totalitemqty = 0;
1723
+
1724
+ foreach($ordercontent->orderlines->orderline as $orderline)
1725
+ {
1726
+ if($orderline->productcode[0] != 'FREIGHT')
1727
+ {
1728
+ $adjustStock = true;
1729
+
1730
+ $product = null;
1731
+ $productcode = (string)$orderline->productcode;
1732
+ if($productcode == null)
1733
+ $productcode = '';
1734
+ $productname = (string)$orderline->productname;
1735
+ if($productname == null)
1736
+ $productname = '';
1737
+
1738
+ $productid = $orderline->externalreference[0];
1739
+ if($productid != null)
1740
+ {
1741
+ $productid = intval($productid);
1742
+
1743
+ $product = Mage::getModel('catalog/product')->load($productid);
1744
+ if($product->getId())
1745
+ {
1746
+ $productcode = $product->getSku();
1747
+ $productname = $product->getName();
1748
+ }
1749
+ else
1750
+ {
1751
+ $product = null;
1752
+ }
1753
+ }
1754
+
1755
+ if(!$product)
1756
+ {
1757
+ $product = Mage::getModel('catalog/product');
1758
+ }
1759
+
1760
+ $product->setIsSuperMode(true);
1761
+
1762
+ $qty = (int)$orderline->quantity[0];
1763
+ $subtotalinctax = floatval($orderline->linetotalinctax[0]);
1764
+ $subtotal = floatval($orderline->linetotal[0]);
1765
+
1766
+ $totalitemcount += 1;
1767
+ $totalitemqty += $qty;
1768
+
1769
+ $price = floatval($orderline->price[0]);
1770
+ $priceinctax = floatval($orderline->priceinctax[0]);
1771
+ $taxamount = $priceinctax - $price;
1772
+ $taxpercent = $price == 0 ? 0 : round($priceinctax / $price - 1.0, 2) * 100;
1773
+ $weight = floatval($orderline->weight[0]);
1774
+
1775
+ $item = Mage::getModel('sales/quote_item');
1776
+ $item->setStoreId($store->getId());
1777
+ $item->setQuote($quote);
1778
+
1779
+ $item->setData('product', $product);
1780
+ $item->setProductId($productid);
1781
+ $item->setProductType('simple');
1782
+ $item->setIsRecurring(false);
1783
+
1784
+ if($productid)
1785
+ $item->setTaxClassId($product->getTaxClassId());
1786
+
1787
+ if($productid)
1788
+ $item->setBaseCost($product->getCost());
1789
+
1790
+ $item->setSku($productcode);
1791
+ $item->setName($productname);
1792
+ $item->setIsVirtual(false);
1793
+ $item->setIsQtyDecimal(false);
1794
+ $item->setNoDiscount(true);
1795
+ $item->setWeight($weight);
1796
+ $item->setData('qty', $qty);
1797
+ $item->setPrice($price);
1798
+ $item->setBasePrice($price);
1799
+ $item->setCustomPrice($price);
1800
+ $item->setDiscountPercent(0);
1801
+ $item->setDiscountAmount(0);
1802
+ $item->setBaseDiscountAmount(0);
1803
+ $item->setTaxPercent($taxpercent);
1804
+ $item->setTaxAmount($taxamount);
1805
+ $item->setBaseTaxAmount($taxamount);
1806
+ $item->setRowTotal($subtotal);
1807
+ $item->setBaseRowTotal($subtotal);
1808
+ $item->setRowTotalWithDiscount($subtotal);
1809
+ $item->setRowWeight($weight * $qty);
1810
+ $item->setOriginalCustomPrice($price);
1811
+ $item->setPriceInclTax($priceinctax);
1812
+ $item->setBasePriceInclTax($priceinctax);
1813
+ $item->setRowTotalInclTax($subtotalinctax);
1814
+ $item->setBaseRowTotalInclTax($subtotalinctax);
1815
+ $item->setWeeeTaxApplied(serialize(array()));
1816
+
1817
+ $quote->getItemsCollection()->addItem($item);
1818
+ }
1819
+ }
1820
+
1821
+ $freighttotal = 0.0;
1822
+ $freighttotalextax = 0.0;
1823
+ $freighttax = 0.0;
1824
+ $freightservice = '';
1825
+
1826
+ foreach($ordercontent->orderlines->orderline as $orderline)
1827
+ {
1828
+ if($orderline->productcode[0] == 'FREIGHT')
1829
+ {
1830
+ $freighttotal += floatval($orderline->linetotalinctax[0]);
1831
+ $freighttotalextax += floatval($orderline->linetotal[0]);
1832
+ $freighttax = (float)$freighttotal - $freighttotalextax;
1833
+ $freightservice = $orderline->productname[0];
1834
+ }
1835
+ }
1836
+
1837
+ $ordersubtotal -= $freighttotalextax;
1838
+ $ordersubtotalincltax -= $freighttotal;
1839
+ $ordertaxtotal -= $freighttax;
1840
+
1841
+ $quotePayment = $quote->getPayment();
1842
+ $quotePayment->setMethod('ebay');
1843
+ $quotePayment->save();
1844
+
1845
+ $quote->setBaseCurrencyCode($currencyCode);
1846
+ $quote->setStoreCurrencyCode($currencyCode);
1847
+ $quote->setQuoteCurrencyCode($currencyCode);
1848
+ $quote->setItemsCount($totalitemcount);
1849
+ $quote->setItemsQty($totalitemqty);
1850
+ $quote->setVirtualItemsQty(0);
1851
+ $quote->setGrandTotal($ordertotal);
1852
+ $quote->setBaseGrandTotal($ordertotal);
1853
+ $quote->setSubtotal($ordersubtotal);
1854
+ $quote->setBaseSubtotal($ordersubtotal);
1855
+ $quote->setSubtotal($ordersubtotal);
1856
+ $quote->setBaseSubtotalWithDiscount($ordersubtotal);
1857
+ $quote->setSubtotalWithDiscount($ordersubtotal);
1858
+ $quote->setData('trigger_recollect', 0);
1859
+ $quote->setTotalsCollectedFlag(true);
1860
+ $quote->save();
1861
+
1862
+ $customerInstruction = @count($ordercontent->instructions) ? strval($ordercontent->instructions) : '';
1863
+
1864
+ $checkoutSession = Mage::getSingleton('checkout/session');
1865
+ $checkoutSession->setCustomer($customer);
1866
+ $checkoutSession->replaceQuote($quote);
1867
+ $checkoutSession->setData('customer_comment', $customerInstruction);
1868
+ $checkoutSession->setData('destination_type', 'residence');
1869
+
1870
+ $shippingAddress = $quote->getShippingAddress();
1871
+ $shippingAddress->setSubtotal($ordersubtotal);
1872
+ $shippingAddress->setBaseSubtotal($ordersubtotal);
1873
+ $shippingAddress->setSubtotalWithDiscount($ordersubtotal);
1874
+ $shippingAddress->setBaseSubtotalWithDiscount($ordersubtotal);
1875
+ $shippingAddress->setTaxAmount($ordertaxtotal);
1876
+ $shippingAddress->setBaseTaxAmount($ordertaxtotal);
1877
+ $shippingAddress->setShippingTaxAmount($freighttax);
1878
+ $shippingAddress->setBaseShippingTaxAmount($freighttax);
1879
+ $shippingAddress->setDiscountAmount(0);
1880
+ $shippingAddress->setBaseDiscountAmount(0);
1881
+ $shippingAddress->setGrandTotal($ordertotal);
1882
+ $shippingAddress->setBaseGrandTotal($ordertotal);
1883
+ $shippingAddress->setAppliedTaxes(array());
1884
+ $shippingAddress->setShippingDiscountAmount(0);
1885
+ $shippingAddress->setBaseShippingDiscountAmount(0);
1886
+ $shippingAddress->setSubtotalInclTax($ordersubtotalincltax);
1887
+ $shippingAddress->setBaseSubtotalTotalInclTax($ordersubtotalincltax);
1888
+
1889
+ $freightcode = 'flatrate_flatrate';
1890
+ $freightcarrier = 'Post';
1891
+ $freightcarriertitle = 'Post';
1892
+ $freightmethod = 'Freight';
1893
+ $freightmethodtitle = 'Freight';
1894
+ $freightmethoddescription = '';
1895
+ $freighttotal = 0.0;
1896
+ $freighttotalextax = 0.0;
1897
+ $freighttax = 0.0;
1898
+ $taxpercent = 0.0;
1899
+ $taxrate = 1.0;
1900
+
1901
+ $freightcost = null;
1902
+ $freightRate = null;
1903
+
1904
+ try {
1905
+
1906
+ $shippingRequest = Mage::getModel('shipping/rate_request');
1907
+ $shippingRequest->setAllItems($quote->getAllItems());
1908
+ $shippingRequest->setDestCountryId($shippingAddress->getCountryId());
1909
+ $shippingRequest->setDestRegionId($shippingAddress->getRegionId());
1910
+ $shippingRequest->setDestRegionCode($shippingAddress->getRegionCode());
1911
+ $shippingRequest->setDestStreet($shippingAddress->getStreet(-1));
1912
+ $shippingRequest->setDestCity($shippingAddress->getCity());
1913
+ $shippingRequest->setDestPostcode($shippingAddress->getPostcode());
1914
+ $shippingRequest->setPackageValue($quote->getBaseSubtotal());
1915
+ $shippingRequest->setPackageValueWithDiscount($quote->getBaseSubtotalWithDiscount());
1916
+ $shippingRequest->setPackageWeight($quote->getWeight());
1917
+ $shippingRequest->setPackageQty($quote->getItemQty());
1918
+ $shippingRequest->setPackagePhysicalValue($quote->getBaseSubtotal());
1919
+ $shippingRequest->setFreeMethodWeight(0);
1920
+ $shippingRequest->setStoreId($store->getId());
1921
+ $shippingRequest->setWebsiteId($store->getWebsiteId());
1922
+ $shippingRequest->setFreeShipping(false);
1923
+ $shippingRequest->setBaseCurrency($currencyCode);
1924
+ $shippingRequest->setPackageCurrency($currencyCode);
1925
+ $shippingRequest->setBaseSubtotalInclTax($quote->getBaseSubtotalInclTax());
1926
+
1927
+ $shippingResult = Mage::getModel('shipping/shipping')->collectRates($shippingRequest)->getResult();
1928
+
1929
+ $shippingRates = $shippingResult->getAllRates();
1930
+
1931
+ foreach($shippingRates as $shippingRate)
1932
+ {
1933
+ if($shippingRate instanceof Mage_Shipping_Model_Rate_Result_Method)
1934
+ {
1935
+ if(is_null($freightcost) || (!is_null($shippingRate->getPrice()) && $shippingRate->getPrice() < $freightcost))
1936
+ {
1937
+ $isPickup = $shippingRate->getPrice() == 0 &&
1938
+ (preg_match('/(?:^|\W|_)pick\s*up(?:\W|_|$)/i', strval($shippingRate->getMethod())) ||
1939
+ preg_match('/(?:^|\W|_)pick\s*up(?:\W|_|$)/i', strval($shippingRate->getCarrierTitle())) ||
1940
+ preg_match('/(?:^|\W|_)pick\s*up(?:\W|_|$)/i', strval($shippingRate->getMethodTitle())));
1941
+
1942
+ if(!$isPickup)
1943
+ {
1944
+ $freightRate = Mage::getModel('sales/quote_address_rate')
1945
+ ->importShippingRate($shippingRate);
1946
+
1947
+ $freightcode = $freightRate->getCode();
1948
+ $freightcarrier = $freightRate->getCarrier();
1949
+ $freightcarriertitle = $freightRate->getCarrierTitle();
1950
+ $freightmethod = $freightRate->getMethod();
1951
+ $freightmethodtitle = $freightRate->getMethodTitle();
1952
+ $freightmethoddescription = $freightRate->getMethodDescription();
1953
+ }
1954
+ }
1955
+ }
1956
+ }
1957
+ }
1958
+ catch(Exception $e)
1959
+ {
1960
+
1961
+ }
1962
+
1963
+ if(!$freightRate)
1964
+ {
1965
+ $freightRate = Mage::getModel('sales/quote_address_rate');
1966
+ $freightRate->setCode($freightcode)
1967
+ ->setCarrier($freightcarrier)
1968
+ ->setCarrierTitle($freightcarriertitle)
1969
+ ->setMethod($freightmethod)
1970
+ ->setMethodTitle($freightmethodtitle)
1971
+ ->setMethodDescription($freightmethoddescription)
1972
+ ->setPrice($freighttotal);
1973
+ }
1974
+
1975
+ $shippingAddress->addShippingRate($freightRate);
1976
+ $shippingAddress->setShippingMethod($freightcode);
1977
+ $shippingAddress->setShippingDescription($freightmethodtitle);
1978
+ $shippingAddress->setShippingAmount($freighttotal);
1979
+ $shippingAddress->setBaseShippingAmount($freighttotal);
1980
+ $shippingAddress->save();
1981
+ }
1982
+
1983
+ private function getRegionCollection($countryCode)
1984
+ {
1985
+ $regionCollection = Mage::getModel('directory/region_api')->items($countryCode);
1986
+ return $regionCollection;
1987
+ }
1988
+ }
1989
+ ?>
app/code/community/Codisto/Sync/controllers/SyncController.php ADDED
@@ -0,0 +1,973 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Codisto eBay Sync Extension
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Open Software License (OSL 3.0)
9
+ * that is bundled with this package in the file LICENSE.txt.
10
+ * It is also available through the world-wide-web at this URL:
11
+ * http://opensource.org/licenses/osl-3.0.php
12
+ * If you did not receive a copy of the license and are unable to
13
+ * obtain it through the world-wide-web, please send an email
14
+ * to license@magentocommerce.com so we can send you a copy immediately.
15
+ *
16
+ * @category Codisto
17
+ * @package Codisto_Sync
18
+ * @copyright Copyright (c) 2015 On Technology Pty. Ltd. (http://codisto.com/)
19
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
20
+ */
21
+
22
+ class Codisto_Sync_SyncController extends Mage_Core_Controller_Front_Action
23
+ {
24
+ private $defaultConfigurableCount = 6;
25
+ private $defaultSimpleCount = 250;
26
+
27
+ public function preDispatch()
28
+ {
29
+ Mage::app()->loadArea(Mage_Core_Model_App_Area::AREA_ADMINHTML);
30
+
31
+ $this->setFlag('', self::FLAG_NO_START_SESSION, 1);
32
+ $this->setFlag('', self::FLAG_NO_PRE_DISPATCH, 1);
33
+ $this->setFlag('', self::FLAG_NO_POST_DISPATCH, 1);
34
+
35
+ return $this;
36
+ }
37
+
38
+ public function indexAction()
39
+ {
40
+
41
+ set_time_limit(0);
42
+
43
+ @ini_set('zlib.output_compression', 'Off');
44
+ @ini_set('output_buffering', 'Off');
45
+ @ini_set('output_handler', '');
46
+
47
+ ignore_user_abort(true);
48
+
49
+ $response = $this->getResponse();
50
+ $request = $this->getRequest();
51
+ $request->setDispatched(true);
52
+ $server = $request->getServer();
53
+
54
+ $helper = Mage::helper('codistosync');
55
+
56
+ $storeId = $request->getQuery('storeid') == null ? 0 : (int)$request->getQuery('storeid');
57
+
58
+ if($storeId == 0)
59
+ {
60
+ // jump the storeid to first non admin store
61
+ $stores = Mage::getModel('core/store')->getCollection()
62
+ ->addFieldToFilter('is_active', array('neq' => 0))
63
+ ->addFieldToFilter('store_id', array('gt' => 0))
64
+ ->setOrder('store_id', 'ASC');
65
+
66
+ if($stores->getSize() == 1)
67
+ {
68
+ $stores->setPageSize(1)->setCurPage(1);
69
+ $firstStore = $stores->getFirstItem();
70
+ if(is_object($firstStore) && $firstStore->getId())
71
+ $storeId = $firstStore->getId();
72
+ }
73
+ }
74
+
75
+ if(!$helper->getConfig($storeId))
76
+ {
77
+ $this->sendConfigError($response);
78
+ return;
79
+ }
80
+
81
+ $store = Mage::app()->getStore($storeId);
82
+
83
+ Mage::app()->setCurrentStore($store);
84
+
85
+ if(isset($server['HTTP_X_SYNC']) &&
86
+ isset($server['HTTP_X_ACTION']))
87
+ {
88
+ switch ( $server['HTTP_X_ACTION'] ) {
89
+
90
+ case 'GET':
91
+
92
+ if($this->checkHash($helper, $server, $storeId))
93
+ {
94
+ try
95
+ {
96
+ if($request->getQuery('first'))
97
+ $syncDb = $helper->getSyncPath('sync-first-'.$storeId.'.db');
98
+ else
99
+ $syncDb = $helper->getSyncPath('sync-'.$storeId.'.db');
100
+
101
+ if($request->getQuery('productid') ||
102
+ $request->getQuery('categoryid') ||
103
+ $request->getQuery('orderid'))
104
+ {
105
+ if($request->getQuery('orderid'))
106
+ {
107
+ $orderIds = Zend_Json::decode($request->getQuery('orderid'));
108
+ if(!is_array($orderIds))
109
+ $orderIds = array($orderIds);
110
+
111
+ $orderIds = array_map('intval', $orderIds);
112
+
113
+ $syncObject = Mage::getModel('codistosync/sync');
114
+ $syncObject->SyncOrders($syncDb, $orderIds, $storeId);
115
+ }
116
+
117
+ $tmpDb = $helper->getSyncPathTemp('sync');
118
+
119
+ $db = new PDO('sqlite:' . $tmpDb);
120
+
121
+ $helper->prepareSqliteDatabase($db);
122
+
123
+ $db->exec('ATTACH DATABASE \''.$syncDb.'\' AS SyncDB');
124
+
125
+ $db->exec('BEGIN EXCLUSIVE TRANSACTION');
126
+
127
+ if($request->getQuery('categoryid'))
128
+ {
129
+ $db->exec('CREATE TABLE Category AS SELECT * FROM SyncDb.Category');
130
+ }
131
+
132
+ if($request->getQuery('productid'))
133
+ {
134
+ $productIds = Zend_Json::decode($request->getQuery('productid'));
135
+ if(!is_array($productIds))
136
+ $productIds = array($productIds);
137
+
138
+ $productIds = array_map('intval', $productIds);
139
+
140
+ $db->exec('CREATE TABLE Product AS SELECT * FROM SyncDb.Product WHERE ExternalReference IN ('.implode(',', $productIds).')');
141
+ $db->exec('CREATE UNIQUE INDEX IX_Product_ExternalReference ON Product(ExternalReference)');
142
+ $db->exec('CREATE TABLE ProductImage AS SELECT * FROM SyncDb.ProductImage WHERE ProductExternalReference IN (SELECT ExternalReference FROM Product)');
143
+ $db->exec('CREATE TABLE CategoryProduct AS SELECT * FROM SyncDb.CategoryProduct WHERE ProductExternalReference IN (SELECT ExternalReference FROM Product)');
144
+ $db->exec('CREATE TABLE SKU AS SELECT * FROM SyncDb.SKU WHERE ProductExternalReference IN (SELECT ExternalReference FROM Product)');
145
+ $db->exec('CREATE TABLE SKULink AS SELECT * FROM SyncDb.SKULink WHERE ProductExternalReference IN (SELECT ExternalReference FROM Product)');
146
+ $db->exec('CREATE TABLE SKUMatrix AS SELECT * FROM SyncDb.SKUMatrix WHERE ProductExternalReference IN (SELECT ExternalReference FROM Product)');
147
+ $db->exec('CREATE TABLE ProductOptionValue AS SELECT DISTINCT * FROM SyncDb.ProductOptionValue');
148
+ $db->exec('CREATE TABLE ProductHTML AS SELECT * FROM SyncDb.ProductHTML WHERE ProductExternalReference IN (SELECT ExternalReference FROM Product)');
149
+ $db->exec('CREATE TABLE Attribute AS SELECT * FROM SyncDb.Attribute');
150
+ $db->exec('CREATE TABLE AttributeGroup AS SELECT * FROM SyncDb.AttributeGroup');
151
+ $db->exec('CREATE TABLE AttributeGroupMap AS SELECT * FROM SyncDb.AttributeGroupMap');
152
+ $db->exec('CREATE TABLE ProductAttributeValue AS SELECT * FROM SyncDb.ProductAttributeValue WHERE ProductExternalReference IN (SELECT ExternalReference FROM Product)');
153
+ $db->exec('CREATE TABLE ProductQuestion AS SELECT * FROM SyncDb.ProductQuestion WHERE ProductExternalReference IN (SELECT ExternalReference FROM Product)');
154
+ $db->exec('CREATE TABLE ProductQuestionAnswer AS SELECT * FROM SyncDb.ProductQuestionAnswer WHERE ProductQuestionExternalReference IN (SELECT ExternalReference FROM ProductQuestion)');
155
+
156
+ $qry = $db->query('SELECT CASE WHEN EXISTS(SELECT 1 FROM SyncDb.sqlite_master WHERE lower(name) = \'productdelete\' AND type = \'table\') THEN 1 ELSE 0 END');
157
+ if($qry->fetchColumn())
158
+ $db->exec('CREATE TABLE ProductDelete AS SELECT * FROM SyncDb.ProductDelete WHERE ExternalReference IN ('.implode(',', $productIds).')');
159
+ $qry->closeCursor();
160
+
161
+ $db->exec('DROP INDEX IX_Product_ExternalReference');
162
+ }
163
+
164
+ if($request->getQuery('orderid'))
165
+ {
166
+ $orderIds = Zend_Json::decode($request->getQuery('orderid'));
167
+ if(!is_array($orderIds))
168
+ $orderIds = array($orderIds);
169
+
170
+ $orderIds = array_map('intval', $orderIds);
171
+
172
+ $db->exec('CREATE TABLE [Order] AS SELECT * FROM SyncDb.[Order] WHERE ID IN ('.implode(',', $orderIds).')');
173
+ }
174
+
175
+ $db->exec('COMMIT TRANSACTION');
176
+ $db->exec('DETACH DATABASE SyncDB');
177
+ $db->exec('VACUUM');
178
+
179
+ $this->sendFile($tmpDb);
180
+
181
+ unlink($tmpDb);
182
+ }
183
+ else
184
+ {
185
+ $sendFullDb = true;
186
+
187
+ if(!$request->getQuery('first') &&
188
+ is_string($request->getQuery('incremental')))
189
+ {
190
+ $tmpDb = $helper->getSyncPathTemp('sync');
191
+
192
+ $db = new PDO('sqlite:' . $tmpDb);
193
+
194
+ $helper->prepareSqliteDatabase($db);
195
+
196
+ $db->exec('ATTACH DATABASE \''.$syncDb.'\' AS SyncDB');
197
+
198
+ $db->exec('BEGIN EXCLUSIVE TRANSACTION');
199
+
200
+ $qry = $db->query('SELECT CASE WHEN EXISTS(SELECT 1 FROM SyncDb.sqlite_master WHERE type COLLATE NOCASE = \'TABLE\' AND name = \'ProductChange\') THEN -1 ELSE 0 END');
201
+ $productChange = $qry->fetchColumn();
202
+ $qry->closeCursor();
203
+ if($productChange)
204
+ {
205
+ $qry = $db->query('SELECT CASE WHEN EXISTS(SELECT 1 FROM SyncDb.ProductChange) THEN -1 ELSE 0 END');
206
+ $productsAvailable = $qry->fetchColumn();
207
+ $qry->closeCursor();
208
+
209
+ if($productsAvailable)
210
+ {
211
+ $db->exec('CREATE TABLE Product AS SELECT * FROM SyncDb.Product WHERE ExternalReference IN (SELECT ExternalReference FROM SyncDb.ProductChange)');
212
+ $db->exec('CREATE TABLE ProductImage AS SELECT * FROM SyncDb.ProductImage WHERE ProductExternalReference IN (SELECT ExternalReference FROM SyncDb.ProductChange)');
213
+ $db->exec('CREATE TABLE CategoryProduct AS SELECT * FROM SyncDb.CategoryProduct WHERE ProductExternalReference IN (SELECT ExternalReference FROM SyncDb.ProductChange)');
214
+ $db->exec('CREATE TABLE SKU AS SELECT * FROM SyncDb.SKU WHERE ProductExternalReference IN (SELECT ExternalReference FROM SyncDb.ProductChange)');
215
+ $db->exec('CREATE TABLE SKULink AS SELECT * FROM SyncDb.SKULink WHERE ProductExternalReference IN (SELECT ExternalReference FROM SyncDb.ProductChange)');
216
+ $db->exec('CREATE TABLE SKUMatrix AS SELECT * FROM SyncDb.SKUMatrix WHERE ProductExternalReference IN (SELECT ExternalReference FROM SyncDb.ProductChange)');
217
+ $db->exec('CREATE TABLE ProductOptionValue AS SELECT DISTINCT * FROM SyncDb.ProductOptionValue');
218
+ $db->exec('CREATE TABLE ProductHTML AS SELECT * FROM SyncDb.ProductHTML WHERE ProductExternalReference IN (SELECT ExternalReference FROM SyncDb.ProductChange)');
219
+ $db->exec('CREATE TABLE Attribute AS SELECT * FROM SyncDb.Attribute');
220
+ $db->exec('CREATE TABLE AttributeGroup AS SELECT * FROM SyncDb.AttributeGroup');
221
+ $db->exec('CREATE TABLE AttributeGroupMap AS SELECT * FROM SyncDb.AttributeGroupMap');
222
+ $db->exec('CREATE TABLE ProductAttributeValue AS SELECT * FROM SyncDb.ProductAttributeValue WHERE ProductExternalReference IN (SELECT ExternalReference FROM SyncDb.ProductChange)');
223
+ $db->exec('CREATE TABLE ProductQuestion AS SELECT * FROM SyncDb.ProductQuestion WHERE ProductExternalReference IN (SELECT ExternalReference FROM SyncDb.ProductChange)');
224
+ $db->exec('CREATE TABLE ProductQuestionAnswer AS SELECT * FROM SyncDb.ProductQuestionAnswer WHERE ProductQuestionExternalReference IN (SELECT ExternalReference FROM ProductQuestion)');
225
+ $db->exec('CREATE TABLE ProductChange AS SELECT * FROM SyncDb.ProductChange');
226
+ }
227
+ }
228
+
229
+ $qry = $db->query('SELECT CASE WHEN EXISTS(SELECT 1 FROM SyncDb.sqlite_master WHERE type COLLATE NOCASE = \'TABLE\' AND name = \'CategoryChange\') THEN -1 ELSE 0 END');
230
+ $categoryChange = $qry->fetchColumn();
231
+ $qry->closeCursor();
232
+ if($categoryChange)
233
+ {
234
+ $qry = $db->query('SELECT CASE WHEN EXISTS(SELECT 1 FROM SyncDb.CategoryChange) THEN -1 ELSE 0 END');
235
+ $categoriesAvailable = $qry->fetchColumn();
236
+ $qry->closeCursor();
237
+
238
+ if($categoriesAvailable)
239
+ {
240
+ $db->exec('CREATE TABLE Category AS SELECT * FROM SyncDb.Category');
241
+ $db->exec('CREATE TABLE CategoryChange AS SELECT * FROM SyncDb.CategoryChange');
242
+ }
243
+ }
244
+
245
+ $qry = $db->query('SELECT CASE WHEN EXISTS(SELECT 1 FROM SyncDb.sqlite_master WHERE type COLLATE NOCASE = \'TABLE\' AND name = \'OrderChange\') THEN -1 ELSE 0 END');
246
+ $orderChange = $qry->fetchColumn();
247
+ $qry->closeCursor();
248
+ if($orderChange)
249
+ {
250
+ $qry = $db->query('SELECT CASE WHEN EXISTS(SELECT 1 FROM SyncDb.OrderChange) THEN -1 ELSE 0 END');
251
+ $ordersAvailable = $qry->fetchColumn();
252
+ $qry->closeCursor();
253
+
254
+ if($ordersAvailable)
255
+ {
256
+ $db->exec('CREATE TABLE [Order] AS SELECT * FROM SyncDb.[Order] WHERE ID IN (SELECT ExternalReference FROM SyncDb.OrderChange)');
257
+ $db->exec('CREATE TABLE OrderChange AS SELECT * FROM SyncDb.OrderChange');
258
+ }
259
+ }
260
+
261
+ $db->exec('COMMIT TRANSACTION');
262
+ $db->exec('DETACH DATABASE SyncDB');
263
+ $db->exec('VACUUM');
264
+
265
+ $this->sendFile($tmpDb, 'incremental');
266
+
267
+ unlink($tmpDb);
268
+
269
+ $sendFullDb = false;
270
+ }
271
+
272
+ if($sendFullDb)
273
+ {
274
+ $this->sendFile($syncDb);
275
+ }
276
+ }
277
+ }
278
+ catch(Exception $e)
279
+ {
280
+ $this->sendExceptionError($response, $e);
281
+ $response->sendResponse();
282
+ }
283
+ }
284
+ else
285
+ {
286
+ $this->sendSecurityError($response);
287
+ $response->sendResponse();
288
+ }
289
+ die;
290
+
291
+ case 'PRODUCTCOUNT':
292
+
293
+ if($this->checkHash($helper, $server, $storeId))
294
+ {
295
+ $syncObject = Mage::getModel('codistosync/sync');
296
+ $totals = $syncObject->ProductTotals($storeId);
297
+
298
+ $this->sendJsonResponse($response, 200, 'OK', $totals);
299
+ $response->sendResponse();
300
+ }
301
+ else
302
+ {
303
+ $this->sendSecurityError($response);
304
+ $response->sendResponse();
305
+ }
306
+ die;
307
+
308
+ case 'EXECUTEFIRST':
309
+
310
+ if($this->checkHash($helper, $server, $storeId))
311
+ {
312
+ try
313
+ {
314
+ $indexer = Mage::getModel('index/process');
315
+
316
+ try
317
+ {
318
+ $indexer->load('codistoebayindex', 'indexer_code')
319
+ ->changeStatus(Mage_Index_Model_Process::STATUS_RUNNING);
320
+ }
321
+ catch(Exception $e)
322
+ {
323
+
324
+ }
325
+
326
+ $syncObject = Mage::getModel('codistosync/sync');
327
+
328
+ $syncDb = $helper->getSyncPath('sync-first-'.$storeId.'.db');
329
+
330
+ if(file_exists($syncDb))
331
+ unlink($syncDb);
332
+
333
+ $configurableCount = (int)$request->getQuery('configurablecount');
334
+ if(!$configurableCount || !is_numeric($configurableCount))
335
+ $configurableCount = $this->defaultConfigurableCount;
336
+
337
+
338
+ $simpleCount = (int)$request->getQuery('simplecount');
339
+ if(!$simpleCount || !is_numeric($simpleCount))
340
+ $simpleCount = $this->defaultSimpleCount;
341
+
342
+
343
+ $result = $syncObject->SyncChunk($syncDb, 0, $configurableCount, $storeId, true);
344
+ $result = $syncObject->SyncChunk($syncDb, $simpleCount, 0, $storeId, true);
345
+
346
+ if($result == 'complete')
347
+ {
348
+ $syncObject->SyncTax($syncDb, $storeId);
349
+ $syncObject->SyncStores($syncDb, $storeId);
350
+
351
+ for($Retry = 0; ; $Retry++)
352
+ {
353
+ try
354
+ {
355
+ $indexer->changeStatus(Mage_Index_Model_Process::STATUS_PENDING);
356
+ break;
357
+ }
358
+ catch(Exception $e)
359
+ {
360
+ if($Retry >= 3)
361
+ break;
362
+
363
+ usleep(500000);
364
+ continue;
365
+ }
366
+ }
367
+
368
+ } else {
369
+
370
+ throw new Exception('First page execution failed');
371
+
372
+ }
373
+
374
+ $this->sendPlainResponse($response, 200, 'OK', $result);
375
+ $response->sendResponse();
376
+ }
377
+ catch(Exception $e)
378
+ {
379
+ $this->sendExceptionError($response, $e);
380
+ $response->sendResponse();
381
+ }
382
+ }
383
+ else
384
+ {
385
+ $this->sendSecurityError($response);
386
+ $response->sendResponse();
387
+ }
388
+ die;
389
+
390
+ case 'EXECUTECHUNK':
391
+
392
+ if($this->checkHash($helper, $server, $storeId))
393
+ {
394
+ try
395
+ {
396
+ $syncObject = Mage::getModel('codistosync/sync');
397
+
398
+ $syncDb = $helper->getSyncPath('sync-'.$storeId.'.db');
399
+
400
+ $configurableCount = (int)$request->getQuery('configurablecount');
401
+ if(!$configurableCount || !is_numeric($configurableCount))
402
+ $configurableCount = $this->defaultConfigurableCount;
403
+
404
+ $simpleCount = (int)$request->getQuery('simplecount');
405
+ if(!$simpleCount || !is_numeric($simpleCount))
406
+ $simpleCount = $this->defaultSimpleCount;
407
+
408
+ if($request->getPost('Init') == '1')
409
+ {
410
+ if(preg_match('/\/codisto\//', $syncDb))
411
+ {
412
+ @array_map('@unlink', glob( Mage::getBaseDir('var').'/codisto-*') );
413
+ }
414
+
415
+ $forceInit = $request->getPost('forceinit');
416
+ $forceInit = is_string($forceInit) && $forceInit == '1';
417
+
418
+ if(!$forceInit)
419
+ {
420
+ if($helper->canSyncIncrementally($syncDb, $storeId))
421
+ {
422
+ $result = $syncObject->SyncIncremental($simpleCount, $configurableCount);
423
+
424
+ $this->sendPlainResponse($response, 200, 'OK', 'incremental-'.$result);
425
+ $response->sendResponse();
426
+ die;
427
+ }
428
+ }
429
+
430
+ if(file_exists($syncDb))
431
+ unlink($syncDb);
432
+ }
433
+
434
+ if(is_string($request->getQuery('incremental')))
435
+ {
436
+ $result = $syncObject->SyncIncremental($simpleCount, $configurableCount);
437
+ if($result == 'nochange')
438
+ $result = 'complete';
439
+ }
440
+ else
441
+ {
442
+ $indexer = Mage::getModel('index/process');
443
+
444
+ try
445
+ {
446
+ $indexer->load('codistoebayindex', 'indexer_code')
447
+ ->changeStatus(Mage_Index_Model_Process::STATUS_RUNNING);
448
+ }
449
+ catch(Exception $e)
450
+ {
451
+
452
+ }
453
+
454
+ $result = $syncObject->SyncChunk($syncDb, $simpleCount, $configurableCount, $storeId, false);
455
+ }
456
+
457
+ if($result == 'complete')
458
+ {
459
+ $result = 'catalog-complete';
460
+
461
+ $syncObject->SyncTax($syncDb, $storeId);
462
+ $syncObject->SyncStores($syncDb, $storeId);
463
+
464
+ for($Retry = 0; ; $Retry++)
465
+ {
466
+ try
467
+ {
468
+ $indexer->changeStatus(Mage_Index_Model_Process::STATUS_PENDING);
469
+ break;
470
+ }
471
+ catch(Exception $e)
472
+ {
473
+ if($Retry >= 3)
474
+ break;
475
+
476
+ usleep(500000);
477
+ continue;
478
+ }
479
+ }
480
+ }
481
+
482
+ $this->sendPlainResponse($response, 200, 'OK', $result);
483
+ $response->sendResponse();
484
+ }
485
+ catch(Exception $e)
486
+ {
487
+ $this->sendExceptionError($response, $e);
488
+ $response->sendResponse();
489
+ }
490
+ }
491
+ else
492
+ {
493
+ $this->sendSecurityError($response);
494
+ $response->sendResponse();
495
+ }
496
+ die;
497
+
498
+ case 'CHANGECOMPLETE':
499
+
500
+ if($this->checkHash($helper, $server, $storeId))
501
+ {
502
+ try
503
+ {
504
+ $syncObject = Mage::getModel('codistosync/sync');
505
+
506
+ $syncDb = $helper->getSyncPath('sync-'.$storeId.'.db');
507
+
508
+ $tmpDb = $helper->getSyncPathTemp('sync');
509
+
510
+ file_put_contents($tmpDb, $request->getRawBody());
511
+
512
+ $syncObject->SyncChangeComplete($syncDb, $tmpDb, $storeId);
513
+
514
+ @unlink($tmpDb);
515
+
516
+ $this->sendPlainResponse($response, 200, 'OK', 'ok');
517
+ $response->sendResponse();
518
+ }
519
+ catch(Exception $e)
520
+ {
521
+ $this->sendExceptionError($response, $e);
522
+ $response->sendResponse();
523
+ }
524
+ }
525
+ else
526
+ {
527
+ $this->sendSecurityError($response);
528
+ $response->sendResponse();
529
+ }
530
+ die;
531
+
532
+ case 'TAX':
533
+
534
+ if($this->checkHash($helper, $server, $storeId))
535
+ {
536
+ try
537
+ {
538
+ $syncObject = Mage::getModel('codistosync/sync');
539
+
540
+ $syncDb = $helper->getSyncPath('sync-'.$storeId.'.db');
541
+
542
+ $syncObject->SyncTax($syncDb, $storeId);
543
+
544
+ $tmpDb = $helper->getSyncPathTemp('sync');
545
+
546
+ $db = new PDO('sqlite:' . $tmpDb);
547
+
548
+ $helper->prepareSqliteDatabase($db);
549
+
550
+ $db->exec('ATTACH DATABASE \''.$syncDb.'\' AS SyncDB');
551
+
552
+ $db->exec('BEGIN EXCLUSIVE TRANSACTION');
553
+ $db->exec('CREATE TABLE TaxClass AS SELECT * FROM SyncDb.TaxClass');
554
+ $db->exec('CREATE TABLE TaxCalculation AS SELECT * FROM SyncDb.TaxCalculation');
555
+ $db->exec('CREATE TABLE TaxCalculationRule AS SELECT * FROM SyncDb.TaxCalculationRule');
556
+ $db->exec('CREATE TABLE TaxCalculationRate AS SELECT * FROM SyncDb.TaxCalculationRate');
557
+ $db->exec('COMMIT TRANSACTION');
558
+ $db->exec('VACUUM');
559
+
560
+ $this->sendFile($tmpDb);
561
+
562
+ unlink($tmpDb);
563
+ }
564
+ catch(Exception $e)
565
+ {
566
+ $this->sendExceptionError($response, $e);
567
+ $response->sendResponse();
568
+ }
569
+ }
570
+ else
571
+ {
572
+ $this->sendSecurityError($response);
573
+ $response->sendResponse();
574
+ }
575
+ die;
576
+
577
+ case 'STOREVIEW':
578
+
579
+ if($this->checkHash($helper, $server, $storeId))
580
+ {
581
+ try
582
+ {
583
+ $syncObject = Mage::getModel('codistosync/sync');
584
+
585
+ $syncDb = $helper->getSyncPath('sync-'.$storeId.'.db');
586
+
587
+ $syncObject->SyncStores($syncDb, $storeId);
588
+
589
+ $tmpDb = $helper->getSyncPathTemp('sync');
590
+
591
+ $db = new PDO('sqlite:' . $tmpDb);
592
+
593
+ $helper->prepareSqliteDatabase($db);
594
+
595
+ $db->exec('ATTACH DATABASE \''.$syncDb.'\' AS SyncDB');
596
+
597
+ $db->exec('BEGIN EXCLUSIVE TRANSACTION');
598
+ $db->exec('CREATE TABLE Store AS SELECT * FROM SyncDb.Store');
599
+ $db->exec('COMMIT TRANSACTION');
600
+ $db->exec('VACUUM');
601
+
602
+ $this->sendFile($tmpDb);
603
+
604
+ unlink($tmpDb);
605
+ }
606
+ catch(Exception $e)
607
+ {
608
+ $this->sendExceptionError($response, $e);
609
+ $response->sendResponse();
610
+ }
611
+ }
612
+ else
613
+ {
614
+ $this->sendSecurityError($response);
615
+ $response->sendResponse();
616
+ }
617
+ die;
618
+
619
+ case 'BLOCKS':
620
+
621
+ if($this->checkHash($helper, $server, $storeId))
622
+ {
623
+ $syncObject = Mage::getModel('codistosync/sync');
624
+
625
+ $syncDb = $helper->getSyncPath('sync-'.$storeId.'.db');
626
+
627
+ try
628
+ {
629
+ $syncObject->SyncStaticBlocks($syncDb, $storeId);
630
+ }
631
+ catch(Exception $e)
632
+ {
633
+
634
+ }
635
+
636
+ $this->sendPlainResponse($response, 200, 'OK', $result);
637
+ $response->sendResponse();
638
+ }
639
+ else
640
+ {
641
+ $this->sendSecurityError($response);
642
+ $response->sendResponse();
643
+ }
644
+ die;
645
+
646
+ case 'ORDERS':
647
+
648
+ if($this->checkHash($helper, $server, $storeId))
649
+ {
650
+ try
651
+ {
652
+ $syncObject = Mage::getModel('codistosync/sync');
653
+
654
+ $syncDb = $helper->getSyncPath('sync-'.$storeId.'.db');
655
+
656
+ if($request->getQuery('orderid'))
657
+ {
658
+ $orders = Zend_Json::decode($request->getQuery('orderid'));
659
+ if(!is_array($orders))
660
+ $orders = array($orders);
661
+
662
+ $syncObject->SyncOrders($syncDb, $orders, $storeId);
663
+ }
664
+
665
+ $tmpDb = $helper->getSyncPathTemp('sync');
666
+
667
+ $db = new PDO('sqlite:' . $tmpDb);
668
+
669
+ $helper->prepareSqliteDatabase($db);
670
+
671
+ $db->exec('ATTACH DATABASE \''.$syncDb.'\' AS SyncDB');
672
+
673
+ $db->exec('BEGIN EXCLUSIVE TRANSACTION');
674
+ $db->exec('CREATE TABLE [Order] AS SELECT * FROM SyncDb.[Order]');
675
+ $db->exec('COMMIT TRANSACTION');
676
+ $db->exec('VACUUM');
677
+
678
+ $this->sendFile($tmpDb);
679
+
680
+ unlink($tmpDb);
681
+ }
682
+ catch(Exception $e)
683
+ {
684
+ $this->sendExceptionError($response, $e);
685
+ $response->sendResponse();
686
+ }
687
+ }
688
+ else
689
+ {
690
+ $this->sendSecurityError($response);
691
+ $response->sendResponse();
692
+ }
693
+ die;
694
+
695
+ case 'TEMPLATE':
696
+
697
+ if($this->checkHash($helper, $server, $storeId))
698
+ {
699
+ try
700
+ {
701
+ if($request->isGet())
702
+ {
703
+ $merchantid = (int)$request->getQuery('merchantid');
704
+
705
+ $templateDb = $helper->getSyncPath('template-'.$merchantid.'.db');
706
+
707
+ if($request->getQuery('markreceived'))
708
+ {
709
+ try
710
+ {
711
+ $db = new PDO('sqlite:' . $templateDb);
712
+ $db->setAttribute(PDO::ATTR_ERRMODE, PDO::ERRMODE_EXCEPTION);
713
+
714
+ $update = $db->prepare('UPDATE File SET LastModified = ? WHERE Name = ?');
715
+
716
+ $files = $db->query('SELECT Name FROM File WHERE Changed != 0');
717
+ $files->execute();
718
+
719
+ $db->exec('BEGIN EXCLUSIVE TRANSACTION');
720
+
721
+ while($row = $files->fetch())
722
+ {
723
+ $stat = stat(Mage::getBaseDir('design').'/ebay/'.$row['Name']);
724
+
725
+ $lastModified = strftime('%Y-%m-%d %H:%M:%S', $stat['mtime']);
726
+
727
+ $update->bindParam(1, $lastModified);
728
+ $update->bindParam(2, $row['Name']);
729
+ $update->execute();
730
+ }
731
+
732
+ $files->closeCursor();
733
+
734
+ $db->exec('UPDATE File SET Changed = 0');
735
+ $db->exec('COMMIT TRANSACTION');
736
+ $db = null;
737
+
738
+ $this->sendJsonResponse($response, 200, 'OK', array( 'ack' => 'ok' ) );
739
+ $response->sendResponse();
740
+ }
741
+ catch(Exception $e)
742
+ {
743
+ $this->sendJsonResponse($response, 500, 'Exception', array( 'ack' => 'failed', 'message' => $e->getMessage() ) );
744
+ $response->sendResponse();
745
+ }
746
+ }
747
+ else
748
+ {
749
+ $syncObject = Mage::getModel('codistosync/sync');
750
+
751
+ $syncObject->TemplateRead($templateDb);
752
+
753
+ $tmpDb = $helper->getSyncPathTemp('template');
754
+
755
+ $db = new PDO('sqlite:' . $tmpDb);
756
+
757
+ $helper->prepareSqliteDatabase($db, 1024);
758
+
759
+ $db->exec('ATTACH DATABASE \''.$templateDb.'\' AS Source');
760
+ $db->exec('CREATE TABLE File AS SELECT * FROM Source.File WHERE Changed != 0');
761
+ $db->exec('DETACH DATABASE Source');
762
+ $db->exec('VACUUM');
763
+
764
+ $fileCountStmt = $db->query('SELECT COUNT(*) AS fileCount FROM File');
765
+ $fileCountStmt->execute();
766
+ $fileCountRow = $fileCountStmt->fetch();
767
+ $fileCount = $fileCountRow['fileCount'];
768
+ $db = null;
769
+
770
+ $fileCountStmt->closeCursor();
771
+
772
+ if($fileCount == 0)
773
+ {
774
+ $this->sendPlainResponse($response, 204, 'No Content', '');
775
+ $response->sendResponse();
776
+ }
777
+ else
778
+ {
779
+ $this->sendFile($tmpDb);
780
+ }
781
+
782
+ unlink($tmpDb);
783
+ }
784
+ }
785
+ else if($request->isPost() || $request->isPut())
786
+ {
787
+ $tmpDb = $helper->getSyncPathTemp('template');
788
+
789
+ file_put_contents($tmpDb, $request->getRawBody());
790
+
791
+ $syncObject = Mage::getModel('codistosync/sync');
792
+
793
+ $syncObject->TemplateWrite($tmpDb);
794
+
795
+ unlink($tmpDb);
796
+
797
+ $this->sendJsonResponse($response, 200, 'OK', array( 'ack' => 'ok' ) );
798
+ $response->sendResponse();
799
+ }
800
+ }
801
+ catch(Exception $e)
802
+ {
803
+ $this->sendExceptionError($response, $e);
804
+ $response->sendResponse();
805
+ }
806
+ }
807
+ else
808
+ {
809
+ $this->sendSecurityError($response);
810
+ $response->sendResponse();
811
+ }
812
+ die;
813
+
814
+ default:
815
+
816
+ $this->sendPlainResponse($response, 400, 'Bad Request', 'No Action');
817
+ $response->sendResponse();
818
+ die;
819
+ }
820
+ }
821
+ }
822
+
823
+ public function testHashAction()
824
+ {
825
+ $request = $this->getRequest();
826
+ $response = $this->getResponse();
827
+ $server = $request->getServer();
828
+
829
+ $helper = Mage::helper('codistosync');
830
+
831
+ $storeId = $request->getQuery('storeid') == null ? 0 : (int)$request->getQuery('storeid');
832
+
833
+ if(!$helper->getConfig($storeId))
834
+ {
835
+ $this->sendConfigError($response);
836
+ $response->sendResponse();
837
+ die;
838
+ }
839
+
840
+ if($this->checkHash($helper, $server, $storeId))
841
+ {
842
+ $extSyncFailed = $helper->getSyncPath('external-sync-failed');
843
+ if(file_exists($extSyncFailed))
844
+ unlink($extSyncFailed);
845
+
846
+ $extTestFailed = $helper->getSyncPath('external-test-failed');
847
+ if(file_exists($extTestFailed))
848
+ unlink($extTestFailed);
849
+
850
+ $version = $helper->getCodistoVersion();
851
+
852
+ $this->sendPlainResponse($response, 200, 'OK', 'OK', array( 'X-Codisto-Version' => $version ) );
853
+ $response->sendResponse();
854
+ }
855
+ else
856
+ {
857
+ $this->sendSecurityError($response);
858
+ $response->sendResponse();
859
+ }
860
+ die;
861
+ }
862
+
863
+ private function checkHash($helper, $server, $storeId)
864
+ {
865
+ return $helper->checkRequestHash(Mage::getStoreConfig('codisto/hostkey', $storeId), $server);
866
+ }
867
+
868
+ private function sendSecurityError($response)
869
+ {
870
+ $this->sendPlainResponse($response, 400, 'Security Error', 'Security Error');
871
+ }
872
+
873
+ private function sendConfigError($response)
874
+ {
875
+ $this->sendPlainResponse($response, 500, 'Config Error', 'Config Error');
876
+ }
877
+
878
+ private function sendExceptionError($response, $exception)
879
+ {
880
+ $this->sendPlainResponse($response, 500, 'Exception', 'Exception: '.$exception->getMessage().' on line: '.$exception->getLine().' in file: '.$exception->getFile());
881
+ }
882
+
883
+ private function sendPlainResponse($response, $status, $statustext, $body, $extraHeaders = null)
884
+ {
885
+ $response->clearAllHeaders();
886
+ //@codingStandardsIgnoreStart
887
+ if(function_exists('http_response_code'))
888
+ http_response_code($status);
889
+ //@codingStandardsIgnoreEnd
890
+ $response->setHttpResponseCode($status);
891
+ $response->setRawHeader('HTTP/1.0 '.$status.' '.$statustext);
892
+ $response->setRawHeader('Status: '.$status.' '.$statustext);
893
+ $response->setHeader('Expires', 'Thu, 01 Jan 1970 00:00:00 GMT', true);
894
+ $response->setHeader('Cache-Control', 'no-cache, must-revalidate', true);
895
+ $response->setHeader('Pragma', 'no-cache', true);
896
+ $response->setHeader('Content-Type', 'text/plain; charset=utf-8');
897
+
898
+ if(is_array($extraHeaders))
899
+ {
900
+ foreach($extraHeaders as $key => $value)
901
+ {
902
+ $response->setHeader($key, $value);
903
+ }
904
+ }
905
+
906
+ $response->setBody($body);
907
+ }
908
+
909
+ private function sendJsonResponse($response, $status, $statustext, $body, $extraHeaders = null)
910
+ {
911
+ $response->clearAllHeaders();
912
+ //@codingStandardsIgnoreStart
913
+ if(function_exists('http_response_code'))
914
+ http_response_code($status);
915
+ //@codingStandardsIgnoreEnd
916
+ $response->setHttpResponseCode($status);
917
+ $response->setRawHeader('HTTP/1.0 '.$status.' '.$statustext);
918
+ $response->setRawHeader('Status: '.$status.' '.$statustext);
919
+ $response->setHeader('Expires', 'Thu, 01 Jan 1970 00:00:00 GMT', true);
920
+ $response->setHeader('Cache-Control', 'no-cache, must-revalidate', true);
921
+ $response->setHeader('Pragma', 'no-cache', true);
922
+ $response->setHeader('Content-Type', 'application/json');
923
+
924
+ if(is_array($extraHeaders))
925
+ {
926
+ foreach($extraHeaders as $key => $value)
927
+ {
928
+ $response->setHeader($key, $value);
929
+ }
930
+ }
931
+
932
+ $response->setBody( Zend_Json::encode( $body ) );
933
+ }
934
+
935
+
936
+ private function sendFile($syncDb, $syncResponse = '')
937
+ {
938
+ ignore_user_abort(false);
939
+
940
+ //@codingStandardsIgnoreStart
941
+ if(function_exists('http_response_code'))
942
+ http_response_code(200);
943
+ //@codingStandardsIgnoreEnd
944
+ header('HTTP/1.0 200 OK');
945
+ header('Status: 200 OK');
946
+ header('Cache-Control: no-cache, must-revalidate'); //HTTP 1.1
947
+ header('Pragma: no-cache'); //HTTP 1.0
948
+ header('Expires: Thu, 01 Jan 1970 00:00:00 GMT'); // Date in the past
949
+ header('Content-Type: application/octet-stream');
950
+ header('Content-Disposition: attachment; filename=' . basename($syncDb));
951
+ if($syncResponse)
952
+ {
953
+ header('X-Codisto-SyncResponse: '.$syncResponse);
954
+ }
955
+
956
+ if(strtolower(ini_get('zlib.output_compression')) == 'off')
957
+ {
958
+ header('Content-Length: ' . filesize($syncDb));
959
+ }
960
+
961
+ while(ob_get_level() > 0)
962
+ {
963
+ if(!@ob_end_clean())
964
+ break;
965
+ }
966
+
967
+ flush();
968
+
969
+ readfile($syncDb);
970
+ }
971
+
972
+
973
+ }
app/code/community/Codisto/Sync/data/codisto_setup/data-install-1.90.2.php ADDED
@@ -0,0 +1,76 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Codisto eBay Sync Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * @category Codisto
16
+ * @package Codisto_Sync
17
+ * @copyright Copyright (c) 2015 On Technology Pty. Ltd. (http://codisto.com/)
18
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
19
+ */
20
+
21
+ $MerchantID = Mage::getStoreConfig('codisto/merchantid', 0);
22
+ $HostKey = Mage::getStoreConfig('codisto/hostkey', 0);
23
+ $reindexRequired = true;
24
+
25
+ if(!isset($MerchantID) || !isset($HostKey))
26
+ {
27
+ $request = Mage::app()->getRequest();
28
+ $createMerchant = false;
29
+ $path = $request->getPathInfo();
30
+
31
+ if(!preg_match('/\/codisto-sync\//', $path))
32
+ {
33
+ try
34
+ {
35
+
36
+ if(!extension_loaded('pdo'))
37
+ {
38
+ throw new Exception('(PHP Data Objects) please refer to <a target="#blank" href="http://help.codisto.com/article/64-what-is-pdoexception-could-not-find-driver">Codisto help article</a>', 999);
39
+ }
40
+
41
+ if(!in_array("sqlite",PDO::getAvailableDrivers(), TRUE))
42
+ {
43
+ throw new PDOException('(sqlite PDO Driver) please refer to <a target="#blank" href="http://help.codisto.com/article/64-what-is-pdoexception-could-not-find-driver">Codisto help article</a>', 999);
44
+ }
45
+
46
+ //Can this request create a new merchant ?
47
+ $createMerchant = Mage::helper('codistosync')->createMerchantwithLock();
48
+
49
+ }
50
+
51
+ //Something else happened such as PDO related exception
52
+ catch(Exception $e)
53
+ {
54
+ //If competing requests are coming in as the extension is installed the lock above will be held ... don't report this back to Codisto .
55
+ if($e->getCode() != "HY000")
56
+ {
57
+ //Otherwise report other exception details to Codisto regarding register
58
+ Mage::helper('codistosync')->logExceptionCodisto($e, "https://ui.codisto.com/installed");
59
+ }
60
+ }
61
+
62
+ $reindexRequired = false;
63
+
64
+ if($createMerchant)
65
+ {
66
+ //If a merchant was succesfully created (a MerchantID was returned) then re-index.
67
+ $MerchantID = Mage::helper('codistosync')->registerMerchant($request);
68
+ $reindexRequired = $MerchantID;
69
+ }
70
+ }
71
+ }
72
+
73
+ if($reindexRequired)
74
+ {
75
+ Mage::helper('codistosync')->eBayReIndex();
76
+ }
app/code/community/Codisto/Sync/etc/adminhtml.xml ADDED
@@ -0,0 +1,110 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!--
3
+ /**
4
+ * Codisto eBay Sync Extension
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Open Software License (OSL 3.0)
9
+ * that is bundled with this package in the file LICENSE.txt.
10
+ * It is also available through the world-wide-web at this URL:
11
+ * http://opensource.org/licenses/osl-3.0.php
12
+ * If you did not receive a copy of the license and are unable to
13
+ * obtain it through the world-wide-web, please send an email
14
+ * to license@magentocommerce.com so you can be sent a copy immediately.
15
+ *
16
+ * @category Codisto
17
+ * @package Codisto_Sync
18
+ * @copyright Copyright (c) 2015 On Technology Pty. Ltd. (http://codisto.com)
19
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
20
+ */
21
+ -->
22
+
23
+ <config>
24
+ <menu>
25
+ <codisto translate="title">
26
+ <title>eBay | Codisto</title>
27
+ <sort_order>99</sort_order>
28
+ <children>
29
+ <listings translate="title">
30
+ <title>Manage Listings</title>
31
+ <sort_order>1</sort_order>
32
+ <action>adminhtml/codisto/index</action>
33
+ </listings>
34
+ <orders translate="title">
35
+ <title>Manage Orders</title>
36
+ <sort_order>2</sort_order>
37
+ <action>adminhtml/codisto/orders</action>
38
+ </orders>
39
+ <categories translate="title">
40
+ <title>Manage Categories</title>
41
+ <sort_order>3</sort_order>
42
+ <action>adminhtml/codisto/categories</action>
43
+ </categories>
44
+ <attributes translate="title">
45
+ <title>Manage Attributes</title>
46
+ <sort_order>4</sort_order>
47
+ <action>adminhtml/codisto/attributemapping</action>
48
+ </attributes>
49
+ <import translate="title">
50
+ <title>Import Listings</title>
51
+ <sort_order>5</sort_order>
52
+ <action>adminhtml/codisto/import</action>
53
+ </import>
54
+ <getstarted translate="title">
55
+ <title>Getting Started</title>
56
+ <sort_order>6</sort_order>
57
+ <action>adminhtml/codisto/intro</action>
58
+ </getstarted>
59
+ <settings translate="title">
60
+ <title>Settings</title>
61
+ <sort_order>7</sort_order>
62
+ <action>adminhtml/codisto/settings</action>
63
+ </settings>
64
+ </children>
65
+ </codisto>
66
+ </menu>
67
+
68
+ <acl>
69
+ <resources>
70
+ <admin>
71
+ <children>
72
+ <codisto translate="title">
73
+ <title>eBay | Codisto</title>
74
+ <sort_order>1</sort_order>
75
+ <children>
76
+ <listings>
77
+ <title>Manage Listings</title>
78
+ <sort_order>1</sort_order>
79
+ </listings>
80
+ <orders>
81
+ <title>Manage Orders</title>
82
+ <sort_order>2</sort_order>
83
+ </orders>
84
+ <categories>
85
+ <title>Manage Categories</title>
86
+ <sort_order>3</sort_order>
87
+ </categories>
88
+ <attributes>
89
+ <title>Manage Attributes</title>
90
+ <sort_order>4</sort_order>
91
+ </attributes>
92
+ <import>
93
+ <title>Import Listings</title>
94
+ <sort_order>5</sort_order>
95
+ </import>
96
+ <getstarted>
97
+ <title>Getting Started</title>
98
+ <sort_order>6</sort_order>
99
+ </getstarted>
100
+ <settings>
101
+ <title>Settings</title>
102
+ <sort_order>7</sort_order>
103
+ </settings>
104
+ </children>
105
+ </codisto>
106
+ </children>
107
+ </admin>
108
+ </resources>
109
+ </acl>
110
+ </config>
app/code/community/Codisto/Sync/etc/config.xml ADDED
@@ -0,0 +1,299 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!--
3
+ /**
4
+ * Codisto eBay Sync Extension
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Open Software License (OSL 3.0)
9
+ * that is bundled with this package in the file LICENSE.txt.
10
+ * It is also available through the world-wide-web at this URL:
11
+ * http://opensource.org/licenses/osl-3.0.php
12
+ * If you did not receive a copy of the license and are unable to
13
+ * obtain it through the world-wide-web, please send an email
14
+ * to license@magentocommerce.com so we can send you a copy immediately.
15
+ *
16
+ * @category Codisto
17
+ * @package Codisto_Sync
18
+ * @copyright Copyright (c) 2015 On Technology Pty. Ltd. (http://codisto.com/)
19
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
20
+ */
21
+ -->
22
+
23
+ <config>
24
+ <modules>
25
+ <Codisto_Sync>
26
+ <version>1.90.2</version>
27
+ <depends>
28
+ <Mage_Payment/>
29
+ </depends>
30
+ </Codisto_Sync>
31
+ </modules>
32
+
33
+ <frontend>
34
+ <routers>
35
+ <codisto-sync>
36
+ <use>standard</use>
37
+ <args>
38
+ <module>Codisto_Sync</module>
39
+ <frontName>codisto-sync</frontName>
40
+ </args>
41
+ </codisto-sync>
42
+ </routers>
43
+ </frontend>
44
+
45
+ <adminhtml>
46
+ <events>
47
+ <controller_action_layout_generate_blocks_after>
48
+ <observers>
49
+ <codisto>
50
+ <type>singleton</type>
51
+ <class>Codisto_Sync_Model_Observer</class>
52
+ <method>addScript</method>
53
+ </codisto>
54
+ </observers>
55
+ </controller_action_layout_generate_blocks_after>
56
+ </events>
57
+ </adminhtml>
58
+
59
+ <crontab>
60
+ <jobs>
61
+ <Codisto_Sync>
62
+ <schedule>
63
+ <cron_expr>*/10 * * * *</cron_expr>
64
+ </schedule>
65
+ <run>
66
+ <model>codistosync/observer::cronSync</model>
67
+ </run>
68
+ </Codisto_Sync>
69
+ </jobs>
70
+ </crontab>
71
+
72
+ <global>
73
+
74
+ <ignore_user_agents>
75
+ <codisto_connect>CodistoConnect/1.0</codisto_connect>
76
+ </ignore_user_agents>
77
+
78
+ <models>
79
+ <codistosync>
80
+ <class>Codisto_Sync_Model</class>
81
+ </codistosync>
82
+
83
+ <ebaypayment>
84
+ <class>Codisto_Sync_Ebaypayment_Model</class>
85
+ </ebaypayment>
86
+ </models>
87
+
88
+ <blocks>
89
+ <codisto><class>Codisto_Sync_Block</class></codisto>
90
+ </blocks>
91
+
92
+ <events>
93
+ <payment_info_block_prepare_specific_information>
94
+ <observers>
95
+ <codisto>
96
+ <type>singleton</type>
97
+ <class>Codisto_Sync_Model_Observer</class>
98
+ <method>paymentInfoBlockPrepareSpecificInformation</method>
99
+ </codisto>
100
+ </observers>
101
+ </payment_info_block_prepare_specific_information>
102
+
103
+ <catalogrule_after_apply>
104
+ <observers>
105
+ <codisto>
106
+ <type>singleton</type>
107
+ <class>Codisto_Sync_Model_Observer</class>
108
+ <method>catalogRuleAfterApply</method>
109
+ </codisto>
110
+ </observers>
111
+ </catalogrule_after_apply>
112
+
113
+ <sales_order_shipment_save_after>
114
+ <observers>
115
+ <codisto>
116
+ <type>singleton</type>
117
+ <class>Codisto_Sync_Model_Observer</class>
118
+ <method>salesOrderShipmentSaveAfter</method>
119
+ </codisto>
120
+ </observers>
121
+ </sales_order_shipment_save_after>
122
+ <sales_order_shipment_track_save_after>
123
+ <observers>
124
+ <codisto_shipping>
125
+ <type>singleton</type>
126
+ <class>Codisto_Sync_Model_Observer</class>
127
+ <method>salesOrderShipmentTrackSaveAfter</method>
128
+ </codisto_shipping>
129
+ </observers>
130
+ </sales_order_shipment_track_save_after>
131
+ <sales_order_invoice_save_commit_after>
132
+ <observers>
133
+ <codisto_save_invoice>
134
+ <class>Codisto_Sync_Model_Observer</class>
135
+ <method>salesOrderInvoiceSaveAfter</method>
136
+ </codisto_save_invoice>
137
+ </observers>
138
+ </sales_order_invoice_save_commit_after>
139
+
140
+ <checkout_submit_all_after>
141
+ <observers>
142
+ <codisto_stockmovements>
143
+ <class>Codisto_Sync_Model_Observer</class>
144
+ <method>checkoutAllSubmitAfter</method>
145
+ </codisto_stockmovements>
146
+ </observers>
147
+ </checkout_submit_all_after>
148
+ <catalog_product_import_finish_before>
149
+ <observers>
150
+ <codisto_stockmovements>
151
+ <class>Codisto_Sync_Model_Observer</class>
152
+ <method>catalogProductImportFinishBefore</method>
153
+ </codisto_stockmovements>
154
+ </observers>
155
+ </catalog_product_import_finish_before>
156
+
157
+ <tax_settings_change_after>
158
+ <observers>
159
+ <codisto_taxsync>
160
+ <type>singleton</type>
161
+ <class>Codisto_Sync_Model_Observer</class>
162
+ <method>taxSettingsChangeAfter</method>
163
+ </codisto_taxsync>
164
+ </observers>
165
+ </tax_settings_change_after>
166
+
167
+ <core_block_abstract_prepare_layout_after>
168
+ <observers>
169
+ <codisto_admin>
170
+ <type>singleton</type>
171
+ <class>Codisto_Sync_Model_Observer</class>
172
+ <method>addProductTab</method>
173
+ </codisto_admin>
174
+ </observers>
175
+ </core_block_abstract_prepare_layout_after>
176
+
177
+ <core_abstract_save_commit_after>
178
+ <observers>
179
+ <codisto_staticblocksync>
180
+ <type>singleton</type>
181
+ <class>Codisto_Sync_Model_Observer</class>
182
+ <method>cmsStaticBlockSaveAfter</method>
183
+ </codisto_staticblocksync>
184
+ </observers>
185
+ </core_abstract_save_commit_after>
186
+ </events>
187
+
188
+ <fieldsets>
189
+ <sales_convert_quote>
190
+ <codisto_orderid>
191
+ <to_order>*</to_order>
192
+ </codisto_orderid>
193
+ </sales_convert_quote>
194
+ <sales_convert_order>
195
+ <codisto_orderid>
196
+ <to_quote>*</to_quote>
197
+ </codisto_orderid>
198
+ </sales_convert_order>
199
+ </fieldsets>
200
+
201
+ <helpers>
202
+ <codistosync>
203
+ <class>Codisto_Sync_Helper</class>
204
+ </codistosync>
205
+ </helpers>
206
+
207
+ <resources>
208
+ <codisto_setup>
209
+ <setup>
210
+ <module>Codisto_Sync</module>
211
+ <class>Codisto_Sync_Model_Resource_Mysql4_Setup</class>
212
+ </setup>
213
+ <connection>
214
+ <use>core_setup</use>
215
+ </connection>
216
+ </codisto_setup>
217
+ <Codisto_Sync_write>
218
+ <connection>
219
+ <use>local_write</use>
220
+ </connection>
221
+ </Codisto_Sync_write>
222
+ <Codisto_Sync_read>
223
+ <connection>
224
+ <use>local_read</use>
225
+ </connection>
226
+ </Codisto_Sync_read>
227
+ </resources>
228
+
229
+ <index>
230
+ <indexer>
231
+ <codistoebayindex>
232
+ <model>codistosync/indexer_ebay</model>
233
+ </codistoebayindex>
234
+ </indexer>
235
+ </index>
236
+ </global>
237
+
238
+ <admin>
239
+ <routers>
240
+ <adminhtml>
241
+ <args>
242
+ <modules>
243
+ <Codisto_Sync after="Mage_Adminhtml">Codisto_Sync</Codisto_Sync>
244
+ </modules>
245
+ </args>
246
+ </adminhtml>
247
+ <codisto-sync>
248
+ <!-- does not leak admin url re: APPSEC-1034 -->
249
+ <!-- required to allow alternate admin base url to work -->
250
+ <use>admin</use>
251
+ <args>
252
+ <module>Codisto_Sync</module>
253
+ <frontName>codisto-sync</frontName>
254
+ </args>
255
+ </codisto-sync>
256
+ </routers>
257
+ </admin>
258
+
259
+ <default>
260
+ <web>
261
+ <routers>
262
+ <codisto-sync>
263
+ <area>admin</area>
264
+ <class>Codisto_Sync_Controller_Router</class>
265
+ </codisto-sync>
266
+ </routers>
267
+ </web>
268
+
269
+ <payment>
270
+ <ebay>
271
+ <active>1</active>
272
+ <model>ebaypayment/paymentmethod</model>
273
+ <order_status>pending</order_status>
274
+ <title>eBay Order</title>
275
+ <allowspecific>0</allowspecific>
276
+ <group>offline</group>
277
+ </ebay>
278
+
279
+ <!-- legacy payment code -->
280
+ <ebaypayment>
281
+ <active>1</active>
282
+ <model>ebaypayment/paymentmethod</model>
283
+ <order_status>pending</order_status>
284
+ <title>eBay Order</title>
285
+ <allowspecific>0</allowspecific>
286
+ <group>offline</group>
287
+ </ebaypayment>
288
+ </payment>
289
+ </default>
290
+
291
+ <phpunit>
292
+ <suite>
293
+ <modules>
294
+ <Codisto_Sync />
295
+ </modules>
296
+ </suite>
297
+ </phpunit>
298
+
299
+ </config>
app/code/community/Codisto/Sync/sql/codisto_setup/mysql4-install-1.90.2.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Codisto eBay Sync Extension
4
+ *
5
+ * NOTICE OF LICENSE
6
+ *
7
+ * This source file is subject to the Open Software License (OSL 3.0)
8
+ * that is bundled with this package in the file LICENSE.txt.
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ * If you did not receive a copy of the license and are unable to
12
+ * obtain it through the world-wide-web, please send an email
13
+ * to license@magentocommerce.com so we can send you a copy immediately.
14
+ *
15
+ * @category Codisto
16
+ * @package Codisto_Sync
17
+ * @copyright Copyright (c) 2014 On Technology Pty. Ltd. (http://codisto.com/)
18
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
19
+ */
20
+ $installer = $this;
21
+ $installer->startSetup();
22
+
23
+ $connection = $this->getConnection();
24
+
25
+ $tablename = $prefix = Mage::getConfig()->getTablePrefix() . 'sales_flat_order';
26
+
27
+ $connection->addColumn(
28
+ $tablename,
29
+ 'codisto_orderid',
30
+ 'varchar(10)'
31
+ );
32
+
33
+ $installer->endSetup();
app/design/ebay/README ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ Template Editing is described here:
2
+
3
+ http://help.codisto.com/article/21-editing-the-imagesmart-ebay-listing-template
4
+
5
+ Further template editing articles are located here:
6
+ http://help.codisto.com/category/11-category
7
+
8
+ To receive a copy of the default template files ensure that <MAGENTO_BASE_DIR>app/design/ebay folder is writable by the user context of the webserver/fpm pool.
9
+ The templates will appear the first time you refresh the full screen preview.
app/etc/modules/Codisto_Sync.xml ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <!--
3
+ /**
4
+ * Codisto eBay Sync Extension
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Open Software License (OSL 3.0)
9
+ * that is bundled with this package in the file LICENSE.txt.
10
+ * It is also available through the world-wide-web at this URL:
11
+ * http://opensource.org/licenses/osl-3.0.php
12
+ * If you did not receive a copy of the license and are unable to
13
+ * obtain it through the world-wide-web, please send an email
14
+ * to license@magentocommerce.com so you can be sent a copy immediately.
15
+ *
16
+ * @category Codisto
17
+ * @package Codisto_Sync
18
+ * @copyright Copyright (c) 2015 On Technology Pty. Ltd. (http://codisto.com)
19
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
20
+ */
21
+ -->
22
+
23
+ <config>
24
+ <modules>
25
+ <Codisto_Sync>
26
+ <active>true</active>
27
+ <codePool>community</codePool>
28
+ </Codisto_Sync>
29
+ </modules>
30
+ </config>
package.xml ADDED
@@ -0,0 +1,2 @@
 
 
1
+ <?xml version="1.0"?>
2
+ <package><name>codistoconnect</name><version>1.90.2</version><stability>stable</stability><license>OSL-3.0</license><channel>community</channel><extends></extends><summary>Fastest, Easiest eBay listing</summary><description>CodistoConnect enables you to list on eBay in the simplest way possible with maximum performance</description><notes></notes><authors><author><name>Codisto</name><user>Codisto</user><email>hello@codisto.com</email></author></authors><date>2016-06-08</date><time>16:45:39</time><compatible></compatible><dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies><contents><target name="mage"><dir name="app"><dir name="design"><dir name="ebay"><file name="README" hash="8a3f3351f68ccde9f161cdbe3960392f"/></dir></dir><dir name="code"><dir name="community"><dir name="Codisto"><dir name="Sync"><dir name="Helper"><file name="CmsContent.php" hash="f00b4523d681c60c660089d0de0f2e03"/><file name="Data.php" hash="331f0298b2c5701e2e7ef4d52b11c5e6"/><file name="Signal.php" hash="b624f962056ceffae9c3160ed3e5655e"/></dir><dir name="controllers"><file name="CodistoController.php" hash="4992c5f9d6d2f7422f409f0321b0e455"/><file name="IndexController.php" hash="4708270a1bd09e040cbd6bbaed8e5f88"/><file name="SyncController.php" hash="b06b9b8e7ed01effc9ba5d4ec0f8d0fc"/></dir><dir name="Controller"><file name="Router.php" hash="0ae958be465fbbe216afe18d4a715c5d"/></dir><dir name="Test"><file name="README" hash="8299e52f9198536ff5fd3fb42f4a29d8"/><dir name="Config"><file name="AdminHtml.php" hash="6ee6404e52ed6376ad41b7556f265c32"/><file name="Config.php" hash="2e9023fcbab484d03936394934f44f13"/><dir name="Config"><dir name="expectations"><file name="testCodistoCoreConfig.yaml" hash="4a4e07f62981139ff6eb8a63420cbf0d"/></dir></dir></dir><dir name="Controllers"><file name="CodistoController.php" hash="a2be4faeac73ff1847c0d7dc4fbdc0e0"/><file name="IndexController.php" hash="f7252fae8d2f7b67397ae56524db49d1"/><file name="SyncController.php" hash="33436e4935631488073765d723a82ff7"/></dir><dir name="Controller"><file name="Router.php" hash="8afc0dca269dd0977ff6b3ac6802d0ee"/></dir><dir name="Model"><file name="Paymentmethod.php" hash="862365909073ffbba057f6f152933826"/><file name="Sync.php" hash="10a38bbb62260208a8b1529e762b7b75"/></dir></dir><dir name="sql"><dir name="codisto_setup"><file name="mysql4-install-1.90.2.php" hash="6d07d4e22ae5d907df1f4389c3a829d4"/></dir></dir><dir name="data"><dir name="codisto_setup"><file name="data-install-1.90.2.php" hash="a42cf5f15b68ac92d4c207bed8472c7d"/></dir></dir><dir name="Block"><file name="PaymentInfo.php" hash="7aa15fed37766d20d9d5a7d707aff80d"/></dir><dir name="Ebaypayment"><dir name="Model"><file name="Paymentmethod.php" hash="480787461a5b952a739f20a752bffb5d"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="4ef592c4047f610b6943758fa4fd43a6"/><file name="config.xml" hash="6eec874745f235bda4e2d6cc46b07091"/></dir><dir name="Model"><file name="Observer.php" hash="f2e13dec1a56b7e124f631a0e529d042"/><file name="Sync.php" hash="6635eb1813d2e458396389069b349e54"/><dir name="Indexer"><file name="Ebay.php" hash="556b1aabc7c3202f31a2e6c250e7d590"/></dir><dir name="Resource"><dir name="Mysql4"><file name="Setup.php" hash="6a6664ea18d93bcdd0f45530caa56244"/></dir></dir></dir></dir></dir></dir></dir><dir name="etc"><dir name="modules"><file name="Codisto_Sync.xml" hash="a791bc2a9302d085eb29edf77421f525"/></dir></dir></dir></target></contents></package>