LinnLiveConnect - Version 1.1.56

Version Notes

improve compatibility with third party extensions

Download this release

Release Info

Developer Albert Andrejev
Extension LinnLiveConnect
Version 1.1.56
Comparing to
See all releases


Code changes from version 1.1.55 to 1.1.56

app/code/local/LinnSystems/LinnLiveConnect/Helper/Data.php CHANGED
@@ -36,6 +36,7 @@ class LinnSystems_LinnLiveConnect_Helper_Data extends Mage_Core_Helper_Abstract
36
 
37
 
38
  public function convertFiltersToArray($filters) {
 
39
  $arrayParams = array(
40
  'nin',
41
  'in',
@@ -69,6 +70,7 @@ class LinnSystems_LinnLiveConnect_Helper_Data extends Mage_Core_Helper_Abstract
69
  }
70
 
71
  protected function _log($message) {
 
72
  Mage::log(print_r($message, true), null, 'LinnLiveExt.log');
73
  }
74
 
@@ -320,12 +322,12 @@ class LinnSystems_LinnLiveConnect_Helper_Data extends Mage_Core_Helper_Abstract
320
 
321
  public function createProductData($productData){
322
 
323
- if (property_exists($productData, 'websites') === false) {
324
- $defaultStore = $this->getDefaultStore();
325
- if($defaultStore){
326
- $productData->websites = array($defaultStore->getWebsiteId());
327
- }
328
- }
329
 
330
  if (property_exists($productData, 'category_ids') === true) {
331
  $productData->category_ids = is_array($productData->category_ids) ? $productData->category_ids : array($productData->category_ids);
@@ -364,17 +366,17 @@ class LinnSystems_LinnLiveConnect_Helper_Data extends Mage_Core_Helper_Abstract
364
  $productData->categories = $productData->category_ids;
365
  }
366
 
367
- if (property_exists($productData, 'add_to_websites') && $productData->add_to_websites === true)
368
- {
369
- $currentWebsites = $_loadedProduct->getWebsiteIds();
370
- $websiteId = $this->getWebsiteId();
371
-
372
- if (in_array($websiteId, $currentWebsites) === false)
373
- {
374
- $currentWebsites[] = $websiteId;
375
- $productData->websites = $currentWebsites;
376
- }
377
- }
378
  }
379
 
380
  public function flushWsdlCache(){
36
 
37
 
38
  public function convertFiltersToArray($filters) {
39
+
40
  $arrayParams = array(
41
  'nin',
42
  'in',
70
  }
71
 
72
  protected function _log($message) {
73
+
74
  Mage::log(print_r($message, true), null, 'LinnLiveExt.log');
75
  }
76
 
322
 
323
  public function createProductData($productData){
324
 
325
+ //if (property_exists($productData, 'websites') === false) {
326
+ // $defaultStore = $this->getDefaultStore();
327
+ // if($defaultStore){
328
+ // $productData->websites = array($defaultStore->getWebsiteId());
329
+ // }
330
+ //}
331
 
332
  if (property_exists($productData, 'category_ids') === true) {
333
  $productData->category_ids = is_array($productData->category_ids) ? $productData->category_ids : array($productData->category_ids);
366
  $productData->categories = $productData->category_ids;
367
  }
368
 
369
+ //if (property_exists($productData, 'add_to_websites') && $productData->add_to_websites === true)
370
+ //{
371
+ // $currentWebsites = $_loadedProduct->getWebsiteIds();
372
+ // $websiteId = $this->getWebsiteId();
373
+
374
+ // if (in_array($websiteId, $currentWebsites) === false)
375
+ // {
376
+ // $currentWebsites[] = $websiteId;
377
+ // $productData->websites = $currentWebsites;
378
+ // }
379
+ //}
380
  }
381
 
382
  public function flushWsdlCache(){
app/code/local/LinnSystems/LinnLiveConnect/Helper/Factory.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class LinnSystems_LinnLiveConnect_Helper_Factory{
3
+
4
+ private function checkVersion($version) {
5
+ $version = intval($version);
6
+
7
+ if ($version == 0) {
8
+ throw new Mage_Api_Exception('version_not_specified');
9
+ }
10
+
11
+ if (Mage::helper('linnLiveConnect/settings') -> getShortVersion() < $version) {
12
+ throw new Mage_Api_Exception('wrong_version');
13
+ }
14
+ }
15
+
16
+ public function createWorker($version) {
17
+ $this->checkVersion($version);
18
+
19
+ if (Mage::GetEdition() == Mage::EDITION_COMMUNITY || Mage::GetEdition() == Mage::EDITION_ENTERPRISE) {
20
+ return Mage::getModel('linnLiveConnect/community');
21
+ }
22
+
23
+ throw new Mage_Api_Exception('unsupported_edition');
24
+ }
25
+ }
26
+
27
+ ?>
app/code/local/LinnSystems/LinnLiveConnect/Model/Api/V2.php CHANGED
@@ -1,1209 +1,131 @@
1
  <?php
2
 
3
- //move to models or replace using config if need
4
- class Mage_Catalog_Model_Product_Api_V2_LL extends Mage_Catalog_Model_Product_Api_V2 {
5
-
6
- public function create($type, $set, $sku, $productData, $store = NULL) {
7
- $tries = 0;
8
- $maxtries = 3;
9
-
10
-
11
- for ($tries = 0; $tries < $maxtries; $tries++) {
12
- try {
13
- return parent::create($type, $set, $sku, $productData, $store);
14
- } catch (Exception $e) {
15
- if ($e -> getMessage() == 'SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction') {
16
- sleep(1);
17
- } else {
18
- throw $e;
19
- }
20
- }
21
- }
22
- }
23
-
24
- public function update($productId, $productData, $store = null, $identifierType = null) {
25
- $tries = 0;
26
- $maxtries = 3;
27
-
28
- for ($tries = 0; $tries < $maxtries; $tries++) {
29
- try {
30
- return parent::update($productId, $productData, $store, $identifierType);
31
- } catch (Exception $e) {
32
- if ($e -> getMessage() == 'SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction') {
33
- sleep(1);
34
- } else {
35
- throw $e;
36
- }
37
- }
38
- }
39
- }
40
-
41
- }
42
-
43
  class LinnSystems_LinnLiveConnect_Model_Api_V2 {
 
 
 
 
 
44
 
45
  public function checkProducts($version, $data) {
46
 
47
- $worker = Factory::createWorker($version);
48
  return $worker -> checkProducts($data);
49
  }
50
 
51
  public function createSimpleProducts($version, $data) {
52
- $worker = Factory::createWorker($version);
53
  return $worker -> createSimpleProducts($data);
54
  }
55
 
56
  public function createConfigurableProducts($version, $data) {
57
 
58
- $worker = Factory::createWorker($version);
59
  return $worker -> createConfigurableProducts($data);
60
  }
61
 
62
  public function createRelatedProducts($version, $data) {
63
 
64
- $worker = Factory::createWorker($version);
65
  return $worker -> createRelatedProducts($data);
66
  }
67
 
68
  public function createProductImages($version, $data) {
69
 
70
- $worker = Factory::createWorker($version);
71
  return $worker -> createProductImages($data);
72
  }
73
 
74
  public function updateSimpleProducts($version, $data) {
75
 
76
- $worker = Factory::createWorker($version);
77
  return $worker -> updateSimpleProducts($data);
78
  }
79
 
80
  public function updateConfigurableProducts($version, $data) {
81
 
82
- $worker = Factory::createWorker($version);
83
  return $worker -> updateConfigurableProducts($data);
84
  }
85
 
86
  public function updateProductImages($version, $data) {
87
 
88
- $worker = Factory::createWorker($version);
89
  return $worker -> updateProductImages($data);
90
  }
91
 
92
  public function updatePriceBulk($version, $data, $store = null, $identifierType = 'id') {
93
 
94
- $worker = Factory::createWorker($version);
95
  return $worker -> updateProductPrices($data, $store, $identifierType);
96
  }
97
 
98
  public function deleteProducts($version, $data) {
99
 
100
- $worker = Factory::createWorker($version);
101
  return $worker -> deleteProducts($data);
102
  }
103
 
104
  public function deleteRelatedProducts($version, $data) {
105
 
106
- $worker = Factory::createWorker($version);
107
  return $worker -> deleteRelatedProducts($data);
108
  }
109
 
110
  public function deleteProductImages($version, $data) {
111
 
112
- $worker = Factory::createWorker($version);
113
  return $worker -> deleteProductImages($data);
114
  }
115
 
116
  public function getProductStoreURL($version, $productId, $store = null, $identifierType = 'id') {
117
 
118
- $worker = Factory::createWorker($version);
119
  return $worker -> getProductStoreURL($productId, $store, $identifierType);
120
  }
121
 
122
  public function getStoreCode($version, $store = null) {
123
 
124
- $worker = Factory::createWorker($version);
125
  return $worker -> getStoreCode($store);
126
  }
127
 
128
  public function getGeneralInfo($version) {
129
 
130
- $worker = Factory::createWorker($version);
131
  return $worker -> getGeneralInfo();
132
  }
133
 
134
  //todo: rename
135
  public function productList($version, $page, $perPage, $filters = null, $store = null) {
136
 
137
- $worker = Factory::createWorker($version);
138
  return $worker -> getProductList($page, $perPage, $filters, $store);
139
  }
140
 
141
  //todo: rename
142
  public function productAttributeOptions($version, $setId) {
143
 
144
- $worker = Factory::createWorker($version);
145
  return $worker -> getProductAttributeOptions($setId);
146
  }
147
 
148
  public function storesList($version) {
149
 
150
- $worker = Factory::createWorker($version);
151
  return $worker -> storesList();
152
  }
153
 
154
  public function disableIndexing($version) {
155
- $worker = Factory::createWorker($version);
156
  return $worker -> disableIndexing();
157
  }
158
 
159
  public function restoreIndexingById($version, $data) {
160
- $worker = Factory::createWorker($version);
161
  return $worker -> restoreIndexingById($data);
162
  }
163
 
164
  }
165
 
166
- class Factory {
167
-
168
- private static function _checkVersion($version) {
169
- $version = intval($version);
170
-
171
- if ($version == 0) {
172
- throw new Mage_Api_Exception('version_not_specified');
173
- }
174
-
175
- if (Mage::helper('linnLiveConnect/settings') -> getShortVersion() < $version) {
176
- throw new Mage_Api_Exception('wrong_version');
177
- }
178
- }
179
-
180
- public static function createWorker($version) {
181
- self::_checkVersion($version);
182
-
183
- if (Mage::GetEdition() == Mage::EDITION_COMMUNITY || Mage::GetEdition() == Mage::EDITION_ENTERPRISE) {
184
- return new LinnLiveCommunity();
185
- }
186
-
187
- throw new Mage_Api_Exception('unsupported_edition');
188
- }
189
-
190
- }
191
-
192
- class LinnLiveMain extends Mage_Core_Model_Abstract {
193
-
194
- protected $_ignoredAttributes = array('created_at', 'updated_at', 'category_ids', 'required_options', 'old_id', 'url_key', 'url_path', 'has_options', 'image_label', 'small_image_label', 'thumbnail_label', 'image', 'small_image', 'thumbnail', 'options_container', 'entity_id', 'entity_type_id', 'attribute_set_id', 'type_id', 'sku', 'name', 'status', 'stock_item', 'description', );
195
-
196
- protected $_permittedAttributes = array('select', 'multiselect', 'text', 'textarea', 'date', 'price');
197
-
198
- protected function _prepareConfigurableData($productsSet, $attributesSet, $isUpdate) {
199
- $helper = Mage::helper('linnLiveConnect');
200
-
201
- $assignedProductsArray = $helper -> objectToArray($this -> _createProductsData($productsSet));
202
-
203
- $_newAttributeOptions = $this -> _newConfigurableOptions($assignedProductsArray);
204
- if (count($_newAttributeOptions) > 0) {
205
- $this -> _checkAssignedProductsOptions($helper -> createOptions($_newAttributeOptions), $assignedProductsArray);
206
- }
207
-
208
- if (!is_array($attributesSet)) {
209
- $attributesSet = array($attributesSet);
210
- }
211
-
212
- $attributesSetArray = $this -> _prepareAttributesData($helper -> objectToArray($attributesSet), $assignedProductsArray);
213
-
214
- foreach ($attributesSetArray as $key => $value) {
215
- $attributesSetArray[$key]["id"] = NULL;
216
- $attributesSetArray[$key]["position"] = NULL;
217
- $attributesSetArray[$key]["store_label"] = isset($value['frontend_label']) ? $value['frontend_label'] : NULL;
218
- //$attributesSetArray[$key]["use_default"] = 0;
219
-
220
- if ($isUpdate == false) {
221
- //check if attribute exists and available
222
- $checkAttribute = Mage::getModel('catalog/resource_eav_attribute') -> loadByCode('catalog_product', $attributesSetArray[$key]["attribute_code"]);
223
-
224
- if (!$checkAttribute -> getId() || !$this -> _isConfigurable($checkAttribute)) {
225
- throw new Mage_Api_Exception('invalid_variation_attribute', 'Invalid attribute [' . $checkAttribute['attribute_code'] . '] provided to Magento extension for creating Variation / Product with options. Check attributes/variations in LinnLive Magento configurator if they do exist/match the ones on the back-end.');
226
- }
227
- }
228
-
229
- }
230
- return array($assignedProductsArray, $attributesSetArray);
231
- }
232
-
233
- protected function _isConfigurable($attribute) {
234
- $isConfigurable = 0;
235
-
236
- if (isset($attribute['is_global']) && $attribute['is_global']) {
237
- $attribute['scope'] = 'global';
238
- }
239
-
240
- if (($attribute['scope'] == 'global') && ($attribute['is_configurable'])) {
241
- if (is_array($attribute['apply_to']) && sizeof($attribute['apply_to'])) {
242
- if (in_array('simple', $attribute['apply_to'])) {
243
- $isConfigurable = 1;
244
- }
245
- } elseif (is_string($attribute['apply_to']) && strlen($attribute['apply_to'])) {
246
- if (strpos($attribute['apply_to'], 'simple') !== false) {
247
- $isConfigurable = 1;
248
- }
249
- } else {
250
- $isConfigurable = 1;
251
- }
252
- }
253
- return $isConfigurable;
254
- }
255
-
256
- protected function _checkAssignedProductsOptions($availableOptions, &$assignedProductsArray) {
257
- foreach ($assignedProductsArray as $id => $productOptions) {
258
- foreach ($productOptions as $index => $option) {
259
- if (isset($availableOptions[$option['attribute_id']][strtolower($option['label'])])) {
260
- $assignedProductsArray[$id][$index]['value_index'] = $availableOptions[$option['attribute_id']][strtolower($option['label'])];
261
- }
262
- }
263
- }
264
- }
265
-
266
- protected function _newConfigurableOptions($assignedProductsArray) {
267
- $_attributesOptions = array();
268
- foreach ($assignedProductsArray as $id => $productOptions) {
269
- foreach ($productOptions as $option) {
270
- if (isset($option['value_index']) && $option['value_index'] == '-1') {
271
- if (isset($_attributesOptions[$option['attribute_id']])) {
272
- $_attributesOptions[$option['attribute_id']][] = $option['label'];
273
- } else {
274
- $_attributesOptions[$option['attribute_id']] = array($option['label']);
275
- }
276
- }
277
- }
278
- }
279
- return $_attributesOptions;
280
- }
281
-
282
- protected function _containsOption($attributeOption, $option) {
283
- foreach ($attributeOption as $inArrayOption)
284
- if ($inArrayOption['value_index'] == $option['value_index'])
285
- return true;
286
-
287
- return false;
288
- }
289
-
290
- protected function _prepareAttributesData($attributesSetArray, $assignedProductsArray) {
291
-
292
- $_attributesOptions = array();
293
- foreach ($assignedProductsArray as $id => $productOptions) {
294
- foreach ($productOptions as $option) {
295
- if (isset($_attributesOptions[$option['attribute_id']]) && !$this -> _containsOption($_attributesOptions[$option['attribute_id']], $option)) {
296
- $_attributesOptions[$option['attribute_id']][] = $option;
297
- } else if (!isset($_attributesOptions[$option['attribute_id']])) {
298
- $_attributesOptions[$option['attribute_id']] = array();
299
- $_attributesOptions[$option['attribute_id']][] = $option;
300
- }
301
- }
302
- }
303
-
304
- foreach ($attributesSetArray as $key => $attribute) {
305
- if (isset($_attributesOptions[$attribute['attribute_id']])) {
306
- $attributesSetArray[$key]['values'] = $_attributesOptions[$attribute['attribute_id']];
307
- }
308
- }
309
-
310
- return $attributesSetArray;
311
- }
312
-
313
- protected function _updateConfigurable($store, $productId, $assignedProducts, $assignedAttributes, $identifierType, $isUpdate = false, $reindex = true) {
314
- $magentoVer = $this -> _getCurrentVersion();
315
- if ($magentoVer == 162) {
316
- $store = Mage::app() -> getStore($store) -> getId();
317
- } else {
318
- $store = NULL;
319
- }
320
-
321
- $product = Mage::helper('catalog/product') -> getProduct($productId, $store, $identifierType);
322
-
323
- $product -> setConfigurableProductsData($assignedProducts);
324
-
325
- if ($isUpdate == false) {
326
- $product -> setConfigurableAttributesData($assignedAttributes);
327
- $product -> setCanSaveConfigurableAttributes(true);
328
- }
329
-
330
- try {
331
- $result = $product -> save();
332
- } catch (Exception $e) {
333
- throw new Mage_Api_Exception('configurable_creating_error', $e -> getMessage());
334
- }
335
-
336
- return $result;
337
- }
338
-
339
- protected function _createProductsData($productData) {
340
- $assignedProductsData = array();
341
-
342
- if (is_array($productData)) {
343
- foreach ($productData as $product) {
344
- $assignedProductsData[$product -> product_id] = array();
345
- if (is_array($product -> values)) {
346
- foreach ($product->values as $productValue) {
347
- $assignedProductsData[$product -> product_id][] = $productValue;
348
- }
349
- }
350
- }
351
- }
352
-
353
- return $assignedProductsData;
354
- }
355
-
356
- protected function _getCurrentVersion() {
357
- $verInfo = Mage::getVersionInfo();
358
-
359
- return intval($verInfo['major'] . $verInfo['minor'] . $verInfo['revision']);
360
- }
361
-
362
- protected function _removeIgnoredAttributes($attributesList) {
363
- $_preparedAttributes = array();
364
- if (is_array($attributesList) && count($attributesList) > 0) {
365
- foreach ($attributesList as $key => $value) {
366
- if (!in_array($key, $this -> _ignoredAttributes) && !is_array($value))
367
- $_preparedAttributes[] = array('key' => $key, 'value' => $value);
368
- }
369
- }
370
-
371
- return $_preparedAttributes;
372
- }
373
-
374
- protected function _productAttributeInfo($attribute_id, $attributeAPI) {
375
- $model = Mage::getResourceModel('catalog/eav_attribute') -> setEntityTypeId(Mage::getModel('eav/entity') -> setType('catalog_product') -> getTypeId());
376
-
377
- $model -> load($attribute_id);
378
-
379
- if (!$model -> getId()) {
380
- throw new Mage_Api_Exception('attribute_not_exists');
381
- }
382
-
383
- if ($model -> isScopeGlobal()) {
384
- $scope = 'global';
385
- } elseif ($model -> isScopeWebsite()) {
386
- $scope = 'website';
387
- } else {
388
- $scope = 'store';
389
- }
390
-
391
- $result = array('attribute_id' => $model -> getId(), 'attribute_code' => $model -> getAttributeCode(), 'frontend_input' => $model -> getFrontendInput(), 'default_value' => $model -> getDefaultValue(), 'is_unique' => $model -> getIsUnique(), 'is_required' => $model -> getIsRequired(), 'apply_to' => $model -> getApplyTo(), 'is_configurable' => $model -> getIsConfigurable(), 'is_searchable' => $model -> getIsSearchable(), 'is_visible_in_advanced_search' => $model -> getIsVisibleInAdvancedSearch(), 'is_comparable' => $model -> getIsComparable(), 'is_used_for_promo_rules' => $model -> getIsUsedForPromoRules(), 'is_visible_on_front' => $model -> getIsVisibleOnFront(), 'used_in_product_listing' => $model -> getUsedInProductListing(), 'scope' => $scope, );
392
-
393
- // set options
394
- $options = $attributeAPI -> options($model -> getId());
395
- // remove empty first element
396
- if ($model -> getFrontendInput() != 'boolean') {
397
- array_shift($options);
398
- }
399
-
400
- if (count($options) > 0) {
401
- $result['options'] = $options;
402
- }
403
-
404
- return $result;
405
- }
406
-
407
- protected function _log($message) {
408
- Mage::log(print_r($message, true), null, 'LinnLiveExt.log');
409
- }
410
-
411
- /********************************Indexer block***********************************************/
412
- /*****************************************************************************************/
413
- /*****************************************************************************************/
414
- public function disableIndexing() {
415
- $states = array();
416
- $blocked = array('cataloginventory_stock', 'catalog_product_flat', 'catalog_category_flat', 'catalogsearch_fulltext');
417
-
418
- $processes = Mage::getSingleton('index/indexer') -> getProcessesCollection();
419
- foreach ($processes as $process) {
420
-
421
- $code = $process -> getIndexerCode();
422
-
423
- if (in_array($code, $blocked) || $process -> getId() > 9) {
424
- continue;
425
- }
426
-
427
- $states[] = array('key' => $code, 'value' => $process -> getMode());
428
-
429
- $process -> setMode(Mage_Index_Model_Process::MODE_MANUAL) -> save();
430
- }
431
- return $states;
432
- }
433
-
434
- public function restoreIndexingById($data) {
435
-
436
- foreach ($data as $key => $value) {
437
-
438
- $process = Mage::getModel('index/indexer') -> getProcessByCode($key);
439
- if ($process && $process -> getIndexerCode()) {
440
-
441
- $value = $value == Mage_Index_Model_Process::MODE_MANUAL ? Mage_Index_Model_Process::MODE_MANUAL : Mage_Index_Model_Process::MODE_REAL_TIME;
442
-
443
- if ($process -> getMode() != $value) {
444
- $process -> setMode($value) -> save();
445
- }
446
-
447
- if ($process -> getStatus() == Mage_Index_Model_Process::STATUS_REQUIRE_REINDEX) {
448
- $process -> reindexEverything();
449
- }
450
- }
451
- }
452
- }
453
-
454
- protected function reindexProducts() {
455
- $processes = Mage::getSingleton('index/indexer') -> getProcessesCollection();
456
- foreach ($processes as $process) {
457
- if ($process -> getStatus() == Mage_Index_Model_Process::STATUS_REQUIRE_REINDEX) {
458
- $process -> reindexEverything();
459
- }
460
- }
461
- }
462
-
463
- protected function lockIndexer() {
464
- Mage::setIsDeveloperMode(true);
465
- //Mage::getSingleton('index/indexer') -> getProcessesCollection() -> walk('lockAndBlock');
466
- }
467
-
468
- protected function unlockIndexer() {
469
- //Mage::getSingleton('index/indexer') -> getProcessesCollection() -> walk('unlock');
470
- Mage::setIsDeveloperMode(false);
471
- }
472
-
473
- protected function cleanCache() {
474
- Mage::app() -> getCacheInstance() -> flush();
475
- Mage::app() -> cleanCache();
476
- }
477
-
478
- protected function disableAllIndexing() {
479
- $processes = Mage::getSingleton('index/indexer') -> getProcessesCollection();
480
- $processes -> walk('setMode', array(Mage_Index_Model_Process::MODE_MANUAL));
481
- $processes -> walk('save');
482
- }
483
-
484
- protected function enableAllIndexing() {
485
- $processes = Mage::getSingleton('index/indexer') -> getProcessesCollection();
486
- //$processes -> walk('reindexAll');
487
- $processes -> walk('setMode', array(Mage_Index_Model_Process::MODE_REAL_TIME));
488
- $processes -> walk('save');
489
- }
490
-
491
- }
492
-
493
- class LinnLiveCommunity extends LinnLiveMain {
494
-
495
- //obsolete
496
- public function storesList() {
497
- return ($this -> _getCurrentVersion() >= 160);
498
- }
499
-
500
- /**
501
- * Get products
502
- * Implementation of catalogProductList because of bug in associativeArray.
503
- * Extended to filter by category id too.
504
- *
505
- * Use 'entity_id' for product_id,
506
- * 'type_id' instead of product type.
507
- * @return array | mixed
508
- */
509
- public function getProductList($page, $perPage, $filters = null, $store = null) {
510
- $helper = Mage::helper('linnLiveConnect');
511
-
512
- //get store
513
- try {
514
- $storeId = Mage::app() -> getStore($helper -> currentStoreCode($store)) -> getId();
515
- } catch (Mage_Core_Model_Store_Exception $e) {
516
- throw new Mage_Api_Exception('store_not_exists', null);
517
- }
518
-
519
- //prepare and convert filters to array
520
- $preparedFilters = $helper -> convertFiltersToArray($filters);
521
- if (empty($preparedFilters)) {
522
- throw new Mage_Api_Exception('filters_invalid', null);
523
- }
524
-
525
- //load collection
526
- $collection = Mage::getModel('catalog/product') -> getCollection() -> addStoreFilter($storeId);
527
-
528
- //filter collection by category if exists
529
- if (isset($preparedFilters['category']) && is_string($preparedFilters['category'])) {
530
- $_category = Mage::getModel('catalog/category') -> load(intval($preparedFilters['category']));
531
-
532
- if ($_category -> getId()) {
533
- $collection = $collection -> addCategoryFilter($_category);
534
- }
535
-
536
- unset($preparedFilters['category']);
537
- }
538
-
539
- //add prepared filters to collection
540
- try {
541
- foreach ($preparedFilters as $field => $data) {
542
- if (is_array($data)) {
543
- foreach ($data as $key => $value) {
544
- $collection -> addFieldToFilter($field, array($key => $value));
545
- }
546
- } else {
547
- $collection -> addFieldToFilter($field, $data);
548
- }
549
- }
550
- } catch (Mage_Core_Exception $e) {
551
- throw new Mage_Api_Exception('filters_invalid', $e -> getMessage());
552
- }
553
-
554
- if ($page == 1) {
555
- //TODO: limit page size
556
- $count = $collection -> count();
557
- } else {
558
- $count = 0;
559
- $collection -> setPageSize($perPage) -> setCurPage($page);
560
- }
561
-
562
- $result = array('count' => $count, 'products' => array());
563
-
564
- $_assignedIds = array();
565
- $_fetchedIds = array();
566
-
567
- $i = 0;
568
- foreach ($collection as $_product) {
569
-
570
- if ($i >= ($perPage * $page))
571
- break;
572
- //TODO remove
573
- $_loadedProduct = Mage::helper('catalog/product') -> getProduct($_product -> getId(), $storeId, 'id');
574
-
575
- $_allAttributes = $_loadedProduct -> getData();
576
-
577
- $_description = isset($_allAttributes['description']) ? $_allAttributes['description'] : '';
578
-
579
- $_productImages = $helper -> productImages($_allAttributes);
580
- $_productAttributes = $this -> _removeIgnoredAttributes($_allAttributes);
581
-
582
- $_fetchedIds[] = $_loadedProduct -> getId();
583
-
584
- $result['products'][$i] = array('product_id' => $_loadedProduct -> getId(), 'sku' => $_loadedProduct -> getSku(), 'name' => $_loadedProduct -> GetName(), 'set' => $_loadedProduct -> getAttributeSetId(), 'type' => $_loadedProduct -> getTypeId(), 'price' => $_loadedProduct -> getPrice(), 'status' => $_loadedProduct -> getStatus(), 'description' => $_description, 'category_ids' => $_loadedProduct -> getCategoryIds(), 'website_ids' => $_loadedProduct -> getWebsiteIds(), 'assigned_ids' => array(), 'conf_attrib_ids' => array(), 'images' => $_productImages, 'attributes' => $_productAttributes, );
585
-
586
- if ($_loadedProduct -> getTypeId() == "configurable") {
587
- $_typeInstance = $_loadedProduct -> getTypeInstance();
588
- $result['products'][$i]['assigned_ids'] = $_typeInstance -> getUsedProductIds();
589
- foreach ($_typeInstance->getConfigurableAttributes() as $attribute) {
590
- $_prices = array();
591
- foreach ($attribute->getPrices() as $price) {
592
- $_prices[] = array('value_index' => $price['value_index'], 'is_fixed' => !$price['is_percent'], 'price_diff' => $price['pricing_value'], 'label' => $price['label'], );
593
- }
594
-
595
- $result['products'][$i]['conf_attrib_ids'][] = array('code' => $attribute -> getProductAttribute() -> getAttributeCode(), 'prices' => $_prices);
596
- }
597
- $_assignedIds = array_merge($_assignedIds, $result['products'][$i]['assigned_ids']);
598
- }
599
-
600
- $i++;
601
- }
602
-
603
- $_absentIds = array_diff($_assignedIds, $_fetchedIds);
604
-
605
- if (count($_absentIds) > 0) {
606
- $collection = Mage::getModel('catalog/product') -> getCollection() -> addIdFilter($_absentIds);
607
-
608
- foreach ($collection as $_product) {
609
- $_loadedProduct = Mage::helper('catalog/product') -> getProduct($_product -> getId(), $storeId, 'id');
610
-
611
- $_allAttributes = $_product -> getData();
612
-
613
- $_description = isset($_allAttributes['description']) ? $_allAttributes['description'] : '';
614
-
615
- $_productImages = $helper -> productImages($_allAttributes);
616
- $_productAttributes = $this -> _removeIgnoredAttributes($_allAttributes);
617
-
618
- $result['products'][] = array('product_id' => $_loadedProduct -> getId(), 'sku' => $_loadedProduct -> getSku(), 'name' => $_loadedProduct -> GetName(), 'set' => $_loadedProduct -> getAttributeSetId(), 'type' => $_loadedProduct -> getTypeId(), 'price' => $_loadedProduct -> getPrice(), 'status' => $_loadedProduct -> getStatus(), 'description' => $_description, 'category_ids' => $_loadedProduct -> getCategoryIds(), 'website_ids' => $_loadedProduct -> getWebsiteIds(), 'assigned_ids' => array(), 'conf_attrib_ids' => array(), 'images' => $_productImages, 'attributes' => $this -> _removeIgnoredAttributes($_loadedProduct -> getData()), );
619
- }
620
- }
621
-
622
- return $result;
623
- }
624
-
625
- /**
626
- * Get attribute set attrobites
627
- *
628
- * @return array | mixed
629
- */
630
- public function getProductAttributeOptions($setId) {
631
-
632
- $result = array();
633
-
634
- $setId = intval($setId);
635
- if ($setId <= 0) {
636
- return $result;
637
- }
638
-
639
- $attributeAPI = Mage::getModel('catalog/product_attribute_api');
640
-
641
- $items = $attributeAPI -> items($setId);
642
-
643
- $attributes = Mage::getModel('catalog/product') -> getResource() -> loadAllAttributes();
644
-
645
- foreach ($items as $item) {
646
- if (!isset($item['attribute_id']) || empty($item['attribute_id']))
647
- continue;
648
- $attributeId = intval($item['attribute_id']);
649
- if ($attributeId <= 0)
650
- continue;
651
-
652
- $additionInfo = $this -> _productAttributeInfo($attributeId, $attributeAPI);
653
-
654
- if (in_array($additionInfo['frontend_input'], $this -> _permittedAttributes) && !in_array($additionInfo['attribute_code'], $this -> _ignoredAttributes)) {
655
-
656
- $attribute = array('attribute_id' => $additionInfo['attribute_id'], 'code' => $additionInfo['attribute_code'], 'type' => $additionInfo['frontend_input'], 'required' => $additionInfo['is_required'], 'scope' => $additionInfo['scope'], 'can_config' => 0);
657
-
658
- if (($additionInfo['frontend_input'] == 'select') || ($additionInfo['frontend_input'] == 'multiselect')) {
659
- if (isset($additionInfo['options'])) {
660
-
661
- if (sizeof($additionInfo['options']) && is_array($additionInfo['options'][0]['value'])) {
662
- continue;
663
- //ignore attributes with multidimensional options
664
- }
665
- $attribute['attribute_options'] = $additionInfo['options'];
666
- }
667
-
668
- $attribute['can_config'] = $this -> _isConfigurable($additionInfo);
669
- }
670
-
671
- $result[] = $attribute;
672
- }
673
- }
674
-
675
- return $result;
676
- }
677
-
678
- /**
679
- * Get general information about magento installation
680
- *
681
- * @return array | mixed
682
- */
683
- public function getGeneralInfo() {
684
- $config = Mage::getStoreConfig("api/config");
685
- $verInfo = Mage::getVersionInfo();
686
-
687
- $result = array('llc_ver' => Mage::helper('linnLiveConnect/settings') -> getVersion(), 'magento_ver' => trim("{$verInfo['major']}.{$verInfo['minor']}.{$verInfo['revision']}" . ($verInfo['patch'] != '' ? ".{$verInfo['patch']}" : "") . "-{$verInfo['stability']}{$verInfo['number']}", '.-'), 'php_ver' => phpversion(), 'api_config' => $config, 'compilation_enabled' => (bool)(defined('COMPILER_INCLUDE_PATH')), 'max_upload_size' => min((int)ini_get("upload_max_filesize"), (int)ini_get("post_max_size"), (int)ini_get("memory_limit")));
688
-
689
- return $result;
690
- }
691
-
692
- /**
693
- * Get store code
694
- *
695
- * @return string
696
- */
697
- public function getStoreCode($store = null) {
698
- $helper = Mage::helper('linnLiveConnect');
699
- return $helper -> currentStoreCode($store);
700
- }
701
-
702
- /**
703
- * Get product url
704
- *
705
- * @return string
706
- */
707
- public function getProductStoreURL($productId, $store = null, $identifierType = 'id') {
708
-
709
- $storeId = $this -> getStoreCode($store);
710
-
711
- $_loadedProduct = Mage::helper('catalog/product') -> getProduct($productId, $storeId, $identifierType);
712
-
713
- if (!$_loadedProduct -> getId()) {
714
- throw new Mage_Api_Exception('product_not_exists', null);
715
- }
716
-
717
- return $_loadedProduct -> getProductUrl();
718
- }
719
-
720
- /********************************Single block***********************************************/
721
- /*****************************************************************************************/
722
- /*****************************************************************************************/
723
- /**
724
- * Check if product exists
725
- *
726
- * @return boolean
727
- */
728
- protected function checkProduct($sku, $store = null, $identifierType = 'id') {
729
- $product = Mage::helper('catalog/product') -> getProduct($sku, $store, $identifierType);
730
- return ($product && $product -> getId());
731
- }
732
-
733
- /**
734
- * Create simple product
735
- *
736
- * @return int
737
- */
738
- public function createSimpleProduct($type, $set, $sku, $productData, $store = null, $allowToUseInventoryProduct = true) {
739
- $helper = Mage::helper('linnLiveConnect');
740
-
741
- if($allowToUseInventoryProduct){
742
- $product = $helper -> getProductBySku($sku);
743
- if ($product) {
744
- return $product -> getId();
745
- }
746
- }
747
-
748
- $store = $helper -> currentStoreCode($store);
749
-
750
- $productData = $helper -> createProductData($productData);
751
-
752
- $productData = $helper -> updateProperties($productData);
753
-
754
- $productData = $helper -> fixAttributes($productData);
755
-
756
- $productAPI = new Mage_Catalog_Model_Product_Api_V2_LL();
757
-
758
- return $productAPI -> create($type, $set, $sku, $productData, $store);
759
- }
760
-
761
- /**
762
- * Create configurable product
763
- *
764
- * @return int
765
- */
766
- public function createConfigurableProduct($set, $sku, $reindex, $productData, $productsSet, $attributesSet, $store = null) {
767
-
768
- if (!$set || !$sku) {
769
- throw new Mage_Api_Exception('data_invalid');
770
- }
771
-
772
- $helper = Mage::helper('linnLiveConnect');
773
-
774
- $helper -> updateConfigurableQuantity($productData);
775
-
776
- $productData = $helper -> createProductData($productData);
777
-
778
- $productData = $helper -> fixAttributes($productData);
779
-
780
- $store = $helper -> currentStoreCode($store);
781
-
782
- //merge into 1?
783
- $productAPI = new Mage_Catalog_Model_Product_Api_V2_LL();
784
- $productId = $productAPI -> create('configurable', $set, $sku, $productData, $store);
785
-
786
- list($assignedProductsArray, $attributesSetArray) = $this -> _prepareConfigurableData($productsSet, $attributesSet, false);
787
- $this -> _updateConfigurable($store, $productId, $assignedProductsArray, $attributesSetArray, 'id', false, $reindex);
788
-
789
- return $productId;
790
- }
791
-
792
- /**
793
- * Create product image
794
- *
795
- * @return string
796
- */
797
- protected function createProductImage($productId, $data, $store = null, $identifierType = 'id') {
798
-
799
- return Mage::getModel('catalog/product_attribute_media_api') -> create($productId, Mage::helper('linnLiveConnect') -> objectToArray($data), $store, $identifierType);
800
- }
801
-
802
- /**
803
- * Create product link association
804
- *
805
- * @return boolean
806
- */
807
- protected function createRelatedProduct($type, $productId, $linkedProductId, $identifierType = 'id') {
808
-
809
- return Mage::getModel('catalog/product_link_api') -> assign($type, $productId, $linkedProductId, null, $identifierType);
810
- }
811
-
812
- /**
813
- * Update simple product
814
- *
815
- * @return boolean
816
- */
817
- public function updateSimpleProduct($productId, $productData, $store = null, $identifierType = 'id') {
818
-
819
- $helper = Mage::helper('linnLiveConnect');
820
- $store = $helper -> currentStoreCode($store);
821
-
822
- $helper -> updateProductData($productId, $productData, $store, $identifierType);
823
-
824
- $productData = $helper -> updateProperties($productData);
825
-
826
- $productData = $helper -> fixAttributes($productData);
827
-
828
- $productAPI = new Mage_Catalog_Model_Product_Api_V2();
829
-
830
- return $productAPI -> update($productId, $productData, $store, $identifierType);
831
- }
832
-
833
- /**
834
- * Update configurable product
835
- *
836
- * @return boolean
837
- */
838
- public function updateConfigurableProduct($productId, $reindex, $productData, $productsSet, $attributesSet, $store = null, $identifierType = 'id') {
839
-
840
- $helper = Mage::helper('linnLiveConnect');
841
-
842
- $helper -> updateConfigurableQuantity($productData);
843
-
844
- $productData = $helper -> fixAttributes($productData);
845
-
846
- $store = $helper -> currentStoreCode($store);
847
-
848
- $helper -> updateProductData($productId, $productData, $store, $identifierType);
849
-
850
- $productAPI = new Mage_Catalog_Model_Product_Api_V2();
851
-
852
- $productAPI -> update($productId, $productData, $store, $identifierType);
853
-
854
- list($assignedProductsArray, $attributesSetArray) = $this -> _prepareConfigurableData($productsSet, $attributesSet, true);
855
-
856
- return $this -> _updateConfigurable($store, $productId, $assignedProductsArray, $attributesSetArray, $identifierType, true, $reindex);
857
- }
858
-
859
- /**
860
- * Update product image
861
- *
862
- * @return boolean
863
- */
864
- protected function updateProductImage($productId, $file, $data, $store = null, $identifierType = 'id') {
865
-
866
- return Mage::getModel('catalog/product_attribute_media_api') -> update($productId, $file, Mage::helper('linnLiveConnect') -> objectToArray($data), $store, $identifierType);
867
- }
868
-
869
- /**
870
- * Update product price
871
- *
872
- * @return boolean
873
- */
874
- protected function updateProductPrice($productId, $price, $store = null, $identifierType = 'id') {
875
-
876
- $product = Mage::helper('catalog/product') -> getProduct($productId, $store, $identifierType);
877
-
878
- if ($product && $product -> getId()) {
879
- if ($product -> getPrice() != $price) {
880
- $product -> setPrice($price);
881
- $product -> save();
882
- }
883
- return true;
884
- }
885
- return false;
886
- }
887
-
888
- /**
889
- * Delete product
890
- *
891
- * @return boolean
892
- */
893
- protected function deleteProduct($productId, $store = null, $identifierType = 'id') {
894
- $product = Mage::helper('catalog/product') -> getProduct($productId, $store, $identifierType);
895
- if ($product && $product -> getId()) {
896
- return $product -> delete();
897
- }
898
- return false;
899
- }
900
-
901
- /**
902
- * Delete product image
903
- *
904
- * @return boolean
905
- */
906
- protected function deleteProductImage($productId, $file, $identifierType = 'id') {
907
-
908
- return Mage::getModel('catalog/product_attribute_media_api') -> remove($productId, $file, $identifierType);
909
- }
910
-
911
- /**
912
- * Remove product link association
913
- *
914
- * @return boolean
915
- */
916
- protected function deleteRelatedProduct($type, $productId, $linkedProductId, $identifierType = 'id') {
917
-
918
- return Mage::getModel('catalog/product_link_api') -> remove($type, $productId, $linkedProductId, $identifierType);
919
- }
920
-
921
- /********************************Bulk block***********************************************/
922
- /*****************************************************************************************/
923
- /*****************************************************************************************/
924
- /**
925
- * Bulk check products by sku/productId
926
- */
927
- public function checkProducts($data) {
928
-
929
- $response = array();
930
-
931
- for ($i = 0; $i < sizeof($data); $i++) {
932
- $entity = $data[$i];
933
- $product = Mage::helper('catalog/product') -> getProduct();
934
- $response[] = array('sku' => $entity -> sku, 'success' => $this -> checkProduct($entity -> sku, $entity -> store, $entity -> identifierType));
935
- }
936
-
937
- return $response;
938
-
939
- }
940
-
941
- /**
942
- * Bulk create simple products
943
- */
944
- public function createSimpleProducts($data) {
945
- $this -> lockIndexer();
946
-
947
- $response = array();
948
-
949
- for ($i = 0; $i < sizeof($data); $i++) {
950
- $entity = $data[$i];
951
- try {
952
- $productId = $this -> createSimpleProduct('simple', $entity -> set, $entity -> sku, $entity -> productData, $entity -> store, false);
953
- $response[] = array('sku' => $entity -> sku, 'productId' => $productId, 'isError' => ($productId < 1));
954
- } catch (Exception $e) {
955
- $response[] = array('sku' => $entity -> sku, 'productId' => 0, 'isError' => true, 'error' => $e -> getMessage());
956
- }
957
- }
958
-
959
- $this -> unlockIndexer();
960
-
961
- return $response;
962
- }
963
-
964
- /**
965
- * Bulk create configurable products
966
- */
967
- public function createConfigurableProducts($data) {
968
-
969
- $this -> lockIndexer();
970
-
971
- $response = array();
972
-
973
- for ($i = 0; $i < sizeof($data); $i++) {
974
- $entity = $data[$i];
975
- try {
976
- $productId = $this -> createConfigurableProduct($entity -> set, $entity -> sku, false, $entity -> productData, $entity -> productsSet, $entity -> attributesSet, $entity -> store);
977
- $response[] = array('sku' => $entity -> sku, 'productId' => $productId, 'isError' => ($productId < 1));
978
-
979
- } catch (Exception $e) {
980
- $response[] = array('sku' => $entity -> sku, 'productId' => 0, 'isError' => true, 'error' => $e -> getMessage());
981
- }
982
- }
983
-
984
- $this -> unlockIndexer();
985
-
986
- return $response;
987
- }
988
-
989
- /**
990
- * Bulk create related products
991
- */
992
- public function createRelatedProducts($data) {
993
-
994
- $this -> lockIndexer();
995
-
996
- $response = array();
997
-
998
- for ($i = 0; $i < sizeof($data); $i++) {
999
- $entity = $data[$i];
1000
- try {
1001
- $result = $this -> createRelatedProduct($entity -> type, $entity -> productId, $entity -> linkedProductId, null, $entity -> identifierType);
1002
- $response[] = array('relatedId' => $entity -> relatedId, 'productId' => $entity -> productId, 'isError' => !$result);
1003
- } catch (Exception $e) {
1004
- $response[] = array('relatedId' => $entity -> relatedId, 'productId' => $entity -> productId, 'isError' => true, 'error' => $e -> getMessage());
1005
- }
1006
- }
1007
-
1008
- $this -> unlockIndexer();
1009
-
1010
- return $response;
1011
- }
1012
-
1013
- /**
1014
- * Bulk create product images
1015
- */
1016
- public function createProductImages($data) {
1017
-
1018
- $this -> lockIndexer();
1019
-
1020
- $response = array();
1021
-
1022
- for ($i = 0; $i < sizeof($data); $i++) {
1023
- $entity = $data[$i];
1024
- try {
1025
- $result = $this -> createProductImage($entity -> productId, $entity -> data, $entity -> store, $entity -> identifierType);
1026
- $response[] = array('imageId' => $entity -> imageId, 'productId' => $entity -> productId, 'isError' => empty($result), 'file' => $result);
1027
- } catch (Exception $e) {
1028
- $response[] = array('imageId' => $entity -> imageId, 'productId' => $entity -> productId, 'isError' => true, 'error' => $e -> getMessage());
1029
- }
1030
- }
1031
-
1032
- $this -> unlockIndexer();
1033
-
1034
- return $response;
1035
- }
1036
-
1037
- /**
1038
- * Bulk update product images
1039
- */
1040
- public function updateProductImages($data) {
1041
-
1042
- $this -> lockIndexer();
1043
-
1044
- $response = array();
1045
-
1046
- for ($i = 0; $i < sizeof($data); $i++) {
1047
- $entity = $data[$i];
1048
- try {
1049
- $result = $this -> updateProductImage($entity -> productId, $entity -> file, $entity -> data, $entity -> store, $entity -> identifierType);
1050
- $response[] = array('imageId' => $entity -> imageId, 'productId' => $entity -> productId, 'isError' => !$result);
1051
- } catch (Exception $e) {
1052
- $response[] = array('imageId' => $entity -> imageId, 'productId' => $entity -> productId, 'isError' => true, 'error' => $e -> getMessage());
1053
- }
1054
- }
1055
-
1056
- $this -> unlockIndexer();
1057
-
1058
- return $response;
1059
- }
1060
-
1061
- /**
1062
- * Bulk price update, TODO: success change to isError
1063
- */
1064
- public function updateProductPrices($data, $store, $identifierType = 'id') {
1065
-
1066
- $this -> lockIndexer();
1067
-
1068
- $response = array();
1069
-
1070
- for ($i = 0; $i < sizeof($data); $i++) {
1071
- $entity = $data[$i];
1072
- try {
1073
- $result = $this -> updateProductPrice($entity -> sku, $entity -> price, $store, $identifierType);
1074
- $response[] = array('sku' => $entity -> sku, 'success' => $result);
1075
- } catch (Exception $e) {
1076
- $response[] = array('sku' => $entity -> sku, 'success' => false);
1077
- }
1078
- }
1079
-
1080
- $this -> unlockIndexer();
1081
-
1082
- return $response;
1083
- }
1084
-
1085
- /**
1086
- * Bulk update simple products
1087
- */
1088
- public function updateSimpleProducts($data) {
1089
-
1090
- $this -> lockIndexer();
1091
-
1092
- $response = array();
1093
-
1094
- for ($i = 0; $i < sizeof($data); $i++) {
1095
- $entity = $data[$i];
1096
- try {
1097
- $result = $this -> updateSimpleProduct($entity -> productId, $entity -> productData, $entity -> store, $entity -> identifierType);
1098
- $response[] = array('sku' => $entity -> sku, 'productId' => $entity -> productId, 'isError' => !$result);
1099
- } catch (Exception $e) {
1100
- $response[] = array('sku' => $entity -> sku, 'productId' => $entity -> productId, 'isError' => true, 'error' => $e -> getMessage());
1101
- }
1102
- }
1103
-
1104
- $this -> unlockIndexer();
1105
-
1106
- return $response;
1107
- }
1108
-
1109
- /**
1110
- * Bulk update configurable products
1111
- */
1112
- public function updateConfigurableProducts($data) {
1113
-
1114
- $this -> lockIndexer();
1115
-
1116
- $response = array();
1117
-
1118
- for ($i = 0; $i < sizeof($data); $i++) {
1119
- $entity = $data[$i];
1120
-
1121
- try {
1122
- $result = $this -> updateConfigurableProduct($entity -> productId, false, $entity -> productData, $entity -> productsSet, $entity -> attributesSet, $entity -> store, $entity -> identifierType);
1123
- $response[] = array('sku' => $entity -> sku, 'productId' => $entity -> productId, 'isError' => !$result);
1124
- } catch (Exception $e) {
1125
- $response[] = array('sku' => $entity -> sku, 'productId' => $entity -> productId, 'isError' => true, 'error' => $e -> getMessage());
1126
- }
1127
- }
1128
-
1129
- $this -> unlockIndexer();
1130
-
1131
- return $response;
1132
- }
1133
-
1134
- /**
1135
- * Bulk delete products
1136
- */
1137
- public function deleteProducts($data) {
1138
-
1139
- $this -> lockIndexer();
1140
-
1141
- $response = array();
1142
-
1143
- for ($i = 0; $i < sizeof($data); $i++) {
1144
- $entity = $data[$i];
1145
- try {
1146
- $result = $this -> deleteProduct($entity -> productId, $entity -> store, $entity -> identifierType);
1147
-
1148
- $response[] = array('sku' => $entity -> sku, 'productId' => $entity -> productId, 'isError' => !$result);
1149
-
1150
- } catch (Exception $e) {
1151
- $response[] = array('sku' => $entity -> sku, 'productId' => $entity -> productId, 'isError' => true, 'error' => $e -> getMessage());
1152
- }
1153
- }
1154
-
1155
- $this -> unlockIndexer();
1156
-
1157
- return $response;
1158
- }
1159
-
1160
- /**
1161
- * Bulk delete related products
1162
- */
1163
- public function deleteRelatedProducts($data) {
1164
-
1165
- $this -> lockIndexer();
1166
-
1167
- $response = array();
1168
-
1169
- for ($i = 0; $i < sizeof($data); $i++) {
1170
- $entity = $data[$i];
1171
- try {
1172
- $result = $this -> deleteRelatedProduct($entity -> type, $entity -> productId, $entity -> linkedProductId, $entity -> identifierType);
1173
- $response[] = array('relatedId' => $entity -> relatedId, 'productId' => $entity -> productId, 'isError' => !$result);
1174
- } catch (Exception $e) {
1175
- $response[] = array('relatedId' => $entity -> relatedId, 'productId' => $entity -> productId, 'isError' => true, 'error' => $e -> getMessage());
1176
- }
1177
- }
1178
-
1179
- $this -> unlockIndexer();
1180
-
1181
- return $response;
1182
- }
1183
-
1184
- /**
1185
- * Bulk delete product images
1186
- */
1187
- public function deleteProductImages($data) {
1188
-
1189
- $this -> lockIndexer();
1190
-
1191
- $response = array();
1192
-
1193
- for ($i = 0; $i < sizeof($data); $i++) {
1194
- $entity = $data[$i];
1195
- try {
1196
- $result = $this -> deleteProductImage($entity -> productId, $entity -> file, $entity -> identifierType);
1197
- $response[] = array('imageId' => $entity -> imageId, 'productId' => $entity -> productId, 'isError' => !$result);
1198
- } catch (Exception $e) {
1199
- $response[] = array('imageId' => $entity -> imageId, 'productId' => $entity -> productId, 'isError' => true, 'error' => $e -> getMessage());
1200
- }
1201
- }
1202
-
1203
- $this -> unlockIndexer();
1204
-
1205
- return $response;
1206
- }
1207
-
1208
- }
1209
  ?>
1
  <?php
2
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
3
  class LinnSystems_LinnLiveConnect_Model_Api_V2 {
4
+ protected $factory = null;
5
+
6
+ public function __construct(){
7
+ $this->factory = Mage::helper('linnLiveConnect/factory');
8
+ }
9
 
10
  public function checkProducts($version, $data) {
11
 
12
+ $worker = $this->factory->createWorker($version);
13
  return $worker -> checkProducts($data);
14
  }
15
 
16
  public function createSimpleProducts($version, $data) {
17
+ $worker = $this->factory->createWorker($version);
18
  return $worker -> createSimpleProducts($data);
19
  }
20
 
21
  public function createConfigurableProducts($version, $data) {
22
 
23
+ $worker = $this->factory->createWorker($version);
24
  return $worker -> createConfigurableProducts($data);
25
  }
26
 
27
  public function createRelatedProducts($version, $data) {
28
 
29
+ $worker = $this->factory->createWorker($version);
30
  return $worker -> createRelatedProducts($data);
31
  }
32
 
33
  public function createProductImages($version, $data) {
34
 
35
+ $worker = $this->factory->createWorker($version);
36
  return $worker -> createProductImages($data);
37
  }
38
 
39
  public function updateSimpleProducts($version, $data) {
40
 
41
+ $worker = $this->factory->createWorker($version);
42
  return $worker -> updateSimpleProducts($data);
43
  }
44
 
45
  public function updateConfigurableProducts($version, $data) {
46
 
47
+ $worker = $this->factory->createWorker($version);
48
  return $worker -> updateConfigurableProducts($data);
49
  }
50
 
51
  public function updateProductImages($version, $data) {
52
 
53
+ $worker = $this->factory->createWorker($version);
54
  return $worker -> updateProductImages($data);
55
  }
56
 
57
  public function updatePriceBulk($version, $data, $store = null, $identifierType = 'id') {
58
 
59
+ $worker = $this->factory->createWorker($version);
60
  return $worker -> updateProductPrices($data, $store, $identifierType);
61
  }
62
 
63
  public function deleteProducts($version, $data) {
64
 
65
+ $worker = $this->factory->createWorker($version);
66
  return $worker -> deleteProducts($data);
67
  }
68
 
69
  public function deleteRelatedProducts($version, $data) {
70
 
71
+ $worker = $this->factory->createWorker($version);
72
  return $worker -> deleteRelatedProducts($data);
73
  }
74
 
75
  public function deleteProductImages($version, $data) {
76
 
77
+ $worker = $this->factory->createWorker($version);
78
  return $worker -> deleteProductImages($data);
79
  }
80
 
81
  public function getProductStoreURL($version, $productId, $store = null, $identifierType = 'id') {
82
 
83
+ $worker = $this->factory->createWorker($version);
84
  return $worker -> getProductStoreURL($productId, $store, $identifierType);
85
  }
86
 
87
  public function getStoreCode($version, $store = null) {
88
 
89
+ $worker = $this->factory->createWorker($version);
90
  return $worker -> getStoreCode($store);
91
  }
92
 
93
  public function getGeneralInfo($version) {
94
 
95
+ $worker = $this->factory->createWorker($version);
96
  return $worker -> getGeneralInfo();
97
  }
98
 
99
  //todo: rename
100
  public function productList($version, $page, $perPage, $filters = null, $store = null) {
101
 
102
+ $worker = $this->factory->createWorker($version);
103
  return $worker -> getProductList($page, $perPage, $filters, $store);
104
  }
105
 
106
  //todo: rename
107
  public function productAttributeOptions($version, $setId) {
108
 
109
+ $worker = $this->factory->createWorker($version);
110
  return $worker -> getProductAttributeOptions($setId);
111
  }
112
 
113
  public function storesList($version) {
114
 
115
+ $worker = $this->factory->createWorker($version);
116
  return $worker -> storesList();
117
  }
118
 
119
  public function disableIndexing($version) {
120
+ $worker = $this->factory->createWorker($version);
121
  return $worker -> disableIndexing();
122
  }
123
 
124
  public function restoreIndexingById($version, $data) {
125
+ $worker = $this->factory->createWorker($version);
126
  return $worker -> restoreIndexingById($data);
127
  }
128
 
129
  }
130
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
131
  ?>
app/code/local/LinnSystems/LinnLiveConnect/Model/Category/Api.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Magento
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
+ * DISCLAIMER
17
+ *
18
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
19
+ * versions in the future. If you wish to customize Magento for your
20
+ * needs please refer to http://www.magentocommerce.com for more information.
21
+ *
22
+ * @category Mage
23
+ * @package Mage_Catalog
24
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
25
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
26
+ */
27
+
28
+ /**
29
+ * Catalog category api
30
+ *
31
+ * @category Mage
32
+ * @package Mage_Catalog
33
+ * @author Magento Core Team <core@magentocommerce.com>
34
+ */
35
+ class LinnSystems_LinnLiveConnect_Model_Category_Api extends Mage_Catalog_Model_Category_Api {
36
+ }
37
+
38
+ // Class Mage_Catalog_Model_Category_Api End
app/code/local/LinnSystems/LinnLiveConnect/Model/Community.php ADDED
@@ -0,0 +1,735 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class LinnSystems_LinnLiveConnect_Model_Community extends LinnSystems_LinnLiveConnect_Model_Main {
3
+
4
+ //obsolete
5
+ public function storesList() {
6
+ return ($this -> _getCurrentVersion() >= 160);
7
+ }
8
+
9
+ /**
10
+ * Get products
11
+ * Implementation of catalogProductList because of bug in associativeArray.
12
+ * Extended to filter by category id too.
13
+ *
14
+ * Use 'entity_id' for product_id,
15
+ * 'type_id' instead of product type.
16
+ * @return array | mixed
17
+ */
18
+ public function getProductList($page, $perPage, $filters = null, $store = null) {
19
+ $helper = Mage::helper('linnLiveConnect');
20
+
21
+ //get store
22
+ try {
23
+ $storeId = Mage::app() -> getStore($helper -> currentStoreCode($store)) -> getId();
24
+ } catch (Mage_Core_Model_Store_Exception $e) {
25
+ throw new Mage_Api_Exception('store_not_exists', null);
26
+ }
27
+
28
+ //prepare and convert filters to array
29
+ $preparedFilters = $helper -> convertFiltersToArray($filters);
30
+ if (empty($preparedFilters)) {
31
+ throw new Mage_Api_Exception('filters_invalid', null);
32
+ }
33
+
34
+ //load collection
35
+ $collection = Mage::getModel('catalog/product') -> getCollection() -> addStoreFilter($storeId);
36
+
37
+ //filter collection by category if exists
38
+ if (isset($preparedFilters['category']) && is_string($preparedFilters['category'])) {
39
+ $_category = Mage::getModel('catalog/category') -> load(intval($preparedFilters['category']));
40
+
41
+ if ($_category -> getId()) {
42
+ $collection = $collection -> addCategoryFilter($_category);
43
+ }
44
+
45
+ unset($preparedFilters['category']);
46
+ }
47
+
48
+ //add prepared filters to collection
49
+ try {
50
+ foreach ($preparedFilters as $field => $data) {
51
+ if (is_array($data)) {
52
+ foreach ($data as $key => $value) {
53
+ $collection -> addFieldToFilter($field, array($key => $value));
54
+ }
55
+ } else {
56
+ $collection -> addFieldToFilter($field, $data);
57
+ }
58
+ }
59
+ } catch (Mage_Core_Exception $e) {
60
+ throw new Mage_Api_Exception('filters_invalid', $e -> getMessage());
61
+ }
62
+
63
+ if ($page == 1) {
64
+ //TODO: limit page size
65
+ $count = $collection -> count();
66
+ } else {
67
+ $count = 0;
68
+ $collection -> setPageSize($perPage) -> setCurPage($page);
69
+ }
70
+
71
+ $result = array('count' => $count, 'products' => array());
72
+
73
+ $_assignedIds = array();
74
+ $_fetchedIds = array();
75
+
76
+ $i = 0;
77
+ foreach ($collection as $_product) {
78
+
79
+ if ($i >= ($perPage * $page))
80
+ break;
81
+ //TODO remove
82
+ $_loadedProduct = Mage::helper('catalog/product') -> getProduct($_product -> getId(), $storeId, 'id');
83
+
84
+ $_allAttributes = $_loadedProduct -> getData();
85
+
86
+ $_description = isset($_allAttributes['description']) ? $_allAttributes['description'] : '';
87
+
88
+ $_productImages = $helper -> productImages($_allAttributes);
89
+ $_productAttributes = $this -> _removeIgnoredAttributes($_allAttributes);
90
+
91
+ $_fetchedIds[] = $_loadedProduct -> getId();
92
+
93
+ $result['products'][$i] = array('product_id' => $_loadedProduct -> getId(), 'sku' => $_loadedProduct -> getSku(), 'name' => $_loadedProduct -> GetName(), 'set' => $_loadedProduct -> getAttributeSetId(), 'type' => $_loadedProduct -> getTypeId(), 'price' => $_loadedProduct -> getPrice(), 'status' => $_loadedProduct -> getStatus(), 'description' => $_description, 'category_ids' => $_loadedProduct -> getCategoryIds(), 'website_ids' => $_loadedProduct -> getWebsiteIds(), 'assigned_ids' => array(), 'conf_attrib_ids' => array(), 'images' => $_productImages, 'attributes' => $_productAttributes, );
94
+
95
+ if ($_loadedProduct -> getTypeId() == "configurable") {
96
+ $_typeInstance = $_loadedProduct -> getTypeInstance();
97
+ $result['products'][$i]['assigned_ids'] = $_typeInstance -> getUsedProductIds();
98
+ foreach ($_typeInstance->getConfigurableAttributes() as $attribute) {
99
+ $_prices = array();
100
+ foreach ($attribute->getPrices() as $price) {
101
+ $_prices[] = array('value_index' => $price['value_index'], 'is_fixed' => !$price['is_percent'], 'price_diff' => $price['pricing_value'], 'label' => $price['label'], );
102
+ }
103
+
104
+ $result['products'][$i]['conf_attrib_ids'][] = array('code' => $attribute -> getProductAttribute() -> getAttributeCode(), 'prices' => $_prices);
105
+ }
106
+ $_assignedIds = array_merge($_assignedIds, $result['products'][$i]['assigned_ids']);
107
+ }
108
+
109
+ $i++;
110
+ }
111
+
112
+ $_absentIds = array_diff($_assignedIds, $_fetchedIds);
113
+
114
+ if (count($_absentIds) > 0) {
115
+ $collection = Mage::getModel('catalog/product') -> getCollection() -> addIdFilter($_absentIds);
116
+
117
+ foreach ($collection as $_product) {
118
+ $_loadedProduct = Mage::helper('catalog/product') -> getProduct($_product -> getId(), $storeId, 'id');
119
+
120
+ $_allAttributes = $_product -> getData();
121
+
122
+ $_description = isset($_allAttributes['description']) ? $_allAttributes['description'] : '';
123
+
124
+ $_productImages = $helper -> productImages($_allAttributes);
125
+ $_productAttributes = $this -> _removeIgnoredAttributes($_allAttributes);
126
+
127
+ $result['products'][] = array('product_id' => $_loadedProduct -> getId(), 'sku' => $_loadedProduct -> getSku(), 'name' => $_loadedProduct -> GetName(), 'set' => $_loadedProduct -> getAttributeSetId(), 'type' => $_loadedProduct -> getTypeId(), 'price' => $_loadedProduct -> getPrice(), 'status' => $_loadedProduct -> getStatus(), 'description' => $_description, 'category_ids' => $_loadedProduct -> getCategoryIds(), 'website_ids' => $_loadedProduct -> getWebsiteIds(), 'assigned_ids' => array(), 'conf_attrib_ids' => array(), 'images' => $_productImages, 'attributes' => $this -> _removeIgnoredAttributes($_loadedProduct -> getData()), );
128
+ }
129
+ }
130
+
131
+ return $result;
132
+ }
133
+
134
+ /**
135
+ * Get attribute set attrobites
136
+ *
137
+ * @return array | mixed
138
+ */
139
+ public function getProductAttributeOptions($setId) {
140
+
141
+ $result = array();
142
+
143
+ $setId = intval($setId);
144
+ if ($setId <= 0) {
145
+ return $result;
146
+ }
147
+
148
+ $attributeAPI = Mage::getModel('catalog/product_attribute_api');
149
+
150
+ $items = $attributeAPI -> items($setId);
151
+
152
+ $attributes = Mage::getModel('catalog/product') -> getResource() -> loadAllAttributes();
153
+
154
+ foreach ($items as $item) {
155
+ if (!isset($item['attribute_id']) || empty($item['attribute_id'])){
156
+ continue;
157
+ }
158
+
159
+ $attributeId = intval($item['attribute_id']);
160
+ if ($attributeId <= 0){
161
+ continue;
162
+ }
163
+
164
+ $additionInfo = $this -> _productAttributeInfo($attributeId, $attributeAPI);
165
+
166
+ if (in_array($additionInfo['frontend_input'], $this -> _permittedAttributes) && !in_array($additionInfo['attribute_code'], $this -> _ignoredAttributes)) {
167
+
168
+ $attribute = array('attribute_id' => $additionInfo['attribute_id'], 'code' => $additionInfo['attribute_code'], 'type' => $additionInfo['frontend_input'], 'required' => $additionInfo['is_required'], 'scope' => $additionInfo['scope'], 'can_config' => 0);
169
+
170
+ if (($additionInfo['frontend_input'] == 'select') || ($additionInfo['frontend_input'] == 'multiselect')) {
171
+ if (isset($additionInfo['options'])) {
172
+
173
+ if (sizeof($additionInfo['options']) && is_array($additionInfo['options'][0]['value'])) {
174
+ continue;
175
+ //ignore attributes with multidimensional options
176
+ }
177
+ $attribute['attribute_options'] = $additionInfo['options'];
178
+ }
179
+
180
+ $attribute['can_config'] = $this -> _isConfigurable($additionInfo);
181
+ }
182
+
183
+ $result[] = $attribute;
184
+ }
185
+ }
186
+
187
+ return $result;
188
+ }
189
+
190
+ /**
191
+ * Get general information about magento installation
192
+ *
193
+ * @return array | mixed
194
+ */
195
+ public function getGeneralInfo() {
196
+ $config = Mage::getStoreConfig("api/config");
197
+ $verInfo = Mage::getVersionInfo();
198
+
199
+ $result = array(
200
+ 'llc_ver' => Mage::helper('linnLiveConnect/settings') -> getVersion(),
201
+ 'magento_ver' => trim("{$verInfo['major']}.{$verInfo['minor']}.{$verInfo['revision']}" . ($verInfo['patch'] != '' ? ".{$verInfo['patch']}" : "") . "-{$verInfo['stability']}{$verInfo['number']}", '.-'),
202
+ 'php_ver' => phpversion(),
203
+ 'api_config' => $config,
204
+ 'compilation_enabled' => (bool)(defined('COMPILER_INCLUDE_PATH')),
205
+ 'max_upload_size' => min((int)ini_get("upload_max_filesize"), (int)ini_get("post_max_size"), (int)ini_get("memory_limit")),
206
+ 'store'=>Mage::helper('linnLiveConnect') -> currentStoreCode($store),
207
+ 'extension_version'=>Mage::helper('linnLiveConnect/settings') -> getVersion(),
208
+ 'max_execution_time'=>ini_get("max_execution_time")
209
+ );
210
+
211
+ return $result;
212
+ }
213
+
214
+ /**
215
+ * Get store code
216
+ *
217
+ * @return string
218
+ */
219
+ public function getStoreCode($store = null) {
220
+ $helper = Mage::helper('linnLiveConnect');
221
+ return $helper -> currentStoreCode($store);
222
+ }
223
+
224
+ /**
225
+ * Get product url
226
+ *
227
+ * @return string
228
+ */
229
+ public function getProductStoreURL($productId, $store = null, $identifierType = 'id') {
230
+
231
+ $storeId = $this -> getStoreCode($store);
232
+
233
+ $_loadedProduct = Mage::helper('catalog/product') -> getProduct($productId, $storeId, $identifierType);
234
+
235
+ if (!$_loadedProduct -> getId()) {
236
+ throw new Mage_Api_Exception('product_not_exists', null);
237
+ }
238
+
239
+ return $_loadedProduct -> getProductUrl();
240
+ }
241
+
242
+ /********************************Single block***********************************************/
243
+ /*****************************************************************************************/
244
+ /*****************************************************************************************/
245
+ /**
246
+ * Check if product exists
247
+ *
248
+ * @return boolean
249
+ */
250
+ protected function checkProduct($sku, $store = null, $identifierType = 'id') {
251
+ $product = Mage::helper('catalog/product') -> getProduct($sku, $store, $identifierType);
252
+ return ($product && $product -> getId());
253
+ }
254
+
255
+ /**
256
+ * Create simple product
257
+ *
258
+ * @return int
259
+ */
260
+ public function createSimpleProduct($type, $set, $sku, $productData, $store = null, $allowToUseInventoryProduct = true) {
261
+ $helper = Mage::helper('linnLiveConnect');
262
+
263
+ if($allowToUseInventoryProduct){
264
+ $product = $helper -> getProductBySku($sku);
265
+ if ($product) {
266
+ return $product -> getId();
267
+ }
268
+ }
269
+
270
+ $store = $helper -> currentStoreCode($store);
271
+
272
+ $productData = $helper -> createProductData($productData);
273
+
274
+ $productData = $helper -> updateProperties($productData);
275
+
276
+ $productData = $helper -> fixAttributes($productData);
277
+
278
+ $productAPI = Mage::getModel('catalog/product_api_v2');
279
+
280
+ return $productAPI -> create($type, $set, $sku, $productData, $store);
281
+ }
282
+
283
+ /**
284
+ * Create configurable product
285
+ *
286
+ * @return int
287
+ */
288
+ public function createConfigurableProduct($set, $sku, $reindex, $productData, $productsSet, $attributesSet, $store = null) {
289
+
290
+ if (!$set || !$sku) {
291
+ throw new Mage_Api_Exception('data_invalid');
292
+ }
293
+
294
+ $helper = Mage::helper('linnLiveConnect');
295
+
296
+ $helper -> updateConfigurableQuantity($productData);
297
+
298
+ $productData = $helper -> createProductData($productData);
299
+
300
+ $productData = $helper -> fixAttributes($productData);
301
+
302
+ $store = $helper -> currentStoreCode($store);
303
+
304
+ //merge into 1?
305
+ $productAPI = Mage::getModel('catalog/product_api_v2');
306
+ $productId = $productAPI -> create('configurable', $set, $sku, $productData, $store);
307
+
308
+ list($assignedProductsArray, $attributesSetArray) = $this -> _prepareConfigurableData($productsSet, $attributesSet, false);
309
+ $this -> _updateConfigurable($store, $productId, $assignedProductsArray, $attributesSetArray, 'id', false, $reindex);
310
+
311
+ return $productId;
312
+ }
313
+
314
+ /**
315
+ * Create product image
316
+ *
317
+ * @return string
318
+ */
319
+ protected function createProductImage($productId, $data, $store = null, $identifierType = 'id') {
320
+
321
+ return Mage::getModel('catalog/product_attribute_media_api') -> create($productId, Mage::helper('linnLiveConnect') -> objectToArray($data), $store, $identifierType);
322
+ }
323
+
324
+ /**
325
+ * Create product link association
326
+ *
327
+ * @return boolean
328
+ */
329
+ protected function createRelatedProduct($type, $productId, $linkedProductId, $identifierType = 'id') {
330
+
331
+ return Mage::getModel('catalog/product_link_api') -> assign($type, $productId, $linkedProductId, null, $identifierType);
332
+ }
333
+
334
+ /**
335
+ * Update simple product
336
+ *
337
+ * @return boolean
338
+ */
339
+ public function updateSimpleProduct($productId, $productData, $store = null, $identifierType = 'id') {
340
+
341
+ $helper = Mage::helper('linnLiveConnect');
342
+ $store = $helper -> currentStoreCode($store);
343
+
344
+ $helper -> updateProductData($productId, $productData, $store, $identifierType);
345
+
346
+ $productData = $helper -> updateProperties($productData);
347
+
348
+ $productData = $helper -> fixAttributes($productData);
349
+
350
+ $productAPI = Mage::getModel('catalog/product_api_v2');
351
+
352
+ return $productAPI -> update($productId, $productData, $store, $identifierType);
353
+ }
354
+
355
+ /**
356
+ * Update configurable product
357
+ *
358
+ * @return boolean
359
+ */
360
+ public function updateConfigurableProduct($productId, $reindex, $productData, $productsSet, $attributesSet, $store = null, $identifierType = 'id') {
361
+
362
+ $helper = Mage::helper('linnLiveConnect');
363
+
364
+ $helper -> updateConfigurableQuantity($productData);
365
+
366
+ $productData = $helper -> fixAttributes($productData);
367
+
368
+ $store = $helper -> currentStoreCode($store);
369
+
370
+ $helper -> updateProductData($productId, $productData, $store, $identifierType);
371
+
372
+ $productAPI = Mage::getModel('catalog/product_api_v2');
373
+
374
+ $productAPI -> update($productId, $productData, $store, $identifierType);
375
+
376
+ list($assignedProductsArray, $attributesSetArray) = $this -> _prepareConfigurableData($productsSet, $attributesSet, true);
377
+
378
+ return $this -> _updateConfigurable($store, $productId, $assignedProductsArray, $attributesSetArray, $identifierType, true, $reindex);
379
+ }
380
+
381
+ /**
382
+ * Update product image
383
+ *
384
+ * @return boolean
385
+ */
386
+ protected function updateProductImage($productId, $file, $data, $store = null, $identifierType = 'id') {
387
+
388
+ return Mage::getModel('catalog/product_attribute_media_api') -> update($productId, $file, Mage::helper('linnLiveConnect') -> objectToArray($data), $store, $identifierType);
389
+ }
390
+
391
+ /**
392
+ * Update product price
393
+ *
394
+ * @return boolean
395
+ */
396
+ protected function updateProductPrice($productId, $price, $store = null, $identifierType = 'id') {
397
+
398
+ $product = Mage::helper('catalog/product') -> getProduct($productId, $store, $identifierType);
399
+
400
+ if ($product && $product -> getId()) {
401
+ if ($product -> getPrice() != $price) {
402
+ $product -> setPrice($price);
403
+ $product -> save();
404
+ }
405
+ return true;
406
+ }
407
+ return false;
408
+ }
409
+
410
+ /**
411
+ * Delete product
412
+ *
413
+ * @return boolean
414
+ */
415
+ protected function deleteProduct($productId, $store = null, $identifierType = 'id') {
416
+ $product = Mage::helper('catalog/product') -> getProduct($productId, $store, $identifierType);
417
+
418
+ if ($product && $product -> getId()) {
419
+ return $product -> delete();
420
+ }
421
+ return false;
422
+ }
423
+
424
+ /**
425
+ * Delete product image
426
+ *
427
+ * @return boolean
428
+ */
429
+ protected function deleteProductImage($productId, $file, $identifierType = 'id') {
430
+
431
+ return Mage::getModel('catalog/product_attribute_media_api') -> remove($productId, $file, $identifierType);
432
+ }
433
+
434
+ /**
435
+ * Remove product link association
436
+ *
437
+ * @return boolean
438
+ */
439
+ protected function deleteRelatedProduct($type, $productId, $linkedProductId, $identifierType = 'id') {
440
+
441
+ return Mage::getModel('catalog/product_link_api') -> remove($type, $productId, $linkedProductId, $identifierType);
442
+ }
443
+
444
+ /********************************Bulk block***********************************************/
445
+ /*****************************************************************************************/
446
+ /*****************************************************************************************/
447
+ /**
448
+ * Bulk check products by sku/productId
449
+ */
450
+ public function checkProducts($data) {
451
+
452
+ $response = array();
453
+
454
+ for ($i = 0; $i < sizeof($data); $i++) {
455
+ $entity = $data[$i];
456
+ $product = Mage::helper('catalog/product') -> getProduct();
457
+ $response[] = array('sku' => $entity -> sku, 'success' => $this -> checkProduct($entity -> sku, $entity -> store, $entity -> identifierType));
458
+ }
459
+
460
+ return $response;
461
+
462
+ }
463
+
464
+ /**
465
+ * Bulk create simple products
466
+ */
467
+ public function createSimpleProducts($data) {
468
+
469
+ $this -> lockIndexer();
470
+
471
+ $response = array();
472
+
473
+ for ($i = 0; $i < sizeof($data); $i++) {
474
+ $entity = $data[$i];
475
+ try {
476
+ $productId = $this -> createSimpleProduct('simple', $entity -> set, $entity -> sku, $entity -> productData, $entity -> store, false);
477
+ $response[] = array('sku' => $entity -> sku, 'productId' => $productId, 'isError' => ($productId < 1));
478
+ } catch (Exception $e) {
479
+ $response[] = array('sku' => $entity -> sku, 'productId' => 0, 'isError' => true, 'error' => $e -> getMessage());
480
+ }
481
+ }
482
+
483
+ $this -> unlockIndexer();
484
+
485
+ return $response;
486
+ }
487
+
488
+ /**
489
+ * Bulk create configurable products
490
+ */
491
+ public function createConfigurableProducts($data) {
492
+
493
+ $this -> lockIndexer();
494
+
495
+ $response = array();
496
+
497
+ for ($i = 0; $i < sizeof($data); $i++) {
498
+ $entity = $data[$i];
499
+ try {
500
+ $productId = $this -> createConfigurableProduct($entity -> set, $entity -> sku, false, $entity -> productData, $entity -> productsSet, $entity -> attributesSet, $entity -> store);
501
+ $response[] = array('sku' => $entity -> sku, 'productId' => $productId, 'isError' => ($productId < 1));
502
+
503
+ } catch (Exception $e) {
504
+ $response[] = array('sku' => $entity -> sku, 'productId' => 0, 'isError' => true, 'error' => $e -> getMessage());
505
+ }
506
+ }
507
+
508
+ $this -> unlockIndexer();
509
+
510
+ return $response;
511
+ }
512
+
513
+ /**
514
+ * Bulk create related products
515
+ */
516
+ public function createRelatedProducts($data) {
517
+
518
+ $this -> lockIndexer();
519
+
520
+ $response = array();
521
+
522
+ for ($i = 0; $i < sizeof($data); $i++) {
523
+ $entity = $data[$i];
524
+ try {
525
+ $result = $this -> createRelatedProduct($entity -> type, $entity -> productId, $entity -> linkedProductId, null, 'id');
526
+ $response[] = array('relatedId' => $entity -> relatedId, 'productId' => $entity -> productId, 'isError' => !$result);
527
+ } catch (Exception $e) {
528
+ $response[] = array('relatedId' => $entity -> relatedId, 'productId' => $entity -> productId, 'isError' => true, 'error' => $e -> getMessage());
529
+ }
530
+ }
531
+
532
+ $this -> unlockIndexer();
533
+
534
+ return $response;
535
+ }
536
+
537
+ /**
538
+ * Bulk create product images
539
+ */
540
+ public function createProductImages($data) {
541
+
542
+ $this -> lockIndexer();
543
+
544
+ $response = array();
545
+
546
+ for ($i = 0; $i < sizeof($data); $i++) {
547
+ $entity = $data[$i];
548
+ try {
549
+ $result = $this -> createProductImage($entity -> productId, $entity -> data, $entity -> store, $entity -> identifierType);
550
+ $response[] = array('imageId' => $entity -> imageId, 'productId' => $entity -> productId, 'isError' => empty($result), 'file' => $result);
551
+ } catch (Exception $e) {
552
+ $response[] = array('imageId' => $entity -> imageId, 'productId' => $entity -> productId, 'isError' => true, 'error' => $e -> getMessage());
553
+ }
554
+ }
555
+
556
+ $this -> unlockIndexer();
557
+
558
+ return $response;
559
+ }
560
+
561
+ /**
562
+ * Bulk update product images
563
+ */
564
+ public function updateProductImages($data) {
565
+
566
+ $this -> lockIndexer();
567
+
568
+ $response = array();
569
+
570
+ for ($i = 0; $i < sizeof($data); $i++) {
571
+ $entity = $data[$i];
572
+ try {
573
+ $result = $this -> updateProductImage($entity -> productId, $entity -> file, $entity -> data, $entity -> store, $entity -> identifierType);
574
+ $response[] = array('imageId' => $entity -> imageId, 'productId' => $entity -> productId, 'isError' => !$result);
575
+ } catch (Exception $e) {
576
+ $response[] = array('imageId' => $entity -> imageId, 'productId' => $entity -> productId, 'isError' => true, 'error' => $e -> getMessage());
577
+ }
578
+ }
579
+
580
+ $this -> unlockIndexer();
581
+
582
+ return $response;
583
+ }
584
+
585
+ /**
586
+ * Bulk price update, TODO: success change to isError
587
+ */
588
+ public function updateProductPrices($data, $store, $identifierType = 'id') {
589
+
590
+ $this -> lockIndexer();
591
+
592
+ $response = array();
593
+
594
+ for ($i = 0; $i < sizeof($data); $i++) {
595
+ $entity = $data[$i];
596
+ try {
597
+ $result = $this -> updateProductPrice($entity -> sku, $entity -> price, $store, $identifierType);
598
+ $response[] = array('sku' => $entity -> sku, 'success' => $result);
599
+ } catch (Exception $e) {
600
+ $response[] = array('sku' => $entity -> sku, 'success' => false);
601
+ }
602
+ }
603
+
604
+ $this -> unlockIndexer();
605
+
606
+ return $response;
607
+ }
608
+
609
+ /**
610
+ * Bulk update simple products
611
+ */
612
+ public function updateSimpleProducts($data) {
613
+
614
+ $this -> lockIndexer();
615
+
616
+ $response = array();
617
+
618
+ for ($i = 0; $i < sizeof($data); $i++) {
619
+ $entity = $data[$i];
620
+ try {
621
+ $result = $this -> updateSimpleProduct($entity -> productId, $entity -> productData, $entity -> store, $entity -> identifierType);
622
+ $response[] = array('sku' => $entity -> sku, 'productId' => $entity -> productId, 'isError' => !$result);
623
+ } catch (Exception $e) {
624
+ $response[] = array('sku' => $entity -> sku, 'productId' => $entity -> productId, 'isError' => true, 'error' => $e -> getMessage());
625
+ }
626
+ }
627
+
628
+ $this -> unlockIndexer();
629
+
630
+ return $response;
631
+ }
632
+
633
+ /**
634
+ * Bulk update configurable products
635
+ */
636
+ public function updateConfigurableProducts($data) {
637
+
638
+ $this -> lockIndexer();
639
+
640
+ $response = array();
641
+
642
+ for ($i = 0; $i < sizeof($data); $i++) {
643
+ $entity = $data[$i];
644
+
645
+ try {
646
+ $result = $this -> updateConfigurableProduct($entity -> productId, false, $entity -> productData, $entity -> productsSet, $entity -> attributesSet, $entity -> store, $entity -> identifierType);
647
+ $response[] = array('sku' => $entity -> sku, 'productId' => $entity -> productId, 'isError' => !$result);
648
+ } catch (Exception $e) {
649
+ $response[] = array('sku' => $entity -> sku, 'productId' => $entity -> productId, 'isError' => true, 'error' => $e -> getMessage());
650
+ }
651
+ }
652
+
653
+ $this -> unlockIndexer();
654
+
655
+ return $response;
656
+ }
657
+
658
+ /**
659
+ * Bulk delete products
660
+ */
661
+ public function deleteProducts($data) {
662
+
663
+ $this -> lockIndexer();
664
+
665
+ $response = array();
666
+
667
+ for ($i = 0; $i < sizeof($data); $i++) {
668
+ $entity = $data[$i];
669
+ try {
670
+ $result = $this -> deleteProduct($entity -> productId, $entity -> store, $entity -> identifierType);
671
+
672
+ $response[] = array('sku' => $entity -> sku, 'productId' => $entity -> productId, 'isError' => !$result);
673
+
674
+ } catch (Exception $e) {
675
+ $response[] = array('sku' => $entity -> sku, 'productId' => $entity -> productId, 'isError' => true, 'error' => $e -> getMessage());
676
+ }
677
+ }
678
+
679
+ $this -> unlockIndexer();
680
+
681
+ return $response;
682
+ }
683
+
684
+ /**
685
+ * Bulk delete related products
686
+ */
687
+ public function deleteRelatedProducts($data) {
688
+
689
+ $this -> lockIndexer();
690
+
691
+ $response = array();
692
+
693
+ for ($i = 0; $i < sizeof($data); $i++) {
694
+ $entity = $data[$i];
695
+ try {
696
+ $result = $this -> deleteRelatedProduct($entity -> type, $entity -> productId, $entity -> linkedProductId, 'id');
697
+ $response[] = array('relatedId' => $entity -> relatedId, 'productId' => $entity -> productId, 'isError' => !$result);
698
+ } catch (Exception $e) {
699
+ $response[] = array('relatedId' => $entity -> relatedId, 'productId' => $entity -> productId, 'isError' => true, 'error' => $e -> getMessage());
700
+ }
701
+ }
702
+
703
+ $this -> unlockIndexer();
704
+
705
+ return $response;
706
+ }
707
+
708
+ /**
709
+ * Bulk delete product images
710
+ */
711
+ public function deleteProductImages($data) {
712
+
713
+ $this -> lockIndexer();
714
+
715
+ $response = array();
716
+
717
+ for ($i = 0; $i < sizeof($data); $i++) {
718
+ $entity = $data[$i];
719
+ try {
720
+ $result = $this -> deleteProductImage($entity -> productId, $entity -> file, $entity -> identifierType);
721
+ $response[] = array('imageId' => $entity -> imageId, 'productId' => $entity -> productId, 'isError' => !$result);
722
+ } catch (Exception $e) {
723
+ $response[] = array('imageId' => $entity -> imageId, 'productId' => $entity -> productId, 'isError' => true, 'error' => $e -> getMessage());
724
+ }
725
+ }
726
+
727
+ $this -> unlockIndexer();
728
+
729
+ return $response;
730
+ }
731
+
732
+ }
733
+
734
+
735
+ ?>
app/code/local/LinnSystems/LinnLiveConnect/Model/Main.php ADDED
@@ -0,0 +1,337 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class LinnSystems_LinnLiveConnect_Model_Main extends Mage_Core_Model_Abstract {
3
+
4
+ protected $_ignoredAttributes = array('created_at', 'updated_at', 'category_ids', 'required_options', 'old_id', 'url_key', 'url_path', 'has_options', 'image_label', 'small_image_label', 'thumbnail_label', 'image', 'small_image', 'thumbnail', 'options_container', 'entity_id', 'entity_type_id', 'attribute_set_id', 'type_id', 'sku', 'name', 'status', 'stock_item', 'description', );
5
+
6
+ protected $_permittedAttributes = array('select', 'multiselect', 'text', 'textarea', 'date', 'price');
7
+
8
+ protected function _prepareConfigurableData($productsSet, $attributesSet, $isUpdate) {
9
+
10
+ $helper = Mage::helper('linnLiveConnect');
11
+
12
+ $assignedProductsArray = $helper -> objectToArray($this -> _createProductsData($productsSet));
13
+
14
+ $_newAttributeOptions = $this -> _newConfigurableOptions($assignedProductsArray);
15
+ if (count($_newAttributeOptions) > 0) {
16
+ $this -> _checkAssignedProductsOptions($helper -> createOptions($_newAttributeOptions), $assignedProductsArray);
17
+ }
18
+
19
+ if (!is_array($attributesSet)) {
20
+ $attributesSet = array($attributesSet);
21
+ }
22
+
23
+ $attributesSetArray = $this -> _prepareAttributesData($helper -> objectToArray($attributesSet), $assignedProductsArray);
24
+
25
+ foreach ($attributesSetArray as $key => $value) {
26
+ $attributesSetArray[$key]["id"] = NULL;
27
+ $attributesSetArray[$key]["position"] = NULL;
28
+ $attributesSetArray[$key]["store_label"] = isset($value['frontend_label']) ? $value['frontend_label'] : NULL;
29
+ //$attributesSetArray[$key]["use_default"] = 0;
30
+
31
+ if ($isUpdate == false) {
32
+ //check if attribute exists and available
33
+ $checkAttribute = Mage::getModel('catalog/resource_eav_attribute') -> loadByCode('catalog_product', $attributesSetArray[$key]["attribute_code"]);
34
+
35
+ if (!$checkAttribute -> getId() || !$this -> _isConfigurable($checkAttribute)) {
36
+ throw new Mage_Api_Exception('invalid_variation_attribute', 'Invalid attribute [' . $checkAttribute['attribute_code'] . '] provided to Magento extension for creating Variation / Product with options. Check attributes/variations in LinnLive Magento configurator if they do exist/match the ones on the back-end.');
37
+ }
38
+ }
39
+
40
+ }
41
+ return array($assignedProductsArray, $attributesSetArray);
42
+ }
43
+
44
+ protected function _isConfigurable($attribute) {
45
+
46
+ $isConfigurable = 0;
47
+
48
+ if (isset($attribute['is_global']) && $attribute['is_global']) {
49
+ $attribute['scope'] = 'global';
50
+ }
51
+
52
+ if (($attribute['scope'] == 'global') && ($attribute['is_configurable'])) {
53
+ if (is_array($attribute['apply_to']) && sizeof($attribute['apply_to'])) {
54
+ if (in_array('simple', $attribute['apply_to'])) {
55
+ $isConfigurable = 1;
56
+ }
57
+ } elseif (is_string($attribute['apply_to']) && strlen($attribute['apply_to'])) {
58
+ if (strpos($attribute['apply_to'], 'simple') !== false) {
59
+ $isConfigurable = 1;
60
+ }
61
+ } else {
62
+ $isConfigurable = 1;
63
+ }
64
+ }
65
+ return $isConfigurable;
66
+ }
67
+
68
+ protected function _checkAssignedProductsOptions($availableOptions, &$assignedProductsArray) {
69
+
70
+ foreach ($assignedProductsArray as $id => $productOptions) {
71
+ foreach ($productOptions as $index => $option) {
72
+ if (isset($availableOptions[$option['attribute_id']][strtolower($option['label'])])) {
73
+ $assignedProductsArray[$id][$index]['value_index'] = $availableOptions[$option['attribute_id']][strtolower($option['label'])];
74
+ }
75
+ }
76
+ }
77
+ }
78
+
79
+ protected function _newConfigurableOptions($assignedProductsArray) {
80
+
81
+ $_attributesOptions = array();
82
+ foreach ($assignedProductsArray as $id => $productOptions) {
83
+ foreach ($productOptions as $option) {
84
+ if (isset($option['value_index']) && $option['value_index'] == '-1') {
85
+ if (isset($_attributesOptions[$option['attribute_id']])) {
86
+ $_attributesOptions[$option['attribute_id']][] = $option['label'];
87
+ } else {
88
+ $_attributesOptions[$option['attribute_id']] = array($option['label']);
89
+ }
90
+ }
91
+ }
92
+ }
93
+ return $_attributesOptions;
94
+ }
95
+
96
+ protected function _containsOption($attributeOption, $option) {
97
+
98
+ foreach ($attributeOption as $inArrayOption)
99
+ if ($inArrayOption['value_index'] == $option['value_index'])
100
+ return true;
101
+
102
+ return false;
103
+ }
104
+
105
+ protected function _prepareAttributesData($attributesSetArray, $assignedProductsArray) {
106
+
107
+ $_attributesOptions = array();
108
+ foreach ($assignedProductsArray as $id => $productOptions) {
109
+ foreach ($productOptions as $option) {
110
+ if (isset($_attributesOptions[$option['attribute_id']]) && !$this -> _containsOption($_attributesOptions[$option['attribute_id']], $option)) {
111
+ $_attributesOptions[$option['attribute_id']][] = $option;
112
+ } else if (!isset($_attributesOptions[$option['attribute_id']])) {
113
+ $_attributesOptions[$option['attribute_id']] = array();
114
+ $_attributesOptions[$option['attribute_id']][] = $option;
115
+ }
116
+ }
117
+ }
118
+
119
+ foreach ($attributesSetArray as $key => $attribute) {
120
+ if (isset($_attributesOptions[$attribute['attribute_id']])) {
121
+ $attributesSetArray[$key]['values'] = $_attributesOptions[$attribute['attribute_id']];
122
+ }
123
+ }
124
+
125
+ return $attributesSetArray;
126
+ }
127
+
128
+ protected function _updateConfigurable($store, $productId, $assignedProducts, $assignedAttributes, $identifierType, $isUpdate = false, $reindex = true) {
129
+
130
+ $magentoVer = $this -> _getCurrentVersion();
131
+ if ($magentoVer == 162) {
132
+ $store = Mage::app() -> getStore($store) -> getId();
133
+ } else {
134
+ $store = NULL;
135
+ }
136
+
137
+ $product = Mage::helper('catalog/product') -> getProduct($productId, $store, $identifierType);
138
+
139
+ $product -> setConfigurableProductsData($assignedProducts);
140
+
141
+ if ($isUpdate == false) {
142
+ $product -> setConfigurableAttributesData($assignedAttributes);
143
+ $product -> setCanSaveConfigurableAttributes(true);
144
+ }
145
+
146
+ try {
147
+ $result = $product -> save();
148
+ } catch (Exception $e) {
149
+ throw new Mage_Api_Exception('configurable_creating_error', $e -> getMessage());
150
+ }
151
+
152
+ return $result;
153
+ }
154
+
155
+ protected function _createProductsData($productData) {
156
+
157
+ $assignedProductsData = array();
158
+
159
+ if (is_array($productData)) {
160
+ foreach ($productData as $product) {
161
+ $assignedProductsData[$product -> product_id] = array();
162
+ if (is_array($product -> values)) {
163
+ foreach ($product->values as $productValue) {
164
+ $assignedProductsData[$product -> product_id][] = $productValue;
165
+ }
166
+ }
167
+ }
168
+ }
169
+
170
+ return $assignedProductsData;
171
+ }
172
+
173
+ protected function _getCurrentVersion() {
174
+
175
+ $verInfo = Mage::getVersionInfo();
176
+
177
+ return intval($verInfo['major'] . $verInfo['minor'] . $verInfo['revision']);
178
+ }
179
+
180
+ protected function _removeIgnoredAttributes($attributesList) {
181
+
182
+ $_preparedAttributes = array();
183
+ if (is_array($attributesList) && count($attributesList) > 0) {
184
+ foreach ($attributesList as $key => $value) {
185
+ if (!in_array($key, $this -> _ignoredAttributes) && !is_array($value))
186
+ $_preparedAttributes[] = array('key' => $key, 'value' => $value);
187
+ }
188
+ }
189
+
190
+ return $_preparedAttributes;
191
+ }
192
+
193
+ protected function _productAttributeInfo($attribute_id, $attributeAPI) {
194
+
195
+ $model = Mage::getResourceModel('catalog/eav_attribute') -> setEntityTypeId(Mage::getModel('eav/entity') -> setType('catalog_product') -> getTypeId());
196
+
197
+ $model -> load($attribute_id);
198
+
199
+ if (!$model -> getId()) {
200
+ throw new Mage_Api_Exception('attribute_not_exists');
201
+ }
202
+
203
+ if ($model -> isScopeGlobal()) {
204
+ $scope = 'global';
205
+ } elseif ($model -> isScopeWebsite()) {
206
+ $scope = 'website';
207
+ } else {
208
+ $scope = 'store';
209
+ }
210
+
211
+ $result = array(
212
+ 'attribute_id' => $model -> getId(),
213
+ 'attribute_code' => $model -> getAttributeCode(),
214
+ 'frontend_input' => $model -> getFrontendInput(),
215
+ 'default_value' => $model -> getDefaultValue(),
216
+ 'is_unique' => $model -> getIsUnique(),
217
+ 'is_required' => $model -> getIsRequired(),
218
+ 'apply_to' => $model -> getApplyTo(),
219
+ 'is_configurable' => $model -> getIsConfigurable(),
220
+ 'is_searchable' => $model -> getIsSearchable(),
221
+ 'is_visible_in_advanced_search' => $model -> getIsVisibleInAdvancedSearch(),
222
+ 'is_comparable' => $model -> getIsComparable(),
223
+ 'is_used_for_promo_rules' => $model -> getIsUsedForPromoRules(),
224
+ 'is_visible_on_front' => $model -> getIsVisibleOnFront(),
225
+ 'used_in_product_listing' => $model -> getUsedInProductListing(),
226
+ 'scope' => $scope,
227
+ );
228
+
229
+ // set options
230
+ $options = $attributeAPI -> options($model -> getId());
231
+ // remove empty first element
232
+ if ($model -> getFrontendInput() != 'boolean' && $model->getIsUserDefined()) {
233
+ array_shift($options);
234
+ }
235
+
236
+ if (count($options) > 0) {
237
+ $result['options'] = $options;
238
+ }
239
+
240
+ return $result;
241
+ }
242
+
243
+ protected function _log($message) {
244
+
245
+ Mage::log(print_r($message, true), null, 'LinnLiveExt.log');
246
+ }
247
+
248
+ /********************************Indexer block***********************************************/
249
+ /*****************************************************************************************/
250
+ /*****************************************************************************************/
251
+ public function disableIndexing() {
252
+
253
+ $states = array();
254
+ $blocked = array('cataloginventory_stock', 'catalog_product_flat', 'catalog_category_flat', 'catalogsearch_fulltext');
255
+
256
+ $processes = Mage::getSingleton('index/indexer') -> getProcessesCollection();
257
+ foreach ($processes as $process) {
258
+
259
+ $code = $process -> getIndexerCode();
260
+
261
+ if (in_array($code, $blocked) || $process -> getId() > 9) {
262
+ continue;
263
+ }
264
+
265
+ $states[] = array('key' => $code, 'value' => $process -> getMode());
266
+
267
+ $process -> setMode(Mage_Index_Model_Process::MODE_MANUAL) -> save();
268
+ }
269
+ return $states;
270
+ }
271
+
272
+ public function restoreIndexingById($data) {
273
+
274
+ foreach ($data as $key => $value) {
275
+
276
+ $process = Mage::getModel('index/indexer') -> getProcessByCode($key);
277
+ if ($process && $process -> getIndexerCode()) {
278
+
279
+ $value = $value == Mage_Index_Model_Process::MODE_MANUAL ? Mage_Index_Model_Process::MODE_MANUAL : Mage_Index_Model_Process::MODE_REAL_TIME;
280
+
281
+ if ($process -> getMode() != $value) {
282
+ $process -> setMode($value) -> save();
283
+ }
284
+
285
+ if ($process -> getStatus() == Mage_Index_Model_Process::STATUS_REQUIRE_REINDEX) {
286
+ $process -> reindexEverything();
287
+ }
288
+ }
289
+ }
290
+ }
291
+
292
+ protected function reindexProducts() {
293
+
294
+ $processes = Mage::getSingleton('index/indexer') -> getProcessesCollection();
295
+ foreach ($processes as $process) {
296
+ if ($process -> getStatus() == Mage_Index_Model_Process::STATUS_REQUIRE_REINDEX) {
297
+ $process -> reindexEverything();
298
+ }
299
+ }
300
+ }
301
+
302
+ protected function lockIndexer() {
303
+
304
+ Mage::setIsDeveloperMode(true);
305
+ //Mage::getSingleton('index/indexer') -> getProcessesCollection() -> walk('lockAndBlock');
306
+ }
307
+
308
+ protected function unlockIndexer() {
309
+
310
+ //Mage::getSingleton('index/indexer') -> getProcessesCollection() -> walk('unlock');
311
+ Mage::setIsDeveloperMode(false);
312
+ }
313
+
314
+ protected function cleanCache() {
315
+
316
+ Mage::app() -> getCacheInstance() -> flush();
317
+ Mage::app() -> cleanCache();
318
+ }
319
+
320
+ protected function disableAllIndexing() {
321
+
322
+ $processes = Mage::getSingleton('index/indexer') -> getProcessesCollection();
323
+ $processes -> walk('setMode', array(Mage_Index_Model_Process::MODE_MANUAL));
324
+ $processes -> walk('save');
325
+ }
326
+
327
+ protected function enableAllIndexing() {
328
+
329
+ $processes = Mage::getSingleton('index/indexer') -> getProcessesCollection();
330
+ //$processes -> walk('reindexAll');
331
+ $processes -> walk('setMode', array(Mage_Index_Model_Process::MODE_REAL_TIME));
332
+ $processes -> walk('save');
333
+ }
334
+
335
+ }
336
+
337
+ ?>
app/code/local/LinnSystems/LinnLiveConnect/Model/Product/Api.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Magento
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
+ * DISCLAIMER
17
+ *
18
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
19
+ * versions in the future. If you wish to customize Magento for your
20
+ * needs please refer to http://www.magentocommerce.com for more information.
21
+ *
22
+ * @category Mage
23
+ * @package Mage_Catalog
24
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
25
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
26
+ */
27
+
28
+ /**
29
+ * Catalog api resource
30
+ *
31
+ * @category Mage
32
+ * @package Mage_Catalog
33
+ * @author Magento Core Team <core@magentocommerce.com>
34
+ */
35
+ class LinnSystems_LinnLiveConnect_Model_Product_Api extends Mage_Catalog_Model_Product_Api {
36
+
37
+
38
+ }
app/code/local/LinnSystems/LinnLiveConnect/Model/Product/Api/V2.php ADDED
@@ -0,0 +1,70 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
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
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Mage
22
+ * @package Mage_Catalog
23
+ * @copyright Copyright (c) 2013 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Catalog product api V2
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Catalog
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class LinnSystems_LinnLiveConnect_Model_Product_Api_V2 extends Mage_Catalog_Model_Product_Api_V2
35
+ {
36
+ public function create($type, $set, $sku, $productData, $store = NULL) {
37
+ $tries = 0;
38
+ $maxtries = 3;
39
+
40
+
41
+ for ($tries = 0; $tries < $maxtries; $tries++) {
42
+ try {
43
+ return parent::create($type, $set, $sku, $productData, $store);
44
+ } catch (Exception $e) {
45
+ if ($e -> getMessage() == 'SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction') {
46
+ sleep(1);
47
+ } else {
48
+ throw $e;
49
+ }
50
+ }
51
+ }
52
+ }
53
+
54
+ public function update($productId, $productData, $store = null, $identifierType = null) {
55
+ $tries = 0;
56
+ $maxtries = 3;
57
+
58
+ for ($tries = 0; $tries < $maxtries; $tries++) {
59
+ try {
60
+ return parent::update($productId, $productData, $store, $identifierType);
61
+ } catch (Exception $e) {
62
+ if ($e -> getMessage() == 'SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction') {
63
+ sleep(1);
64
+ } else {
65
+ throw $e;
66
+ }
67
+ }
68
+ }
69
+ }
70
+ }
app/code/local/LinnSystems/LinnLiveConnect/Model/Product/Attribute/Api.php ADDED
@@ -0,0 +1,38 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
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
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Mage
22
+ * @package Mage_Catalog
23
+ * @copyright Copyright (c) 2013 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Catalog product attribute api
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Catalog
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class LinnSystems_LinnLiveConnect_Model_Product_Attribute_Api extends Mage_Catalog_Model_Product_Attribute_Api
35
+ {
36
+
37
+
38
+ } // Class Mage_Catalog_Model_Product_Attribute_Api End
app/code/local/LinnSystems/LinnLiveConnect/Model/Product/Attribute/Media/Api.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ /**
4
+ * Magento
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
+ * DISCLAIMER
17
+ *
18
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
19
+ * versions in the future. If you wish to customize Magento for your
20
+ * needs please refer to http://www.magentocommerce.com for more information.
21
+ *
22
+ * @category Mage
23
+ * @package Mage_Catalog
24
+ * @copyright Copyright (c) 2010 Magento Inc. (http://www.magentocommerce.com)
25
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
26
+ */
27
+
28
+ /**
29
+ * Catalog product media api
30
+ *
31
+ * @category Mage
32
+ * @package Mage_Catalog
33
+ * @author Magento Core Team <core@magentocommerce.com>
34
+ */
35
+ class LinnSystems_LinnLiveConnect_Model_Product_Attribute_Media_Api extends Mage_Catalog_Model_Product_Attribute_Media_Api {
36
+
37
+ }
38
+
39
+ // Class Mage_Catalog_Model_Product_Attribute_Media_Api End
app/code/local/LinnSystems/LinnLiveConnect/Model/Product/Link/Api.php ADDED
@@ -0,0 +1,37 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /**
3
+ * Magento
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
+ * DISCLAIMER
16
+ *
17
+ * Do not edit or add to this file if you wish to upgrade Magento to newer
18
+ * versions in the future. If you wish to customize Magento for your
19
+ * needs please refer to http://www.magentocommerce.com for more information.
20
+ *
21
+ * @category Mage
22
+ * @package Mage_Catalog
23
+ * @copyright Copyright (c) 2013 Magento Inc. (http://www.magentocommerce.com)
24
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
25
+ */
26
+
27
+ /**
28
+ * Catalog product link api
29
+ *
30
+ * @category Mage
31
+ * @package Mage_Catalog
32
+ * @author Magento Core Team <core@magentocommerce.com>
33
+ */
34
+ class LinnSystems_LinnLiveConnect_Model_Product_Link_Api extends Mage_Catalog_Model_Product_Link_Api
35
+ {
36
+
37
+ } // Class Mage_Catalog_Model_Product_Link_Api End
app/code/local/LinnSystems/LinnLiveConnect/etc/api.xml CHANGED
@@ -70,6 +70,14 @@
70
  <title>Bulk create product images</title>
71
  <acl>linnLive/createProductImages</acl>
72
  </createProductImages>
 
 
 
 
 
 
 
 
73
  <updateProductImages translate="title" module="linnLiveConnect">
74
  <title>Bulk update product images</title>
75
  <acl>linnLive/updateProductImages</acl>
@@ -226,6 +234,12 @@
226
  <createProductImages translate="title" module="linnLiveConnect">
227
  <title>Bulk create product images</title>
228
  </createProductImages>
 
 
 
 
 
 
229
  <updateProductImages translate="title" module="linnLiveConnect">
230
  <title>Bulk update product images</title>
231
  </updateProductImages>
70
  <title>Bulk create product images</title>
71
  <acl>linnLive/createProductImages</acl>
72
  </createProductImages>
73
+ <createProductImagesByPath translate="title" module="linnLiveConnect">
74
+ <title>Bulk create product images by path</title>
75
+ <acl>linnLive/createProductImagesByPath</acl>
76
+ </createProductImagesByPath>
77
+ <createProductImagesByUrl translate="title" module="linnLiveConnect">
78
+ <title>Bulk create product images by path</title>
79
+ <acl>linnLive/createProductImagesByUrl</acl>
80
+ </createProductImagesByUrl>
81
  <updateProductImages translate="title" module="linnLiveConnect">
82
  <title>Bulk update product images</title>
83
  <acl>linnLive/updateProductImages</acl>
234
  <createProductImages translate="title" module="linnLiveConnect">
235
  <title>Bulk create product images</title>
236
  </createProductImages>
237
+ <createProductImagesByPath translate="title" module="linnLiveConnect">
238
+ <title>Bulk create product images</title>
239
+ </createProductImagesByPath>
240
+ <createProductImagesByUrl translate="title" module="linnLiveConnect">
241
+ <title>Bulk create product images</title>
242
+ </createProductImagesByUrl>
243
  <updateProductImages translate="title" module="linnLiveConnect">
244
  <title>Bulk update product images</title>
245
  </updateProductImages>
app/code/local/LinnSystems/LinnLiveConnect/etc/config.xml CHANGED
@@ -2,7 +2,7 @@
2
  <config>
3
  <modules>
4
  <LinnSystems_LinnLiveConnect>
5
- <version>1.1.55</version>
6
  </LinnSystems_LinnLiveConnect>
7
  </modules>
8
  <global>
@@ -12,6 +12,15 @@
12
  </linnLiveConnect>
13
  </helpers>
14
  <models>
 
 
 
 
 
 
 
 
 
15
  <linnLiveConnect>
16
  <class>LinnSystems_LinnLiveConnect_Model</class>
17
  </linnLiveConnect>
2
  <config>
3
  <modules>
4
  <LinnSystems_LinnLiveConnect>
5
+ <version>1.1.56</version>
6
  </LinnSystems_LinnLiveConnect>
7
  </modules>
8
  <global>
12
  </linnLiveConnect>
13
  </helpers>
14
  <models>
15
+ <catalog>
16
+ <rewrite>
17
+ <category_api>LinnSystems_LinnLiveConnect_Model_Category_Api</category_api>
18
+ <product_api>LinnSystems_LinnLiveConnect_Model_Product_Api</product_api>
19
+ <product_attribute_api>LinnSystems_LinnLiveConnect_Model_Product_Attribute_Api</product_attribute_api>
20
+ <product_attribute_media_api>LinnSystems_LinnLiveConnect_Model_Product_Attribute_Media_Api</product_attribute_media_api>
21
+ <product_link_api>LinnSystems_LinnLiveConnect_Model_Product_Link_Api</product_link_api>
22
+ </rewrite>
23
+ </catalog>
24
  <linnLiveConnect>
25
  <class>LinnSystems_LinnLiveConnect_Model</class>
26
  </linnLiveConnect>
app/code/local/LinnSystems/LinnLiveConnect/etc/wsi.xml CHANGED
@@ -17,6 +17,9 @@
17
  <xsd:element minOccurs="0" maxOccurs="1" name="api_config" type="typens:linnLiveGetGeneralInfoApiConfigResponseDataEntity" />
18
  <xsd:element minOccurs="1" maxOccurs="1" name="compilation_enabled" type="xsd:boolean" />
19
  <xsd:element minOccurs="1" maxOccurs="1" name="max_upload_size" type="xsd:string" />
 
 
 
20
  </xsd:sequence>
21
  </xsd:complexType>
22
 
@@ -688,7 +691,7 @@
688
  </xsd:sequence>
689
  </xsd:complexType>
690
  </xsd:element>
691
-
692
  <xsd:element name="linnLiveCreateConfigurableProductsRequestParam">
693
  <xsd:complexType>
694
  <xsd:sequence>
@@ -811,6 +814,41 @@
811
  </xsd:complexType>
812
  </xsd:element>
813
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
814
  <xsd:element name="linnLiveUpdateProductImagesRequestParam">
815
  <xsd:complexType>
816
  <xsd:sequence>
@@ -988,7 +1026,21 @@
988
  <wsdl:message name="linnLiveCreateProductImagesResponse">
989
  <wsdl:part name="parameters" element="typens:linnLiveCreateProductImagesResponseParam" />
990
  </wsdl:message>
991
-
 
 
 
 
 
 
 
 
 
 
 
 
 
 
992
  <wsdl:message name="linnLiveUpdateProductImagesRequest">
993
  <wsdl:part name="parameters" element="typens:linnLiveUpdateProductImagesRequestParam" />
994
  </wsdl:message>
@@ -1017,7 +1069,7 @@
1017
  <wsdl:part name="parameters" element="typens:linnLiveInfoResponseParam" />
1018
  </wsdl:message>
1019
 
1020
- <!-- Stub parameters for catalogProductAttributeRemove , remove for 1.8 -->
1021
  <wsdl:message name="catalogProductAttributeRemoveRequest">
1022
  <wsdl:part name="parameters" element="typens:linnLiveAttributeRemoveRequestParam" />
1023
  </wsdl:message>
@@ -1069,6 +1121,18 @@
1069
  <wsdl:output message="typens:linnLiveCreateProductImagesResponse" />
1070
  </wsdl:operation>
1071
 
 
 
 
 
 
 
 
 
 
 
 
 
1072
  <wsdl:operation name="linnLiveUpdateProductImages">
1073
  <wsdl:documentation>Update bulk product images</wsdl:documentation>
1074
  <wsdl:input message="typens:linnLiveUpdateProductImagesRequest" />
@@ -1246,6 +1310,26 @@
1246
  </wsdl:output>
1247
  </wsdl:operation>
1248
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1249
  <wsdl:operation name="linnLiveUpdateProductImages">
1250
  <soap:operation soapAction="" />
1251
  <wsdl:input>
17
  <xsd:element minOccurs="0" maxOccurs="1" name="api_config" type="typens:linnLiveGetGeneralInfoApiConfigResponseDataEntity" />
18
  <xsd:element minOccurs="1" maxOccurs="1" name="compilation_enabled" type="xsd:boolean" />
19
  <xsd:element minOccurs="1" maxOccurs="1" name="max_upload_size" type="xsd:string" />
20
+ <xsd:element minOccurs="1" maxOccurs="1" name="store" type="xsd:string" />
21
+ <xsd:element minOccurs="1" maxOccurs="1" name="extension_version" type="xsd:string" />
22
+ <xsd:element minOccurs="1" maxOccurs="1" name="max_execution_time" type="xsd:string" />
23
  </xsd:sequence>
24
  </xsd:complexType>
25
 
691
  </xsd:sequence>
692
  </xsd:complexType>
693
  </xsd:element>
694
+
695
  <xsd:element name="linnLiveCreateConfigurableProductsRequestParam">
696
  <xsd:complexType>
697
  <xsd:sequence>
814
  </xsd:complexType>
815
  </xsd:element>
816
 
817
+ <xsd:element name="linnLiveCreateProductImagesByPathRequestParam">
818
+ <xsd:complexType>
819
+ <xsd:sequence>
820
+ <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
821
+ <xsd:element minOccurs="1" maxOccurs="1" name="version" type="xsd:int" />
822
+ <xsd:element minOccurs="1" maxOccurs="1" name="data" type="typens:linnLiveCreateProductImagesRequestArray" />
823
+ </xsd:sequence>
824
+ </xsd:complexType>
825
+ </xsd:element>
826
+ <xsd:element name="linnLiveCreateProductImagesByPathResponseParam">
827
+ <xsd:complexType>
828
+ <xsd:sequence>
829
+ <xsd:element name="result" minOccurs="0" type="typens:linnLiveBulkImageResponseArray"/>
830
+ </xsd:sequence>
831
+ </xsd:complexType>
832
+ </xsd:element>
833
+
834
+ <xsd:element name="linnLiveCreateProductImagesByUrlRequestParam">
835
+ <xsd:complexType>
836
+ <xsd:sequence>
837
+ <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
838
+ <xsd:element minOccurs="1" maxOccurs="1" name="version" type="xsd:int" />
839
+ <xsd:element minOccurs="1" maxOccurs="1" name="data" type="typens:linnLiveCreateProductImagesRequestArray" />
840
+ </xsd:sequence>
841
+ </xsd:complexType>
842
+ </xsd:element>
843
+ <xsd:element name="linnLiveCreateProductImagesByUrlResponseParam">
844
+ <xsd:complexType>
845
+ <xsd:sequence>
846
+ <xsd:element name="result" minOccurs="0" type="typens:linnLiveBulkImageResponseArray"/>
847
+ </xsd:sequence>
848
+ </xsd:complexType>
849
+ </xsd:element>
850
+
851
+
852
  <xsd:element name="linnLiveUpdateProductImagesRequestParam">
853
  <xsd:complexType>
854
  <xsd:sequence>
1026
  <wsdl:message name="linnLiveCreateProductImagesResponse">
1027
  <wsdl:part name="parameters" element="typens:linnLiveCreateProductImagesResponseParam" />
1028
  </wsdl:message>
1029
+
1030
+ <wsdl:message name="linnLiveCreateProductImagesByPathRequest">
1031
+ <wsdl:part name="parameters" element="typens:linnLiveCreateProductImagesByPathRequestParam" />
1032
+ </wsdl:message>
1033
+ <wsdl:message name="linnLiveCreateProductImagesByPathResponse">
1034
+ <wsdl:part name="parameters" element="typens:linnLiveCreateProductImagesByPathResponseParam" />
1035
+ </wsdl:message>
1036
+
1037
+ <wsdl:message name="linnLiveCreateProductImagesByUrlRequest">
1038
+ <wsdl:part name="parameters" element="typens:linnLiveCreateProductImagesByUrlRequestParam" />
1039
+ </wsdl:message>
1040
+ <wsdl:message name="linnLiveCreateProductImagesByUrlResponse">
1041
+ <wsdl:part name="parameters" element="typens:linnLiveCreateProductImagesByUrlResponseParam" />
1042
+ </wsdl:message>
1043
+
1044
  <wsdl:message name="linnLiveUpdateProductImagesRequest">
1045
  <wsdl:part name="parameters" element="typens:linnLiveUpdateProductImagesRequestParam" />
1046
  </wsdl:message>
1069
  <wsdl:part name="parameters" element="typens:linnLiveInfoResponseParam" />
1070
  </wsdl:message>
1071
 
1072
+ <!-- Stub parameters for catalogProductAttributeRemove , remove for 1.8 -->
1073
  <wsdl:message name="catalogProductAttributeRemoveRequest">
1074
  <wsdl:part name="parameters" element="typens:linnLiveAttributeRemoveRequestParam" />
1075
  </wsdl:message>
1121
  <wsdl:output message="typens:linnLiveCreateProductImagesResponse" />
1122
  </wsdl:operation>
1123
 
1124
+ <wsdl:operation name="linnLiveCreateProductImagesByPath">
1125
+ <wsdl:documentation>Create bulk product images</wsdl:documentation>
1126
+ <wsdl:input message="typens:linnLiveCreateProductImagesByPathRequest" />
1127
+ <wsdl:output message="typens:linnLiveCreateProductImagesByPathResponse" />
1128
+ </wsdl:operation>
1129
+
1130
+ <wsdl:operation name="linnLiveCreateProductImagesByUrl">
1131
+ <wsdl:documentation>Create bulk product images</wsdl:documentation>
1132
+ <wsdl:input message="typens:linnLiveCreateProductImagesByUrlRequest" />
1133
+ <wsdl:output message="typens:linnLiveCreateProductImagesByUrlResponse" />
1134
+ </wsdl:operation>
1135
+
1136
  <wsdl:operation name="linnLiveUpdateProductImages">
1137
  <wsdl:documentation>Update bulk product images</wsdl:documentation>
1138
  <wsdl:input message="typens:linnLiveUpdateProductImagesRequest" />
1310
  </wsdl:output>
1311
  </wsdl:operation>
1312
 
1313
+ <wsdl:operation name="linnLiveCreateProductImagesByPath">
1314
+ <soap:operation soapAction="" />
1315
+ <wsdl:input>
1316
+ <soap:body use="literal" />
1317
+ </wsdl:input>
1318
+ <wsdl:output>
1319
+ <soap:body use="literal" />
1320
+ </wsdl:output>
1321
+ </wsdl:operation>
1322
+
1323
+ <wsdl:operation name="linnLiveCreateProductImagesByUrl">
1324
+ <soap:operation soapAction="" />
1325
+ <wsdl:input>
1326
+ <soap:body use="literal" />
1327
+ </wsdl:input>
1328
+ <wsdl:output>
1329
+ <soap:body use="literal" />
1330
+ </wsdl:output>
1331
+ </wsdl:operation>
1332
+
1333
  <wsdl:operation name="linnLiveUpdateProductImages">
1334
  <soap:operation soapAction="" />
1335
  <wsdl:input>
package.xml CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>LinnLiveConnect</name>
4
- <version>1.1.55</version>
5
  <stability>stable</stability>
6
  <license>GPL v2</license>
7
  <channel>community</channel>
@@ -9,11 +9,11 @@
9
  <summary>Extended SOAP WS-I compliant API to support integration with LinnLive2.</summary>
10
  <description>Extended SOAP WS-I compliant API to support integration with LinnLive2 (http://www.linnlive.com).&#xD;
11
  Contains some workarounds to avoid bugs in original Magento modules and additional functionality to operate Magento store remotely.</description>
12
- <notes>price update fixed</notes>
13
  <authors><author><name>Albert Andrejev</name><user>albert_andrejev</user><email>albert@linnsystems.com</email></author><author><name>Pavel Nikolajev</name><user>Pavel_LL2</user><email>pavel.nokolajev@linnsystems.com</email></author><author><name>Aleksandr Kornev</name><user>alex_LL2</user><email>alex.kornevs@linnsystems.com</email></author></authors>
14
- <date>2014-11-04</date>
15
- <time>14:00:26</time>
16
- <contents><target name="magelocal"><dir name="LinnSystems"><dir name="LinnLiveConnect"><dir name="Helper"><file name="Data.php" hash="c9e451e14ccc0e723f6535627ade9e0d"/><file name="Settings.php" hash="086ba912d38dc66964a2f40f685394a5"/></dir><dir name="Model"><dir name="Api"><file name="V2.php" hash="bca78c146c45b83af9f1d18494f7be9f"/></dir></dir><dir name="etc"><file name="api.xml" hash="75b6e8083d17b8dbf4c1cab2ff3ed1ea"/><file name="config.xml" hash="0ec4b881655aa0352392a279cf244291"/><file name="wsdl.xml" hash="2b450fd6a6332d20583aaa4fc52012b6"/><file name="wsi.xml" hash="c27640d6dc0ddb63fa3b0450a8312780"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="LinnSystems_LinnLiveConnect.xml" hash="19c48712cd0516815d6784592ada0881"/></dir></target></contents>
17
  <compatible/>
18
  <dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies>
19
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>LinnLiveConnect</name>
4
+ <version>1.1.56</version>
5
  <stability>stable</stability>
6
  <license>GPL v2</license>
7
  <channel>community</channel>
9
  <summary>Extended SOAP WS-I compliant API to support integration with LinnLive2.</summary>
10
  <description>Extended SOAP WS-I compliant API to support integration with LinnLive2 (http://www.linnlive.com).&#xD;
11
  Contains some workarounds to avoid bugs in original Magento modules and additional functionality to operate Magento store remotely.</description>
12
+ <notes>improve compatibility with third party extensions</notes>
13
  <authors><author><name>Albert Andrejev</name><user>albert_andrejev</user><email>albert@linnsystems.com</email></author><author><name>Pavel Nikolajev</name><user>Pavel_LL2</user><email>pavel.nokolajev@linnsystems.com</email></author><author><name>Aleksandr Kornev</name><user>alex_LL2</user><email>alex.kornevs@linnsystems.com</email></author></authors>
14
+ <date>2014-11-17</date>
15
+ <time>09:26:38</time>
16
+ <contents><target name="magelocal"><dir name="LinnSystems"><dir name="LinnLiveConnect"><dir name="Helper"><file name="Data.php" hash="62cd16402139b5316cb7b70fa6d2695c"/><file name="Factory.php" hash="7e0a0e26fa3618917f3540b799b05840"/><file name="Settings.php" hash="086ba912d38dc66964a2f40f685394a5"/></dir><dir name="Model"><dir name="Api"><file name="V2.php" hash="a60247b30a00144ee34b77b74821266a"/></dir><dir name="Category"><file name="Api.php" hash="c01d5bb1dfb59a559c3b94615593e38d"/></dir><file name="Community.php" hash="9018b657efc39133e30e57ff31fcc789"/><file name="Main.php" hash="bdf4ddce8fa2b01d75bd9f69ae854ab3"/><dir name="Product"><dir name="Api"><file name="V2.php" hash="0497a6775a80f0292b47aa0e64eee77d"/></dir><file name="Api.php" hash="721f80734374313c91d2cfbf46fb7a17"/><dir name="Attribute"><file name="Api.php" hash="d0678623a145bc2d76993819bd63bdb9"/><dir name="Media"><file name="Api.php" hash="62d58c61d93371793ebe94162755c4cd"/></dir></dir><dir name="Link"><file name="Api.php" hash="d42a76ca6368eabad4e4a96fd40a93a2"/></dir></dir></dir><dir name="etc"><file name="api.xml" hash="a4b2a568bf5b2def5f3fe32c06b4528c"/><file name="config.xml" hash="f60368e8365a7b2518c78f3b28d02b9d"/><file name="wsdl.xml" hash="2b450fd6a6332d20583aaa4fc52012b6"/><file name="wsi.xml" hash="67dfb6257459f972cebaa06e3443a67f"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="LinnSystems_LinnLiveConnect.xml" hash="19c48712cd0516815d6784592ada0881"/></dir></target></contents>
17
  <compatible/>
18
  <dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies>
19
  </package>