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#x2F;', $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#x2F;', $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#x2F;', $k))
64
+ {
65
+ $html .= '<tr><td>'.$this->escapeHtml(preg_replace('/_HTML#x2F;', '', $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