LinnLiveConnect - Version 1.1.53

Version Notes

bulk methods added

Download this release

Release Info

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


Code changes from version 1.1.52 to 1.1.53

app/code/local/LinnSystems/LinnLiveConnect/Helper/Data.php CHANGED
@@ -1,4 +1,379 @@
1
  <?php
2
  class LinnSystems_LinnLiveConnect_Helper_Data extends Mage_Core_Helper_Abstract
3
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
4
  }
1
  <?php
2
  class LinnSystems_LinnLiveConnect_Helper_Data extends Mage_Core_Helper_Abstract
3
  {
4
+
5
+ //TODO: use helper func
6
+ public function objectToArray( $result )
7
+ {
8
+ $array = array();
9
+ foreach ($result as $key=>$value)
10
+ {
11
+ if (is_object($value) || is_array($value))
12
+ {
13
+ $array[$key]=$this->objectToArray($value);
14
+ }
15
+ else
16
+ {
17
+ $array[$key]=$value;
18
+ }
19
+ }
20
+ return $array;
21
+ }
22
+
23
+ public function getProductBySku($sku)
24
+ {
25
+ if ($sku) {
26
+ $product = Mage::getModel('catalog/product');
27
+ $productId = $product->getIdBySku((string)$sku);
28
+ if ($productId) {
29
+ $product->load($productId);
30
+ if ($product->getId()) {
31
+ return $product;
32
+ }
33
+ }
34
+ }
35
+ }
36
+
37
+
38
+ public function _convertFiltersToArray($filters) {
39
+ $arrayParams = array(
40
+ 'nin',
41
+ 'in',
42
+ );
43
+
44
+ $preparedFilters = array();
45
+
46
+ if (isset($filters->filter)) {
47
+ $preparedFilters = $filters->filter;
48
+ }
49
+
50
+ if (isset($filters->complex_filter)) {
51
+
52
+ foreach ($filters->complex_filter as $idx=>$data) {
53
+ if (is_object($data->value)) {
54
+ //1.8
55
+ $field = $data->key;
56
+ $opts = $data->value;
57
+
58
+ } else {
59
+ //1.7
60
+ $field = $idx;
61
+ $opts = $data;
62
+ }
63
+
64
+ $value = (in_array($opts->key, $arrayParams)) ? explode(',', $opts->value) : $opts->value;
65
+ $preparedFilters[$field][$opts->key] = $value;
66
+ }
67
+ }
68
+ return $preparedFilters;
69
+ }
70
+
71
+ protected function _log($message) {
72
+ Mage::log(print_r($message, true), null, 'LinnLiveExt.log');
73
+ }
74
+
75
+ public function productImages($attributesList)
76
+ {
77
+ $_images = array();
78
+
79
+ if (is_array($attributesList) && count($attributesList) > 0 && isset($attributesList['media_gallery']))
80
+ {
81
+ $small = empty($attributesList['small_image']) ? false : $attributesList['small_image'];
82
+ $base = empty($attributesList['image']) ? false : $attributesList['image'];
83
+ $thumb = empty($attributesList['thumbnail']) ? false : $attributesList['thumbnail'];
84
+
85
+ foreach($attributesList['media_gallery']['images'] as $key=>$value)
86
+ {
87
+ $newImage = array();
88
+ $newImage['file'] = $value['file'];
89
+ $newImage['label'] = $value['label'];
90
+ $newImage['disabled'] = $value['disabled'] ? true : false;
91
+
92
+ $newImage['small_image'] = $small == $newImage['file'];
93
+ $newImage['image'] = $base == $newImage['file'];
94
+ $newImage['thumbnail'] = $thumb == $newImage['file'];
95
+
96
+ $_images[] = $newImage;
97
+ }
98
+ }
99
+
100
+ return $_images;
101
+ }
102
+
103
+
104
+ public function currentStoreCode($store=null)
105
+ {
106
+ if ($store != null) {
107
+ return $store;
108
+ }
109
+ return $this->getDefaultStore()->getCode();
110
+ }
111
+
112
+ private function getDefaultStore($storeCode=null)
113
+ {
114
+ if (Mage::app()->isSingleStoreMode()) {
115
+ return Mage::app()->getWebsite(true)->getDefaultStore();
116
+ }
117
+
118
+ if ($storeCode != null) {
119
+ return Mage::getModel('core/store')->load( $storeCode, 'code');
120
+ }
121
+
122
+ $mageRunCode = isset($_SERVER['MAGE_RUN_CODE']) ? $_SERVER['MAGE_RUN_CODE'] : '';
123
+ $mageRunType = isset($_SERVER['MAGE_RUN_TYPE']) ? $_SERVER['MAGE_RUN_TYPE'] : 'store';
124
+
125
+ if(!empty($mageRunCode)){
126
+ switch($mageRunType){
127
+ case 'store':
128
+ return Mage::getModel('core/store')->load( $mageRunCode, 'code');
129
+ break;
130
+
131
+ case 'website':
132
+ return Mage::getModel('core/website')->load( $mageRunCode, 'code')->getDefaultStore();
133
+ break;
134
+ }
135
+ }
136
+
137
+ return Mage::app()->getWebsite(true)->getDefaultStore();//Mage::app()->getStore();
138
+ }
139
+
140
+
141
+ public function updateConfigurableQuantity( & $productData)
142
+ {
143
+ $productData = $this->updateProperties($productData);
144
+
145
+ if (!property_exists($productData, 'stock_data'))
146
+ {
147
+ $productData->stock_data = new stdClass();
148
+ }
149
+
150
+ $productData->stock_data->manage_stock = 1;
151
+ $productData->stock_data->is_in_stock = 1;
152
+ }
153
+
154
+ public function updateProperties($productData)
155
+ {
156
+ if (property_exists($productData, 'status')) {
157
+ $productData->status = ($productData->status == 1) ? Mage_Catalog_Model_Product_Status::STATUS_ENABLED : Mage_Catalog_Model_Product_Status::STATUS_DISABLED;
158
+ }
159
+
160
+ if (property_exists($productData, 'stock_data') && property_exists($productData->stock_data, 'qty')) {
161
+ $productData->stock_data->qty = intval($productData->stock_data->qty);
162
+ $productData->stock_data->is_in_stock = 1;
163
+ $productData->stock_data->manage_stock = 1;
164
+ }
165
+ return $productData;
166
+ }
167
+
168
+ public function createOptions($newOptions)
169
+ {
170
+ $installer = new Mage_Eav_Model_Entity_Setup('core_setup');
171
+ $attributeApi = Mage::getModel('catalog/product_attribute_api');
172
+ $helperCatalog = Mage::helper('catalog');
173
+
174
+ $installer->startSetup();
175
+
176
+ $attributesList = array();
177
+
178
+ foreach($newOptions as $attribute_id=>$options)
179
+ {
180
+ $aOption = array();
181
+ $aOption['attribute_id'] = $attribute_id;
182
+ $attributesList[] = $attribute_id;
183
+
184
+ $i=0;
185
+ foreach($options as $option)
186
+ {
187
+ $optionTitle = $helperCatalog->stripTags($option);
188
+
189
+ $aOption['value']['option'.$i][0] = $optionTitle;
190
+ $i++;
191
+ }
192
+ $installer->addAttributeOption($aOption);
193
+ }
194
+ $installer->endSetup();
195
+
196
+ Mage::app()->cleanCache(array(Mage_Core_Model_Translate::CACHE_TAG));
197
+
198
+
199
+ $currentOptions = array();
200
+ $attributeApi = Mage::getModel('catalog/product_attribute_api');
201
+ foreach($attributesList as $attribute_id)
202
+ {
203
+ if (!isset($currentOptions[$attribute_id])){
204
+ $currentOptions[$attribute_id] = array();
205
+ }
206
+
207
+ $attributeOptions = $attributeApi->options($attribute_id);
208
+
209
+ foreach ($attributeOptions as $opts)
210
+ {
211
+
212
+ $label = strtolower($opts['label']);
213
+ $optionId = $opts['value'];
214
+ if (!isset($currentOptions[$attribute_id][$label]))
215
+ $currentOptions[$attribute_id][$label] = $optionId;
216
+ else {
217
+ $oldId = $currentOptions[$attribute_id][$label];
218
+ if ($oldId > $optionId)
219
+ {
220
+ $attributeApi->removeOption($attribute_id, $oldId);
221
+ $currentOptions[$attribute_id][$label] = $optionId;
222
+ }
223
+ else
224
+ {
225
+ $attributeApi->removeOption($attribute_id, $optionId);
226
+ }
227
+ }
228
+ }
229
+ }
230
+
231
+ return $currentOptions;
232
+ }
233
+
234
+
235
+ //Fix for buggy associativeArray implementation
236
+ public function fixAttributes($productData)
237
+ {
238
+ $_newAttributeOptions = $this->newOptions($productData);
239
+
240
+ $_availableOptions = array();
241
+ if (count($_newAttributeOptions) > 0)
242
+ {
243
+ $_availableOptions = $this->createOptions($_newAttributeOptions);
244
+ }
245
+
246
+ if (property_exists($productData, 'additional_attributes')) {
247
+
248
+ $additional_attributes = new stdClass();
249
+ $additional_attributes->single_data = array();
250
+ $i = 0;
251
+
252
+ if (is_array($productData->additional_attributes))
253
+ {
254
+ foreach ($productData->additional_attributes as $option) {
255
+ $additional_attributes->single_data[$i] = new stdClass();
256
+ $additional_attributes->single_data[$i]->key = $option->code;
257
+
258
+ $value = isset($option->value)? $option->value : "";
259
+
260
+ if (isset($_availableOptions[$option->attribute_id]) && isset($_availableOptions[$option->attribute_id][strtolower($option->label)]))
261
+ {
262
+ $value = $_availableOptions[$option->attribute_id][strtolower($option->label)];
263
+ }
264
+
265
+
266
+ if ($option->type == 'multiselect')
267
+ {
268
+ if(!isset($additional_attributes->single_data[$i]->value)){
269
+ $additional_attributes->single_data[$i]->value = array();
270
+ }
271
+
272
+ array_push($additional_attributes->single_data[$i]->value, $value);
273
+ }
274
+ else
275
+ {
276
+ $additional_attributes->single_data[$i]->value = $value;
277
+ }
278
+
279
+ $i++;
280
+ }
281
+ }
282
+
283
+ if ($i>0)
284
+ {
285
+ $productData->additional_attributes = $additional_attributes;
286
+ }
287
+ else
288
+ {
289
+ unset($productData->additional_attributes);
290
+ }
291
+
292
+ }
293
+ return $productData;
294
+ }
295
+
296
+ protected function newOptions($productData)
297
+ {
298
+ $_attributesOptions = array();
299
+
300
+ if (property_exists($productData, 'additional_attributes') && is_array($productData->additional_attributes)) {
301
+
302
+ foreach($productData->additional_attributes as $_attribute) {
303
+ if (($_attribute->type == 'select' || $_attribute->type == 'multiselect') && $_attribute->value == "-1")
304
+ {
305
+ if (isset($_attributesOptions[$_attribute->attribute_id]))
306
+ {
307
+ $_attributesOptions[$_attribute->attribute_id][] = $_attribute->label;
308
+ }
309
+ else
310
+ {
311
+ $_attributesOptions[$_attribute->attribute_id] = array($_attribute->label);
312
+ }
313
+ }
314
+ }
315
+ }
316
+
317
+ return $_attributesOptions;
318
+ }
319
+
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);
332
+ $productData->categories = $productData->category_ids;
333
+ }
334
+
335
+ return $productData;
336
+ }
337
+
338
+ public function getWebsiteId($store=null)
339
+ {
340
+ return $this->getDefaultStore($store)->getWebsiteId();
341
+ }
342
+
343
+
344
+ public function updateProductData($productId, $productData, $store = null, $identifierType = 'id'){
345
+
346
+ $store = $this->currentStoreCode($store);
347
+ try {
348
+ $storeId = Mage::app()->getStore($store)->getId();
349
+ }
350
+ catch (Mage_Core_Model_Store_Exception $e) {
351
+ throw new Mage_Api_Exception('store_not_exists', null);
352
+ }
353
+
354
+ $_loadedProduct = Mage::helper('catalog/product')->getProduct($productId, $storeId, $identifierType);
355
+
356
+ if (!$_loadedProduct->getId())
357
+ {
358
+ throw new Mage_Api_Exception('product_not_exists', null);
359
+ }
360
+
361
+ if (property_exists($productData, 'category_ids'))
362
+ {
363
+ $productData->category_ids = is_array($productData->category_ids) ? $productData->category_ids : array($productData->category_ids);
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
  }
app/code/local/LinnSystems/LinnLiveConnect/Helper/Settings.php ADDED
@@ -0,0 +1,13 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class LinnSystems_LinnLiveConnect_Helper_Settings{
3
+ public function getVersion() {
4
+ return Mage::getConfig() -> getModuleConfig("LinnSystems_LinnLiveConnect") -> version;
5
+ }
6
+
7
+ public function getShortVersion() {
8
+ $version = explode('.', $this->getVersion());
9
+ return array_pop($version);
10
+ }
11
+ }
12
+
13
+ ?>
app/code/local/LinnSystems/LinnLiveConnect/Model/Api/V2.php CHANGED
@@ -1,1622 +1,1359 @@
1
  <?php
2
- class Settings {
3
- public static function getVersion() {
4
- return Mage::getConfig()->getModuleConfig("LinnSystems_LinnLiveConnect")->version;
5
- }
6
- public static function getShortVersion(){
7
- $version = explode('.',self::getVersion());
8
- return array_pop($version);
9
- }
10
- }
11
 
12
- class Mage_Catalog_Model_Product_Api_V2_LL extends Mage_Catalog_Model_Product_Api_V2{
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
13
 
14
- public function create($type, $set, $sku, $productData, $store = NULL){
15
- $tries = 0;
16
- $maxtries = 3;
17
- Mage::setIsDeveloperMode(true);
18
-
19
- do {
20
- $retry = false;
21
- try {
22
- return parent::create($type, $set, $sku, $productData, $store);
23
- } catch (Exception $e) {
24
-
25
- if ($tries < $maxtries && $e->getMessage()=='SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction') {
26
- $retry = true;
27
- sleep(1);
28
- }else{
29
- throw $e;
30
- }
31
- $tries++;
32
- }
33
-
34
- } while ($retry);
35
- }
36
-
37
- public function update($productId, $productData, $store = null, $identifierType = null){
38
- $tries = 0;
39
- $maxtries = 3;
40
- Mage::setIsDeveloperMode(true);
41
-
42
- do {
43
- $retry = false;
44
- try {
45
- return parent::update($productId, $productData, $store, $identifierType);
46
- } catch (Exception $e) {
47
-
48
- if ($tries < $maxtries && $e->getMessage()=='SQLSTATE[40001]: Serialization failure: 1213 Deadlock found when trying to get lock; try restarting transaction') {
49
- $retry = true;
50
- sleep(1);
51
- }else{
52
- throw $e;
53
- }
54
- $tries++;
55
- }
56
-
57
- } while ($retry);
58
- }
59
  }
60
 
61
  class LinnSystems_LinnLiveConnect_Model_Api_V2 {
62
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
 
64
- public function getProductStoreURL($version, $productId, $store = null, $identifierType = 'id') {
65
- $worker = Factory::createWorker($version);
66
- return $worker->getProductStoreURL($productId, $store, $identifierType);
67
- }
68
-
69
- public function configurableProduct($version, $set, $sku, $reindex, $productData, $productsSet, $attributesSet, $store=null)
70
- {
71
- $worker = Factory::createWorker($version);
72
- return $worker->configurableProduct($set, $sku, $reindex, $productData, $productsSet, $attributesSet, $store);
73
- }
74
-
75
- public function updateConfigurableProduct($version, $productId, $reindex, $productData, $productsSet, $attributesSet, $store=null, $identifierType='id')
76
- {
77
- $worker = Factory::createWorker($version);
78
- return $worker->updateConfigurableProduct($productId, $reindex, $productData, $productsSet, $attributesSet, $store, $identifierType);
79
- }
80
-
81
- public function storesList($version)
82
- {
83
- $worker = Factory::createWorker($version);
84
- return $worker->storesList();
85
- }
86
-
87
- public function getStoreCode($version, $store=null)
88
- {
89
- $worker = Factory::createWorker($version);
90
- return $worker->getStoreCode($store);
91
- }
92
-
93
- public function deleteAssigned($version, $productId, $store=null, $identifierType='id')
94
- {
95
- $worker = Factory::createWorker($version);
96
- return $worker->deleteAssigned($productId, $store, $identifierType);
97
- }
98
-
99
- public function assignImages($version, $productImages)
100
- {
101
- $worker = Factory::createWorker($version);
102
- return $worker->assignImages($productImages);
103
- }
104
-
105
- public function productList($version, $page, $perPage, $filters = null, $store = null)
106
- {
107
- $worker = Factory::createWorker($version);
108
- return $worker->productList($page, $perPage, $filters, $store);
109
- }
110
-
111
- public function productAttributeOptions($version, $setId)
112
- {
113
- $worker = Factory::createWorker($version);
114
- return $worker->productAttributeOptions($setId);
115
- }
116
-
117
- public function update($version, $productId, $productData, $store = null, $identifierType = 'id')
118
- {
119
- $worker = Factory::createWorker($version);
120
- return $worker->update($productId, $productData, $store, $identifierType);
121
- }
122
-
123
- public function create($version, $type, $set, $sku, $productData, $store = null)
124
- {
125
- $worker = Factory::createWorker($version);
126
- return $worker->create($type, $set, $sku, $productData, $store);
127
- }
128
-
129
- public function updatePriceBulk($version, $data, $store = null, $identifierType = 'id')
130
- {
131
- $worker = Factory::createWorker($version);
132
- return $worker->updatePriceBulk($data, $store, $identifierType);
133
- }
134
-
135
- public function getGeneralInfo($version)
136
- {
137
- $worker = Factory::createWorker($version);
138
- return $worker->getGeneralInfo();
139
- }
140
-
141
-
142
  }
143
 
144
  class Factory {
145
 
146
- private static function _checkVersion($version)
147
- {
148
- $version = intval($version);
149
 
150
- if ($version == 0) throw new Mage_Api_Exception('version_not_specified');
151
- if (Settings::getShortVersion() < $version ) throw new Mage_Api_Exception('wrong_version');
152
- }
153
 
154
- public static function createWorker($version)
155
- {
156
- self::_checkVersion($version);
 
157
 
158
- if (Mage::GetEdition() == Mage::EDITION_COMMUNITY)
159
- {
160
- return new LinnLiveCommunity();
161
- }
162
- else if (Mage::GetEdition() == Mage::EDITION_ENTERPRISE)
163
- {
164
- return new LinnLiveEnterprise();
165
- }
 
166
 
167
- throw new Mage_Api_Exception('unsupported_edition');
168
- }
169
  }
170
 
171
  class LinnLiveMain extends Mage_Core_Model_Abstract {
172
 
 
173
 
174
- protected $_ignoredAttributes = array(
175
- 'created_at',
176
- 'updated_at',
177
- 'category_ids',
178
- 'required_options',
179
- 'old_id',
180
- 'url_key',
181
- 'url_path',
182
- 'has_options',
183
- 'image_label',
184
- 'small_image_label',
185
- 'thumbnail_label',
186
- 'image',
187
- 'small_image',
188
- 'thumbnail',
189
- 'options_container',
190
- 'entity_id',
191
- 'entity_type_id',
192
- 'attribute_set_id',
193
- 'type_id',
194
- 'sku',
195
- 'name',
196
- 'status',
197
- 'stock_item',
198
- 'description',
199
- );
200
-
201
- protected $_permittedAttributes = array (
202
- 'select',
203
- 'multiselect',
204
- 'text',
205
- 'textarea',
206
- 'date',
207
- 'price'
208
- );
209
-
210
-
211
- private function _prepareConfigurableData($productsSet, $attributesSet, $isUpdate)
212
- {
213
- $assignedProductsArray = $this->_objectToArray(
214
- $this->_createProductsData($productsSet)
215
- );
216
-
217
- $_newAttributeOptions = $this->_newConfigurableOptions($assignedProductsArray);
218
- if (count($_newAttributeOptions) > 0)
219
- {
220
- $this->_checkAssignedProductsOptions(
221
- $this->_createOptions($_newAttributeOptions),
222
- $assignedProductsArray
223
- );
224
- }
225
 
226
-
227
- if (!is_array($attributesSet))
228
- {
229
- $attributesSet = array($attributesSet);
230
- }
231
-
232
- $attributesSetArray = $this->_prepareAttributesData(
233
- $this->_objectToArray($attributesSet),
234
- $assignedProductsArray
235
- );
236
-
237
- foreach($attributesSetArray as $key=>$value)
238
- {
239
- $attributesSetArray[$key]["id"] = NULL;
240
- $attributesSetArray[$key]["position"] = NULL;
241
- $attributesSetArray[$key]["store_label"] = $value['frontend_label'];
242
- //$attributesSetArray[$key]["use_default"] = 0;
243
-
244
- if($isUpdate==false){
245
- //check if attribute exists and available
246
- $checkAttribute = Mage::getModel('catalog/resource_eav_attribute')->loadByCode('catalog_product',$attributesSetArray[$key]["attribute_code"]);
247
-
248
- if(!$checkAttribute->getId() || !$this->_isConfigurable($checkAttribute)){
249
- 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.');
250
- }
251
- }
252
-
253
- }
254
- return array($assignedProductsArray, $attributesSetArray);
255
- }
256
 
257
-
258
- private function _isConfigurable($attribute){
259
- $isConfigurable = 0;
260
 
261
- if(isset($attribute['is_global']) && $attribute['is_global']){
262
- $attribute['scope'] = 'global';
263
- }
 
264
 
265
- if (($attribute['scope'] == 'global') && ($attribute['is_configurable']))
266
- {
267
- if(is_array($attribute['apply_to']) && sizeof($attribute['apply_to'])){
268
- if (in_array('simple', $attribute['apply_to'])) {
269
- $isConfigurable = 1;
270
- }
271
- }elseif(is_string($attribute['apply_to']) && strlen($attribute['apply_to'])){
272
- if(strpos($attribute['apply_to'],'simple')!==false){
273
- $isConfigurable = 1;
274
- }
275
- }else{
276
- $isConfigurable = 1;
277
- }
278
- }
279
- return $isConfigurable;
280
- }
281
-
282
- private function _checkAssignedProductsOptions($availableOptions, & $assignedProductsArray)
283
- {
284
- foreach ($assignedProductsArray as $id => $productOptions)
285
- {
286
- foreach($productOptions as $index => $option)
287
- {
288
- if (isset($availableOptions[$option['attribute_id']][strtolower($option['label'])]))
289
- {
290
- $assignedProductsArray[$id][$index]['value_index'] = $availableOptions[$option['attribute_id']][strtolower($option['label'])];
291
- }
292
- }
293
- }
294
- }
295
 
296
- protected function _createOptions($newOptions)
297
- {
298
- $installer = new Mage_Eav_Model_Entity_Setup('core_setup');
299
- $attributeApi = Mage::getModel('catalog/product_attribute_api');
300
- $helperCatalog = Mage::helper('catalog');
301
 
302
- $installer->startSetup();
 
 
 
 
303
 
304
- $attributesList = array();
 
 
305
 
306
- foreach($newOptions as $attribute_id=>$options)
307
- {
308
- $aOption = array();
309
- $aOption['attribute_id'] = $attribute_id;
310
- $attributesList[] = $attribute_id;
311
 
312
- $i=0;
313
- foreach($options as $option)
314
- {
315
- $optionTitle = $helperCatalog->stripTags($option);
316
 
317
- $aOption['value']['option'.$i][0] = $optionTitle;
318
- $i++;
319
- }
320
- $installer->addAttributeOption($aOption);
321
- }
322
- $installer->endSetup();
323
-
324
- Mage::app()->cleanCache(array(Mage_Core_Model_Translate::CACHE_TAG));
325
-
326
-
327
- $currentOptions = array();
328
- $attributeApi = Mage::getModel('catalog/product_attribute_api');
329
- foreach($attributesList as $attribute_id)
330
- {
331
- if (!isset($currentOptions[$attribute_id]))
332
- $currentOptions[$attribute_id] = array();
333
-
334
- $attributeOptions = $attributeApi->options($attribute_id);
335
-
336
- foreach ($attributeOptions as $opts)
337
- {
338
- $label = strtolower($opts['label']);
339
- $optionId = $opts['value'];
340
- if (!isset($currentOptions[$attribute_id][$label]))
341
- $currentOptions[$attribute_id][$label] = $optionId;
342
- else {
343
- $oldId = $currentOptions[$attribute_id][$label];
344
- if ($oldId > $optionId)
345
- {
346
- $attributeApi->removeOption($attribute_id, $oldId);
347
- $currentOptions[$attribute_id][$label] = $optionId;
348
- }
349
- else
350
- {
351
- $attributeApi->removeOption($attribute_id, $optionId);
352
- }
353
- }
354
- }
355
- }
356
 
357
- return $currentOptions;
358
- }
359
-
360
- private function _newConfigurableOptions($assignedProductsArray)
361
- {
362
- $_attributesOptions = array();
363
- foreach ($assignedProductsArray as $id => $productOptions)
364
- {
365
- foreach($productOptions as $option)
366
- {
367
- if (isset($option['value_index']) && $option['value_index'] == '-1')
368
- {
369
- if (isset($_attributesOptions[$option['attribute_id']]))
370
- {
371
- $_attributesOptions[$option['attribute_id']][] = $option['label'];
372
- }
373
- else
374
- {
375
- $_attributesOptions[$option['attribute_id']] = array($option['label']);
376
- }
377
- }
378
- }
379
- }
380
- return $_attributesOptions;
381
- }
382
-
383
- protected function _newOptions($productData)
384
- {
385
- $_attributesOptions = array();
386
-
387
- if (property_exists($productData, 'additional_attributes')) {
388
- $_attributes = $productData->additional_attributes;
389
- if (is_array($_attributes)) {
390
- foreach($_attributes as $_attribute) {
391
- if (($_attribute->type == 'select' || $_attribute->type == 'multiselect') && $_attribute->value == "-1")
392
- {
393
- if (isset($_attributesOptions[$_attribute->attribute_id]))
394
- {
395
- $_attributesOptions[$_attribute->attribute_id][] = $_attribute->label;
396
- }
397
- else
398
- {
399
- $_attributesOptions[$_attribute->attribute_id] = array($_attribute->label);
400
- }
401
- }
402
- }
403
- }
404
- else
405
- {
406
- if (($_attributes->type == 'select' || $_attributes->type == 'multiselect') && $_attributes->value == "-1")
407
- {
408
- if (isset($_attributesOptions[$_attributes->attribute_id]))
409
- {
410
- $_attributesOptions[$_attributes->attribute_id][] = $_attributes->label;
411
- }
412
- else
413
- {
414
- $_attributesOptions[$_attributes->attribute_id] = array($_attributes->label);
415
- }
416
- }
417
- }
418
 
419
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
420
 
421
- return $_attributesOptions;
422
- }
423
-
424
- private function _containsOption($attributeOption, $option)
425
- {
426
- foreach ($attributeOption as $inArrayOption)
427
- if ($inArrayOption['value_index'] == $option['value_index']) return true;
428
-
429
- return false;
430
- }
431
-
432
- private function _prepareAttributesData($attributesSetArray, $assignedProductsArray)
433
- {
434
-
435
- $_attributesOptions = array();
436
- foreach ($assignedProductsArray as $id => $productOptions)
437
- {
438
- foreach($productOptions as $option)
439
- {
440
- if (isset($_attributesOptions[$option['attribute_id']]) && !$this->_containsOption($_attributesOptions[$option['attribute_id']], $option))
441
- {
442
- $_attributesOptions[$option['attribute_id']][] = $option;
443
- }
444
- else if (!isset($_attributesOptions[$option['attribute_id']]))
445
- {
446
- $_attributesOptions[$option['attribute_id']] = array();
447
- $_attributesOptions[$option['attribute_id']][] = $option;
448
- }
449
- }
450
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
451
 
452
- foreach($attributesSetArray as $key => $attribute)
453
- {
454
- if (isset($_attributesOptions[$attribute['attribute_id']])){
455
- $attributesSetArray[$key]['values'] = $_attributesOptions[$attribute['attribute_id']];
456
- }
457
- }
458
 
459
- return $attributesSetArray;
460
- }
461
-
462
- private function _updateConfigurable($store, $productId, $assignedProducts, $assignedAttributes, $identifierType, $isUpdate=false, $reindex=true)
463
- {
464
- $magentoVer = $this->_getCurrentVersion();
465
- if ($magentoVer == 162)
466
- {
467
- $store = Mage::app()->getStore($store)->getId();
468
- }else{
469
- $store = NULL;
470
- }
471
 
472
- $product = Mage::helper('catalog/product')->getProduct($productId, $store, $identifierType);
473
-
474
- $product->setConfigurableProductsData($assignedProducts);
475
 
476
- if ($isUpdate == false) {
477
- $product->setConfigurableAttributesData($assignedAttributes);
478
- $product->setCanSaveConfigurableAttributes(true);
479
- }
480
-
481
-
482
 
483
- try {
484
- $result = $product->save();
485
- }
486
- catch (Exception $e) {
487
- throw new Mage_Api_Exception('configurable_creating_error', $e->getMessage());
488
- }
 
489
 
490
- if ($reindex === true)
491
- {
492
- try {
493
- $indexer = Mage::getSingleton('index/indexer');
494
- $process = $indexer->getProcessByCode('catalog_product_price');
495
- $process->reindexEverything();
496
- }
497
- catch (Mage_Core_Exception $e) {
498
- throw new Mage_Api_Exception('configurable_creating_error', $e->getMessage());
499
- }
500
- }
501
 
502
- return $result;
503
- }
 
 
 
 
504
 
505
- private function _createProductsData($productData)
506
- {
507
- $assignedProductsData = array();
508
 
509
- if (is_array($productData))
510
- {
511
- foreach ($productData as $product)
512
- {
513
- $assignedProductsData[$product->product_id] = array();
514
- $this->_fillAssignedProductValues($product, $assignedProductsData);
515
- }
516
- }
517
- else
518
- {
519
- $assignedProductsData[$productData->product_id] = array();
520
- $this->_fillAssignedProductValues($product, $assignedProductsData);
521
- }
522
 
 
 
 
523
 
524
- return $assignedProductsData;
525
- }
 
 
 
 
526
 
527
- private function _fillAssignedProductValues(& $product, & $assignedProductsData)
528
- {
529
- if (is_array($product->values))
530
- {
531
- foreach ($product->values as $productValue)
532
- {
533
- $assignedProductsData[$product->product_id][] = $productValue;
534
- }
535
- }
536
- else
537
- {
538
- $assignedProductsData[$product->product_id][] = $product->values;
539
- }
540
- }
541
 
542
- private function _updateConfigurableQuantity( & $productData)
543
- {
544
- $productData = $this->_updateProperties($productData);
545
 
546
- if (!property_exists($productData, 'stock_data'))
547
- {
548
- $productData->stock_data = new stdClass();
549
- }
550
 
551
- $productData->stock_data->manage_stock = 1;
552
- $productData->stock_data->is_in_stock = 1;
553
- }
554
 
555
- private function _updateProperties($productData)
556
- {
557
- if (property_exists($productData, 'status')) {
558
- $productData->status = ($productData->status == 1) ? Mage_Catalog_Model_Product_Status::STATUS_ENABLED : Mage_Catalog_Model_Product_Status::STATUS_DISABLED;
559
- }
560
 
561
- if (property_exists($productData, 'stock_data') && property_exists($productData->stock_data, 'qty')) {
562
- $productData->stock_data->qty = intval($productData->stock_data->qty);
563
- $productData->stock_data->is_in_stock = 1;
564
- $productData->stock_data->manage_stock = 1;
565
- }
566
- return $productData;
567
- }
568
-
569
- //TODO: use helper func
570
- private function _objectToArray( $result )
571
- {
572
- $array = array();
573
- foreach ($result as $key=>$value)
574
- {
575
- if (is_object($value) || is_array($value))
576
- {
577
- $array[$key]=$this->_objectToArray($value);
578
- }
579
- else
580
- {
581
- $array[$key]=$value;
582
- }
583
- }
584
- return $array;
585
- }
586
-
587
- private function _getCurrentVersion()
588
- {
589
- $verInfo = Mage::getVersionInfo();
590
-
591
- return intval($verInfo['major'].$verInfo['minor'].$verInfo['revision']);
592
- }
593
-
594
- private function _productImages($attributesList)
595
- {
596
- $_images = array();
597
-
598
- if (is_array($attributesList) && count($attributesList) > 0 && isset($attributesList['media_gallery']))
599
- {
600
- $small = empty($attributesList['small_image']) ? false : $attributesList['small_image'];
601
- $base = empty($attributesList['image']) ? false : $attributesList['image'];
602
- $thumb = empty($attributesList['thumbnail']) ? false : $attributesList['thumbnail'];
603
-
604
- foreach($attributesList['media_gallery']['images'] as $key=>$value)
605
- {
606
- $newImage = array();
607
- $newImage['file'] = $value['file'];
608
- $newImage['label'] = $value['label'];
609
- $newImage['disabled'] = $value['disabled'] ? true : false;
610
-
611
- $newImage['small_image'] = $small == $newImage['file'];
612
- $newImage['image'] = $base == $newImage['file'];
613
- $newImage['thumbnail'] = $thumb == $newImage['file'];
614
-
615
- $_images[] = $newImage;
616
- }
617
- }
618
 
619
- return $_images;
620
- }
621
-
622
- private function _removeIgnoredAttributes($attributesList)
623
- {
624
- $_preparedAttributes = array();
625
- if (is_array($attributesList) && count($attributesList) > 0)
626
- {
627
- foreach($attributesList as $key=>$value)
628
- {
629
- if (!in_array($key, $this->_ignoredAttributes) && !is_array($value))
630
- $_preparedAttributes[]= array('key' => $key, 'value' => $value);
631
- }
632
- }
633
 
634
- return $_preparedAttributes;
635
- }
636
 
637
- private function _currentStoreCode($store=null)
638
- {
639
- if ($store != null) {
640
- return $store;
641
- }
642
- return $this->_getStore()->getCode();
643
- }
644
-
645
- private function _getProductBySku($sku)
646
- {
647
- if ($sku) {
648
- $product = Mage::getModel('catalog/product');
649
- $productId = $product->getIdBySku((string)$sku);
650
- if ($productId) {
651
- $product->load($productId);
652
- if ($product->getId()) {
653
- return $product;
654
- }
655
- }
656
- }
657
- }
658
 
659
- private function _getStore($storeCode=null)
660
- {
661
- if (Mage::app()->isSingleStoreMode()) {
662
- return Mage::app()->getWebsite(true)->getDefaultStore();
663
- }
664
 
665
- $mageRunCode = isset($_SERVER['MAGE_RUN_CODE']) ? $_SERVER['MAGE_RUN_CODE'] : '';
666
- $mageRunType = isset($_SERVER['MAGE_RUN_TYPE']) ? $_SERVER['MAGE_RUN_TYPE'] : 'store';
 
 
 
 
 
 
 
 
 
 
 
 
 
667
 
668
- if ($storeCode != null) {
669
- return Mage::getModel('core/store')->load( $storeCode, 'code');
670
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
671
 
672
- if ($mageRunType == 'store') {
673
- if (!empty($mageRunCode))
674
- {
675
- return Mage::getModel('core/store')->load( $mageRunCode, 'code');
676
- }
677
- } else {
678
- if ($mageRunType == 'website') {
679
- $websiteCode = empty($mageRunCode) ? '' : $mageRunCode;
680
- } else {
681
- $websiteCode = empty($mageRunType) ? '' : $mageRunType;
682
- }
683
-
684
- if (!empty($websiteCode))
685
- {
686
- $currentWebSite = Mage::getModel('core/website')->load( $websiteCode, 'code');
687
- $defaultStore = $currentWebSite->getDefaultStore();
688
- if (isset($defaultStore)){
689
- return $defaultStore;
 
 
 
690
  }
691
- }
692
- }
693
 
 
694
 
695
- return Mage::app()->getWebsite(true)->getDefaultStore();//Mage::app()->getStore();
696
- }
697
 
698
- private function _getWebsiteId($store=null)
699
- {
700
- return array($this->_getStore($store)->getWebsiteId());
701
- }
702
 
703
- private function _productAttributeInfo($attribute_id, $attributeAPI)
704
- {
705
- $model = Mage::getResourceModel('catalog/eav_attribute')->setEntityTypeId(Mage::getModel('eav/entity')->setType('catalog_product')->getTypeId());
 
706
 
707
- $model->load($attribute_id);
 
 
 
 
708
 
709
- if (!$model->getId()) {
710
- throw new Mage_Api_Exception('attribute_not_exists');
711
- }
712
 
713
- if ($model->isScopeGlobal()) {
714
- $scope = 'global';
715
- } elseif ($model->isScopeWebsite()) {
716
- $scope = 'website';
717
- } else {
718
- $scope = 'store';
719
- }
720
 
721
- $result = array(
722
- 'attribute_id' => $model->getId(),
723
- 'attribute_code' => $model->getAttributeCode(),
724
- 'frontend_input' => $model->getFrontendInput(),
725
- 'default_value' => $model->getDefaultValue(),
726
- 'is_unique' => $model->getIsUnique(),
727
- 'is_required' => $model->getIsRequired(),
728
- 'apply_to' => $model->getApplyTo(),
729
- 'is_configurable' => $model->getIsConfigurable(),
730
- 'is_searchable' => $model->getIsSearchable(),
731
- 'is_visible_in_advanced_search' => $model->getIsVisibleInAdvancedSearch(),
732
- 'is_comparable' => $model->getIsComparable(),
733
- 'is_used_for_promo_rules' => $model->getIsUsedForPromoRules(),
734
- 'is_visible_on_front' => $model->getIsVisibleOnFront(),
735
- 'used_in_product_listing' => $model->getUsedInProductListing(),
736
- 'scope' => $scope,
737
- );
738
-
739
- // set options
740
- $options = $attributeAPI->options($model->getId());
741
- // remove empty first element
742
- if ($model->getFrontendInput() != 'boolean') {
743
- array_shift($options);
744
- }
745
 
746
- if (count($options) > 0) {
747
- $result['options'] = $options;
748
- }
749
 
750
- return $result;
751
- }
752
-
753
- //Fix for buggy associativeArray implementation
754
- private function _fixAttributes($productData)
755
- {
756
- $_newAttributeOptions = $this->_newOptions($productData);
757
- $_availableOptions = array();
758
- if (count($_newAttributeOptions) > 0)
759
- {
760
- $_availableOptions = $this->_createOptions($_newAttributeOptions);
761
- }
762
 
763
- if (property_exists($productData, 'additional_attributes')) {
764
- $tmpAttr = $productData->additional_attributes;
765
- if (count($tmpAttr) == 0)
766
- {
767
- unset($productData->additional_attributes);
768
- return $productData;
769
- }
770
-
771
- if (is_array($tmpAttr))
772
- {
773
- foreach ($tmpAttr as $option) {
774
- $code = $option->code;
775
- if ( ($option->type == 'multiselect') && (is_array($productData->$code) == false) )
776
- {
777
- $productData->$code = array();
778
- }
779
- if (isset($_availableOptions[$option->attribute_id][strtolower($option->label)]))
780
- {
781
- if ($option->type == 'multiselect')
782
- {
783
- array_push($productData->$code, $_availableOptions[$option->attribute_id][strtolower($option->label)]);
784
- }
785
- else
786
- {
787
- $productData->$code = $_availableOptions[$option->attribute_id][strtolower($option->label)];
788
- }
789
- }
790
- else
791
- {
792
- if ($option->type == 'multiselect')
793
- {
794
- array_push($productData->$code, $option->value);
795
- }
796
- else
797
- {
798
- $productData->$code = $option->value;
799
- }
800
- }
801
-
802
- }
803
- }
804
- else
805
- {
806
- $code = $tmpAttr->code;
807
- if (isset($_availableOptions[$tmpAttr->attribute_id][strtolower($tmpAttr->label)]))
808
- $productData->$code = $_availableOptions[$tmpAttr->attribute_id][strtolower($tmpAttr->label)];
809
- else
810
- $productData->$code = $tmpAttr->value;
811
- }
812
- }
813
 
814
- unset($productData->additional_attributes);
815
-
816
- return $productData;
817
- }
818
-
819
-
820
- protected function reindexSingleProduct($product){
821
- /* $indexer = Mage::getSingleton('index/indexer');
822
- $indexer->lockIndexer();
823
- $indexer->unlockIndexer(); */
824
- $event = Mage::getSingleton('index/indexer')->logEvent( $product, $product->getResource()->getType(), Mage_Index_Model_Event::TYPE_SAVE, false);
825
- Mage::getSingleton('index/indexer')->getProcessByCode('catalog_url')->setMode(Mage_Index_Model_Process::MODE_REAL_TIME)->processEvent($event);
826
- }
827
-
828
- protected function disableIndexing(){
829
- $processes = Mage::getSingleton('index/indexer')->getProcessesCollection();
830
- $processes->walk('setMode', array(Mage_Index_Model_Process::MODE_MANUAL));
831
- $processes->walk('save');
832
- }
833
-
834
- protected function enableIndexing(){
835
- $processes = Mage::getSingleton('index/indexer')->getProcessesCollection();
836
- $processes->walk('reindexAll');
837
- $processes->walk('setMode', array(Mage_Index_Model_Process::MODE_REAL_TIME));
838
- $processes->walk('save');
839
- }
840
-
841
- /*
842
- * Helper for productList
843
- $helper = Mage::helper('api');
844
- $helper->v2AssociativeArrayUnpacker($data);
845
- Mage::helper('api')->toArray($data);
846
-
847
- */
848
- private function _convertFiltersToArray($filters) {
849
- $arrayParams = array(
850
- 'nin',
851
- 'in',
852
- );
853
-
854
- $preparedFilters = array();
855
-
856
- if (isset($filters->filter)) {
857
- $preparedFilters = $filters->filter;
858
- }
859
 
860
- if (isset($filters->complex_filter)) {
 
 
 
861
 
862
- foreach ($filters->complex_filter as $idx=>$data) {
863
- if (is_object($data->value)) {
864
- //1.8
865
- $field = $data->key;
866
- $opts = $data->value;
867
 
868
- } else {
869
- //1.7
870
- $field = $idx;
871
- $opts = $data;
872
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
873
 
874
- $value = (in_array($opts->key, $arrayParams)) ? explode(',', $opts->value) : $opts->value;
875
- $preparedFilters[$field][$opts->key] = $value;
876
- }
877
- }
878
- return $preparedFilters;
879
- }
880
-
881
- protected function _log($message) {
882
- Mage::log(print_r($message, true), null, 'LinnLiveExt.log');
883
- }
884
-
885
- /*
886
- *
887
- * Public functions(API)
888
- *
889
- */
890
- public function configurableProduct($set, $sku, $reindex, $productData, $productsSet, $attributesSet, $store=null)
891
- {
892
-
893
- if (!$set || !$sku) {
894
- throw new Mage_Api_Exception('data_invalid');
895
- }
896
-
897
- $this->_updateConfigurableQuantity($productData);
898
- $productData = $this->_fixAttributes($productData);
899
-
900
- $store = $this->_currentStoreCode($store);
901
- $defaultStore = $this->_getStore();
902
-
903
- if (property_exists($productData, 'websites') === false && isset($defaultStore) ) {
904
- $productData->websites = array($defaultStore->getWebsiteId());
905
- }
906
 
907
- if (property_exists($productData, 'category_ids') && !is_array($productData->category_ids))
908
- {
909
- if (is_string($productData->category_ids)) {
910
- $productData->category_ids = array($productData->category_ids);
911
- }
912
- }
913
- else if (property_exists($productData, 'category_ids') === false)
914
- {
915
- $productData->category_ids = array();
916
- }
917
 
918
- $productData->categories = $productData->category_ids;
919
-
920
- //merge into 1?
921
- $productAPI = new Mage_Catalog_Model_Product_Api_V2_LL();
922
- $productId = $productAPI->create('configurable', $set, $sku, $productData, $store);
923
 
924
- list($assignedProductsArray, $attributesSetArray) = $this->_prepareConfigurableData($productsSet, $attributesSet, false);
925
- $this->_updateConfigurable($store, $productId, $assignedProductsArray, $attributesSetArray, 'id', false, $reindex);
926
 
927
- return $productId;
928
- }
929
 
930
- public function updateConfigurableProduct($productId, $reindex, $productData, $productsSet, $attributesSet, $store=null, $identifierType='id')
931
- {
 
 
932
 
933
- $this->_updateConfigurableQuantity($productData);
934
- $productData = $this->_fixAttributes($productData);
935
-
936
-
937
-
938
- $store = $this->_currentStoreCode($store);
939
 
940
- try {
941
- $storeId = Mage::app()->getStore($store)->getId();
942
- }
943
- catch (Mage_Core_Model_Store_Exception $e) {
944
- throw new Mage_Api_Exception('store_not_exists', null);
945
- }
946
 
947
- $_loadedProduct = Mage::helper('catalog/product')->getProduct($productId, $storeId, $identifierType);
 
948
 
949
- if (!$_loadedProduct->getId())
950
- {
951
- throw new Mage_Api_Exception('product_not_exists', null);
952
- }
953
 
954
- $_categoryIds = $_loadedProduct->getCategoryIds();
955
-
956
- if (property_exists($productData, 'category_ids'))
957
- {
958
 
959
- if (!is_array($productData->category_ids))
960
- {
961
- $productData->category_ids = array($productData->category_ids);
962
- }
 
 
 
 
963
 
964
- $productData->category_ids = array_merge($_categoryIds, $productData->category_ids);
965
- }
966
- else
967
- {
968
- $productData->category_ids = $_categoryIds;
969
- }
970
 
971
- $productData->category_ids = array_unique($productData->category_ids);
 
972
 
973
- if ( (property_exists($productData, 'removed_categories') === true) && (is_array($productData->removed_categories) === true) && (count($productData->removed_categories) > 0) )
974
- {
975
- $tmpCats = array();
976
- $productData->category_ids = array_diff($productData->category_ids, $productData->removed_categories);
977
- }
978
 
979
- $productData->categories = $productData->category_ids;
 
980
 
981
- if (property_exists($productData, 'add_to_websites') && $productData->add_to_websites === true)
982
- {
983
- $currentWebsites = $_loadedProduct->getWebsiteIds();
984
- $websiteId = $this->_getWebsiteId();
985
- $websiteId = $websiteId[0];
986
 
987
- if (in_array($websiteId, $currentWebsites) === false)
988
- {
989
- $currentWebsites[] = $websiteId;
990
- $productData->websites = $currentWebsites;
991
- }
992
- }
993
 
994
- $productAPI = new Mage_Catalog_Model_Product_Api_V2();
995
-
996
- $productAPI->update($productId, $productData, $store, $identifierType);
997
-
998
- list($assignedProductsArray, $attributesSetArray) = $this->_prepareConfigurableData($productsSet, $attributesSet, true);
999
- return $this->_updateConfigurable($store, $productId, $assignedProductsArray, $attributesSetArray, $identifierType, true, $reindex);
1000
- }
1001
-
1002
- public function getGeneralInfo(){
1003
- $config = Mage::getStoreConfig("api/config");
1004
- $verInfo = Mage::getVersionInfo();
1005
-
1006
- $result = array(
1007
- 'llc_ver' => Settings::getVersion(),
1008
- 'magento_ver' => trim("{$verInfo['major']}.{$verInfo['minor']}.{$verInfo['revision']}" . ($verInfo['patch'] != '' ? ".{$verInfo['patch']}" : ""). "-{$verInfo['stability']}{$verInfo['number']}", '.-'),
1009
- 'php_ver' => phpversion(),
1010
- 'api_config' => $config
1011
- );
1012
-
1013
- return $result;
1014
- }
1015
-
1016
- public function storesList()
1017
- {
1018
- return ($this->_getCurrentVersion() >= 160);
1019
- }
1020
-
1021
- public function getStoreCode($store=null)
1022
- {
1023
- return $this->_currentStoreCode($store);
1024
- }
1025
-
1026
- public function deleteAssigned($productId, $store=null, $identifierType='id')
1027
- {
1028
- $store = $this->_currentStoreCode($store);
1029
-
1030
- try {
1031
- $storeId = Mage::app()->getStore($store)->getId();
1032
- }
1033
- catch (Mage_Core_Model_Store_Exception $e) {
1034
- throw new Mage_Api_Exception('store_not_exists', null);
1035
- }
1036
 
1037
- $_loadedProduct = Mage::helper('catalog/product')->getProduct($productId, $storeId, $identifierType);
 
1038
 
1039
- if (!$_loadedProduct->getId())
1040
- {
1041
- throw new Mage_Api_Exception('product_not_exists', null);
1042
- }
1043
 
 
 
1044
 
1045
- $currentWebsites = $_loadedProduct->getWebsiteIds();
1046
- $websiteId = $this->_getWebsiteId($store);
1047
- $websiteId = $websiteId[0];
 
 
 
1048
 
1049
- $newWebsiteIds = array();
1050
 
1051
- if (in_array($websiteId, $currentWebsites) === true)
1052
- {
1053
- for ($i = 0; $i < count($currentWebsites); $i++)
1054
- {
1055
- if ($currentWebsites[$i] != $websiteId)
1056
- {
1057
- $newWebsiteIds[] = $currentWebsites[$i];
1058
- }
1059
- }
1060
 
1061
- $_loadedProduct->setWebsiteIds($newWebsiteIds);
1062
 
1063
- $_loadedProduct->save();
1064
- }
1065
 
1066
- return true;
1067
- }
1068
-
1069
- public function assignImages($productImages)
1070
- {
1071
- $store = $this->_currentStoreCode(null);
1072
-
1073
- foreach($productImages as $imageData)
1074
- {
1075
- $productId = intval($imageData->product_id);
1076
- if ($productId < 1) {
1077
- throw new Mage_Api_Exception('product_not_exists', null);
1078
- }
1079
-
1080
- $product = Mage::helper('catalog/product')->getProduct($productId, $store, 'id');
1081
-
1082
- $images = $imageData->images;
1083
-
1084
- $baseImageExist = false;
1085
- foreach($images as $image)
1086
- {
1087
- if (is_array($image->types) && in_array('image', $image->types))
1088
- {
1089
- $baseImageExist = true;
1090
- }
1091
- }
1092
-
1093
- if ($baseImageExist == false && count($images) > 0)
1094
- {
1095
- $images[0]->types = array('image');
1096
- }
1097
-
1098
- reset($images);
1099
-
1100
- foreach($images as $image)
1101
- {
1102
- $catalogProductDir = Mage::getBaseDir('media') . DS . 'catalog/product';
1103
- $filePath = $catalogProductDir.$image->image_name;
1104
-
1105
- if (is_array($image->types) && count($image->types) > 0)
1106
- {
1107
- $imageTypes = $image->types;
1108
- }
1109
- else
1110
- {
1111
- $imageTypes = "";
1112
- }
1113
-
1114
- try
1115
- {
1116
- $product->addImageToMediaGallery($filePath, $imageTypes, false, false);
1117
- }
1118
- catch (Exception $e) { }
1119
-
1120
- }
1121
-
1122
- $product->save();
1123
- }
1124
 
1125
- return true;
1126
- }
1127
-
1128
-
1129
- /*
1130
- * Implementation of catalogProductList because of bug in associativeArray.
1131
- * Extended to filter by category id too.
1132
- *
1133
- * Use 'entity_id' for product_id,
1134
- * 'type_id' instead of product type.
1135
- */
1136
- public function productList($page, $perPage, $filters = null, $store = null)
1137
- {
1138
- //get store
1139
- try {
1140
- $storeId = Mage::app()->getStore( $this->_currentStoreCode($store) )->getId();
1141
- }
1142
- catch (Mage_Core_Model_Store_Exception $e) {
1143
- throw new Mage_Api_Exception('store_not_exists', null);
1144
- }
1145
 
1146
- //prepare and convert filters to array
1147
- $preparedFilters = $this->_convertFiltersToArray($filters);
1148
- if (empty($preparedFilters)) {
1149
- throw new Mage_Api_Exception('filters_invalid', null);
1150
- }
1151
 
1152
- //load collection
1153
- $collection = Mage::getModel('catalog/product')->getCollection()->addStoreFilter($storeId);
1154
 
1155
- //filter collection by category if exists
1156
- if (isset($preparedFilters['category']) && is_string($preparedFilters['category']))
1157
- {
1158
- $_category = Mage::getModel('catalog/category')->load( intval($preparedFilters['category']) );
1159
 
1160
- if ($_category->getId()) {
1161
- $collection = $collection->addCategoryFilter($_category);
1162
- }
1163
 
1164
- unset($preparedFilters['category']);
1165
- }
 
 
 
 
1166
 
1167
- //add prepared filters to collection
1168
- try {
1169
- foreach ($preparedFilters as $field => $data) {
1170
- if(is_array($data)){
1171
- foreach ($data as $key => $value){
1172
- $collection->addFieldToFilter($field, array($key=>$value));
1173
- }
1174
- }else{
1175
- $collection->addFieldToFilter($field, $data);
1176
- }
1177
- }
1178
- }
1179
- catch (Mage_Core_Exception $e) {
1180
- throw new Mage_Api_Exception('filters_invalid', $e->getMessage());
1181
- }
1182
 
 
 
 
 
 
 
1183
 
1184
- if ($page == 1)
1185
- {
1186
- //TODO: limit page size
1187
- $count = $collection->count();
1188
- }
1189
- else
1190
- {
1191
- $count = 0;
1192
- $collection->setPageSize($perPage)->setCurPage($page);
1193
- }
1194
 
1195
- $result = array(
1196
- 'count'=>$count,
1197
- 'products'=>array()
1198
- );
1199
-
1200
- $_assignedIds = array();
1201
- $_fetchedIds = array();
1202
-
1203
- $i = 0;
1204
- foreach ($collection as $_product) {
1205
-
1206
- if ($i >= ($perPage * $page)) break;//TODO remove
1207
- $_loadedProduct = Mage::helper('catalog/product')->getProduct($_product->getId(), $storeId, 'id');
1208
-
1209
- $_allAttributes = $_loadedProduct->getData();
1210
-
1211
-
1212
- $_description = isset($_allAttributes['description']) ? $_allAttributes['description'] : '';
1213
-
1214
- $_productImages = $this->_productImages($_allAttributes);
1215
- $_productAttributes = $this->_removeIgnoredAttributes($_allAttributes);
1216
-
1217
- $_fetchedIds[] = $_loadedProduct->getId();
1218
-
1219
- $result['products'][$i] = array(
1220
- 'product_id' => $_loadedProduct->getId(),
1221
- 'sku' => $_loadedProduct->getSku(),
1222
- 'name' => $_loadedProduct->GetName(),
1223
- 'set' => $_loadedProduct->getAttributeSetId(),
1224
- 'type' => $_loadedProduct->getTypeId(),
1225
- 'price' => $_loadedProduct->getPrice(),
1226
- 'status' => $_loadedProduct->getStatus(),
1227
- 'description' => $_description,
1228
- 'category_ids' => $_loadedProduct->getCategoryIds(),
1229
- 'website_ids' => $_loadedProduct->getWebsiteIds(),
1230
- 'assigned_ids' => array(),
1231
- 'conf_attrib_ids' => array(),
1232
- 'images' => $_productImages,
1233
- 'attributes' => $_productAttributes,
1234
- );
1235
-
1236
- if ($_loadedProduct->getTypeId() == "configurable")
1237
- {
1238
- $_typeInstance = $_loadedProduct->getTypeInstance();
1239
- $result['products'][$i]['assigned_ids'] = $_typeInstance->getUsedProductIds();
1240
- foreach($_typeInstance->getConfigurableAttributes() as $attribute) {
1241
- $_prices = array();
1242
- foreach($attribute->getPrices() as $price)
1243
- {
1244
- $_prices[] = array(
1245
- 'value_index' => $price['value_index'],
1246
- 'is_fixed' => !$price['is_percent'],
1247
- 'price_diff' => $price['pricing_value'],
1248
- 'label' => $price['label'],
1249
- );
1250
- }
1251
-
1252
- $result['products'][$i]['conf_attrib_ids'][] = array(
1253
- 'code' => $attribute->getProductAttribute()->getAttributeCode(),
1254
- 'prices' => $_prices
1255
- );
1256
- }
1257
- $_assignedIds = array_merge($_assignedIds, $result['products'][$i]['assigned_ids']);
1258
- }
1259
-
1260
- $i++;
1261
- }
1262
 
1263
- $_absentIds = array_diff($_assignedIds, $_fetchedIds);
1264
-
1265
- if (count($_absentIds) > 0)
1266
- {
1267
- $collection = Mage::getModel('catalog/product')->getCollection()->addIdFilter($_absentIds);
1268
-
1269
- foreach ($collection as $_product) {
1270
- $_loadedProduct = Mage::helper('catalog/product')->getProduct($_product->getId(), $storeId, 'id');
1271
-
1272
- $_allAttributes = $_product->getData();
1273
-
1274
- $_description = isset($_allAttributes['description']) ? $_allAttributes['description'] : '';
1275
-
1276
- $_productImages = $this->_productImages($_allAttributes);
1277
- $_productAttributes = $this->_removeIgnoredAttributes($_allAttributes);
1278
-
1279
- $result['products'][] = array(
1280
- 'product_id' => $_loadedProduct->getId(),
1281
- 'sku' => $_loadedProduct->getSku(),
1282
- 'name' => $_loadedProduct->GetName(),
1283
- 'set' => $_loadedProduct->getAttributeSetId(),
1284
- 'type' => $_loadedProduct->getTypeId(),
1285
- 'price' => $_loadedProduct->getPrice(),
1286
- 'status' => $_loadedProduct->getStatus(),
1287
- 'description' => $_description,
1288
- 'category_ids' => $_loadedProduct->getCategoryIds(),
1289
- 'website_ids' => $_loadedProduct->getWebsiteIds(),
1290
- 'assigned_ids' => array(),
1291
- 'conf_attrib_ids' => array(),
1292
- 'images' => $_productImages,
1293
- 'attributes' => $this->_removeIgnoredAttributes($_loadedProduct->getData()),
1294
- );
1295
- }
 
 
1296
  }
1297
 
1298
- return $result;
1299
- }
1300
 
1301
- public function productAttributeOptions($setId)
1302
- {
1303
 
1304
- $result = array();
1305
 
1306
- $setId = intval($setId);
1307
- if ($setId <= 0) return $result;
1308
 
1309
- $attributeAPI = Mage::getModel('catalog/product_attribute_api');
1310
 
1311
- $items = $attributeAPI->items($setId);
 
1312
 
1313
- $attributes = Mage::getModel('catalog/product')->getResource()->loadAllAttributes();
 
 
 
 
 
1314
 
1315
- foreach ($items as $item) {
1316
- if (!isset($item['attribute_id']) || empty($item['attribute_id'])) continue;
1317
- $attributeId = intval($item['attribute_id']);
1318
- if ($attributeId <= 0) continue;
1319
 
1320
- $additionInfo = $this->_productAttributeInfo($attributeId, $attributeAPI);
1321
 
1322
- if (in_array($additionInfo['frontend_input'], $this->_permittedAttributes) && !in_array($additionInfo['attribute_code'], $this->_ignoredAttributes))
1323
- {
1324
 
1325
- $attribute = array(
1326
- 'attribute_id' => $additionInfo['attribute_id'],
1327
- 'code' => $additionInfo['attribute_code'],
1328
- 'type' => $additionInfo['frontend_input'],
1329
- 'required' => $additionInfo['is_required'],
1330
- 'scope' => $additionInfo['scope'],
1331
- 'can_config' => 0
1332
- );
1333
 
1334
- if ( ($additionInfo['frontend_input'] == 'select') || ($additionInfo['frontend_input'] == 'multiselect') ) {
1335
- if (isset($additionInfo['options'])) {
1336
 
1337
- if (sizeof($additionInfo['options']) && is_array($additionInfo['options'][0]['value'])) {
1338
- continue;//ignore attributes with multidimensional options
1339
- }
1340
- $attribute['attribute_options'] = $additionInfo['options'];
1341
- }
1342
-
1343
- $attribute['can_config'] = $this->_isConfigurable($additionInfo);
1344
- }
1345
 
1346
- $result[] = $attribute;
1347
- }
1348
- }
1349
 
1350
- return $result;
1351
- }
1352
 
1353
- public function update($productId, $productData, $store = null, $identifierType = 'id')
1354
- {
1355
- $store = $this->_currentStoreCode($store);
1356
- try {
1357
- $storeId = Mage::app()->getStore($store)->getId();
1358
- }
1359
- catch (Mage_Core_Model_Store_Exception $e) {
1360
- throw new Mage_Api_Exception('store_not_exists', null);
1361
- }
1362
 
1363
- $_loadedProduct = Mage::helper('catalog/product')->getProduct($productId, $storeId, $identifierType);
 
 
 
 
 
1364
 
1365
- if (!$_loadedProduct->getId())
1366
- {
1367
- throw new Mage_Api_Exception('product_not_exists', null);
1368
- }
1369
 
 
 
 
 
 
 
1370
 
1371
- $_categoryIds = $_loadedProduct->getCategoryIds();
1372
- if (property_exists($productData, 'category_ids'))
1373
- {
1374
- if (!is_array($productData->category_ids))
1375
- {
1376
- $productData->category_ids = array($productData->category_ids);
1377
- }
1378
 
1379
- $productData->category_ids = array_merge($_categoryIds, $productData->category_ids);
1380
- }
1381
- else
1382
- {
1383
- $productData->category_ids = $_categoryIds;
1384
- }
1385
 
1386
- $productData->category_ids = array_unique($productData->category_ids);
 
1387
 
1388
- if ( (property_exists($productData, 'removed_categories') === true) && (is_array($productData->removed_categories) === true) && (count($productData->removed_categories) > 0) )
1389
- {
1390
- $tmpCats = array();
1391
 
1392
- $productData->category_ids = array_diff($productData->category_ids, $productData->removed_categories);
1393
- }
1394
 
1395
- $productData->categories = $productData->category_ids;
1396
 
1397
- if (property_exists($productData, 'add_to_websites') && $productData->add_to_websites === true)
1398
- {
1399
- $currentWebsites = $_loadedProduct->getWebsiteIds();
1400
- $websiteId = $this->_getWebsiteId();
1401
- $websiteId = $websiteId[0];
1402
 
1403
- if (in_array($websiteId, $currentWebsites) === false)
1404
- {
1405
- $currentWebsites[] = $websiteId;
1406
- $productData->websites = $currentWebsites;
1407
- }
1408
- }
1409
 
1410
- $productData = $this->_updateProperties($productData);
 
 
 
 
 
1411
 
1412
- $productData = $this->_fixAttributes($productData);
1413
 
1414
- $productAPI = new Mage_Catalog_Model_Product_Api_V2();
1415
 
1416
- $result = $productAPI->update($productId, $productData, $store, $identifierType);
1417
 
1418
- return $result;
1419
- }
1420
 
1421
- public function create($type, $set, $sku, $productData, $store = null)
1422
- {
1423
- $product = $this->_getProductBySku($sku);
1424
- if ($product) {
1425
- return $product->getId();
1426
- }
1427
 
1428
- $store = $this->_currentStoreCode($store);
1429
 
1430
- $defaultStore = $this->_getStore();
1431
 
1432
- if (property_exists($productData, 'websites') === false && isset($defaultStore)) {
1433
- $productData->websites = array($defaultStore->getWebsiteId());
1434
- }
 
 
 
 
 
 
 
 
 
 
 
1435
 
1436
- if (property_exists($productData, 'category_ids') && !is_array($productData->category_ids)) {
1437
- if (is_string($productData->category_ids)){
1438
- $productData->category_ids = array($productData->category_ids);
 
 
 
 
 
 
 
 
 
 
1439
  }
1440
- }else if (property_exists($productData, 'category_ids') === false)
1441
- {
1442
- $productData->category_ids = array();
1443
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1444
 
1445
- $productData->categories = $productData->category_ids;
1446
 
1447
- $productData = $this->_updateProperties($productData);
 
1448
 
1449
- $productData = $this->_fixAttributes($productData);
 
 
 
1450
 
1451
- $productAPI = new Mage_Catalog_Model_Product_Api_V2_LL();
1452
-
1453
- return $productAPI->create($type, $set, $sku, $productData, $store);
1454
- }
1455
 
1456
- public function getProductStoreURL($productId, $store = null, $identifierType = 'id') {
1457
 
1458
- $storeId = $this->getStoreCode($store);
 
 
 
 
1459
 
1460
- $_loadedProduct = Mage::helper('catalog/product')->getProduct($productId, $storeId, $identifierType);
 
 
 
1461
 
1462
- if (!$_loadedProduct->getId())
1463
- {
1464
- throw new Mage_Api_Exception('product_not_exists', null);
1465
- }
1466
 
1467
- return $_loadedProduct->getProductUrl();
1468
- }
1469
-
1470
- public function updatePriceBulk($data, $store, $identifierType) {
1471
- $response = array();
1472
- for ($i = 0; $i< sizeof($data); $i++) {
1473
- $d = $data[$i];
1474
- $product = Mage::helper('catalog/product')->getProduct($d->sku, $store, $identifierType);
1475
- if ($product && $product->getId()) {
1476
- if ($product->getPrice()!=$d->price) {
1477
- $product->setPrice($d->price);
1478
- $product->save();
1479
- }
1480
- }
1481
- $response[] = array('sku'=>$d->sku, 'success'=>($product && $product->getId()));
1482
- }
1483
- return $response;
1484
- }
1485
- }
1486
 
1487
- class LinnLiveEnterprise extends LinnLiveMain {
1488
-
1489
- public function productAttributeOptions($setId)
1490
- {
1491
- $result = array();
1492
-
1493
- $setId = intval($setId);
1494
- if ($setId <= 0) return $result;
1495
-
1496
- $attributeAPI = Mage::getModel('catalog/product_attribute_api');
1497
-
1498
- $attributes = Mage::getModel('catalog/product')->getResource()->loadAllAttributes()->getSortedAttributes($setId);
1499
-
1500
- foreach ($attributes as $attribute) {
1501
-
1502
- if ((!$attribute->getId() || $attribute->isInSet($setId))
1503
- && !in_array($attribute->getAttributeCode(), $this->_ignoredAttributes)
1504
- && in_array($attribute->getFrontendInput(), $this->_permittedAttributes)) {
1505
-
1506
- if (!$attribute->getId() || $attribute->isScopeGlobal()) {
1507
- $scope = 'global';
1508
- } elseif ($attribute->isScopeWebsite()) {
1509
- $scope = 'website';
1510
- } else {
1511
- $scope = 'store';
1512
- }
1513
-
1514
- $result[] = array(
1515
- 'attribute_id' => $attribute->getId(),
1516
- 'code' => $attribute->getAttributeCode(),
1517
- 'type' => $attribute->getFrontendInput(),
1518
- 'required' => $attribute->getIsRequired(),
1519
- 'scope' => $scope,
1520
- 'can_config' => 0
1521
- );
1522
-
1523
- if ( ($attribute->getFrontendInput() == 'select') || ($attribute->getFrontendInput() == 'multiselect') ) {
1524
- if (($scope == 'global') && $attribute->getIsConfigurable())
1525
- {
1526
- if (strpos($attribute->getApplyTo(), 'simple') !== false)
1527
- $result[]['can_config'] = 1;
1528
- }
1529
-
1530
- $options = $attributeAPI->options($attribute->getId());
1531
-
1532
- // remove empty first element
1533
- if ($attribute->getFrontendInput() != 'boolean') {
1534
- array_shift($options);
1535
- }
1536
-
1537
- if (count($options) > 0) {
1538
- $result[]['attribute_options'] = $options;
1539
- }
1540
- }
1541
- }
1542
- }
1543
 
1544
- return $result;
1545
- }
1546
-
1547
- //Fix for buggy associativeArray implementation
1548
- private function _fixAttributes($productData)
1549
- {
1550
- $_newAttributeOptions = $this->_newOptions($productData);
1551
- $_availableOptions = array();
1552
- if (count($_newAttributeOptions) > 0)
1553
- {
1554
- $_availableOptions = $this->_createOptions($_newAttributeOptions);
1555
- }
1556
 
1557
- if (property_exists($productData, 'additional_attributes')) {
1558
- $tmpAttr = $productData->additional_attributes;
1559
- if (count($tmpAttr) == 0)
1560
- {
1561
- unset($productData->additional_attributes);
1562
- return $productData;
1563
- }
1564
- $productData->additional_attributes = new stdClass();
1565
- $productData->additional_attributes->single_data = array();
1566
- $i=0;
1567
- if (is_array($tmpAttr))
1568
- {
1569
- foreach ($tmpAttr as $option) {
1570
- $productData->additional_attributes->single_data[$i] = new stdClass();
1571
- $productData->additional_attributes->single_data[$i]->key = $option->code;
1572
-
1573
- if ( ($option->type == 'multiselect') && (is_array($productData->additional_attributes->single_data[$i]->value) == false) )
1574
- {
1575
- $productData->additional_attributes->single_data[$i]->value = array();
1576
- }
1577
-
1578
- if (isset($_availableOptions[$option->attribute_id][strtolower($option->label)]))
1579
- {
1580
- if ($option->type == 'multiselect')
1581
- {
1582
- array_push($productData->additional_attributes->single_data[$i]->value, $_availableOptions[$option->attribute_id][strtolower($option->label)]);
1583
- }
1584
- else
1585
- {
1586
- $productData->additional_attributes->single_data[$i]->value = $_availableOptions[$option->attribute_id][strtolower($option->label)];
1587
- }
1588
- }
1589
- else
1590
- {
1591
- if ($option->type == 'multiselect')
1592
- {
1593
- array_push($productData->additional_attributes->single_data[$i]->value, $option->value);
1594
- }
1595
- else
1596
- {
1597
- $productData->additional_attributes->single_data[$i]->value = $option->value;
1598
- }
1599
- }
1600
- $i++;
1601
- }
1602
- }
1603
- else
1604
- {
1605
- $productData->additional_attributes->single_data[0] = new stdClass();
1606
- $productData->additional_attributes->single_data[0]->key = $tmpAttr->code;
1607
- if (isset($_availableOptions[$tmpAttr->attribute_id][strtolower($tmpAttr->label)]))
1608
- $productData->additional_attributes->single_data[0]->value = $_availableOptions[$tmpAttr->attribute_id][strtolower($tmpAttr->label)];
1609
- else
1610
- $productData->additional_attributes->single_data[0]->value = $tmpAttr->value;
1611
- }
1612
- }
1613
 
1614
- return $productData;
1615
- }
1616
- }
 
 
 
 
 
 
1617
 
1618
- class LinnLiveCommunity extends LinnLiveMain {
1619
 
1620
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1621
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1622
  ?>
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
+ //obsolete, pls remove
69
+ public function create($version, $type, $set, $sku, $productData, $store = null) {
70
+
71
+ $worker = Factory::createWorker($version);
72
+ return $worker -> createSimpleProduct($type, $set, $sku, $productData, $store, true);
73
+ }
74
+
75
+ //obsolete, pls remove
76
+ public function configurableProduct($version, $set, $sku, $reindex, $productData, $productsSet, $attributesSet, $store = null) {
77
+
78
+ $worker = Factory::createWorker($version);
79
+ return $worker -> createConfigurableProduct($set, $sku, $reindex, $productData, $productsSet, $attributesSet, $store);
80
+ }
81
+
82
+ public function createProductImages($version, $data) {
83
+
84
+ $worker = Factory::createWorker($version);
85
+ return $worker -> createProductImages($data);
86
+ }
87
+
88
+ public function updateSimpleProducts($version, $data) {
89
+
90
+ $worker = Factory::createWorker($version);
91
+ return $worker -> updateSimpleProducts($data);
92
+ }
93
+
94
+ public function updateConfigurableProducts($version, $data) {
95
+
96
+ $worker = Factory::createWorker($version);
97
+ return $worker -> updateConfigurableProducts($data);
98
+ }
99
+
100
+ public function updateProductImages($version, $data) {
101
+
102
+ $worker = Factory::createWorker($version);
103
+ return $worker -> updateProductImages($data);
104
+ }
105
+
106
+ //obsolete, pls remove
107
+ public function update($version, $productId, $productData, $store = null, $identifierType = 'id') {
108
+
109
+ $worker = Factory::createWorker($version);
110
+ return $worker -> updateSimpleProduct($productId, $productData, $store, $identifierType);
111
+ }
112
+
113
+ public function updatePriceBulk($version, $data, $store = null, $identifierType = 'id') {
114
+
115
+ $worker = Factory::createWorker($version);
116
+ return $worker -> updateProductPrices($data, $store, $identifierType);
117
+ }
118
+
119
+ //obsolete, pls remove
120
+ public function updateConfigurableProduct($version, $productId, $reindex, $productData, $productsSet, $attributesSet, $store = null, $identifierType = 'id') {
121
+
122
+ $worker = Factory::createWorker($version);
123
+ return $worker -> updateConfigurableProduct($productId, $reindex, $productData, $productsSet, $attributesSet, $store, $identifierType);
124
+ }
125
+
126
+ public function deleteProducts($version, $data) {
127
+
128
+ $worker = Factory::createWorker($version);
129
+ return $worker -> deleteProducts($data);
130
+ }
131
+
132
+ public function deleteRelatedProducts($version, $data) {
133
+
134
+ $worker = Factory::createWorker($version);
135
+ return $worker -> deleteRelatedProducts($data);
136
+ }
137
+
138
+ //obsolete, pls remove
139
+ public function deleteAssigned($version, $productId, $store = null, $identifierType = 'id') {
140
+
141
+ $worker = Factory::createWorker($version);
142
+ return $worker -> deleteAssigned($productId, $store, $identifierType);
143
+ }
144
+
145
+ public function deleteProductImages($version, $data) {
146
+
147
+ $worker = Factory::createWorker($version);
148
+ return $worker -> deleteProductImages($data);
149
+ }
150
+
151
+ public function getProductStoreURL($version, $productId, $store = null, $identifierType = 'id') {
152
+
153
+ $worker = Factory::createWorker($version);
154
+ return $worker -> getProductStoreURL($productId, $store, $identifierType);
155
+ }
156
+
157
+ public function getStoreCode($version, $store = null) {
158
+
159
+ $worker = Factory::createWorker($version);
160
+ return $worker -> getStoreCode($store);
161
+ }
162
+
163
+ public function getGeneralInfo($version) {
164
+
165
+ $worker = Factory::createWorker($version);
166
+ return $worker -> getGeneralInfo();
167
+ }
168
+
169
+ //todo: rename
170
+ public function productList($version, $page, $perPage, $filters = null, $store = null) {
171
+
172
+ $worker = Factory::createWorker($version);
173
+ return $worker -> getProductList($page, $perPage, $filters, $store);
174
+ }
175
+
176
+ //todo: rename
177
+ public function productAttributeOptions($version, $setId) {
178
+
179
+ $worker = Factory::createWorker($version);
180
+ return $worker -> getProductAttributeOptions($setId);
181
+ }
182
+
183
+ //obsolete
184
+ public function assignImages($version, $productImages) {
185
+
186
+ $worker = Factory::createWorker($version);
187
+ return $worker -> assignImages($productImages);
188
+ }
189
+
190
+ public function storesList($version) {
191
+
192
+ $worker = Factory::createWorker($version);
193
+ return $worker -> storesList();
194
+ }
195
+
196
+ public function disableIndexing($version) {
197
+ $worker = Factory::createWorker($version);
198
+ return $worker -> disableIndexing();
199
+ }
200
+
201
+ public function restoreIndexingById($version, $data) {
202
+ $worker = Factory::createWorker($version);
203
+ return $worker -> restoreIndexingById($data);
204
+ }
205
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
206
  }
207
 
208
  class Factory {
209
 
210
+ private static function _checkVersion($version) {
211
+ $version = intval($version);
 
212
 
213
+ if ($version == 0) {
214
+ throw new Mage_Api_Exception('version_not_specified');
215
+ }
216
 
217
+ if (Mage::helper('linnLiveConnect/settings') -> getShortVersion() < $version) {
218
+ throw new Mage_Api_Exception('wrong_version');
219
+ }
220
+ }
221
 
222
+ public static function createWorker($version) {
223
+ self::_checkVersion($version);
224
+
225
+ if (Mage::GetEdition() == Mage::EDITION_COMMUNITY || Mage::GetEdition() == Mage::EDITION_ENTERPRISE) {
226
+ return new LinnLiveCommunity();
227
+ }
228
+
229
+ throw new Mage_Api_Exception('unsupported_edition');
230
+ }
231
 
 
 
232
  }
233
 
234
  class LinnLiveMain extends Mage_Core_Model_Abstract {
235
 
236
+ 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', );
237
 
238
+ protected $_permittedAttributes = array('select', 'multiselect', 'text', 'textarea', 'date', 'price');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
239
 
240
+ protected function _prepareConfigurableData($productsSet, $attributesSet, $isUpdate) {
241
+ $helper = Mage::helper('linnLiveConnect');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
242
 
243
+ $assignedProductsArray = $helper -> objectToArray($this -> _createProductsData($productsSet));
 
 
244
 
245
+ $_newAttributeOptions = $this -> _newConfigurableOptions($assignedProductsArray);
246
+ if (count($_newAttributeOptions) > 0) {
247
+ $this -> _checkAssignedProductsOptions($helper -> createOptions($_newAttributeOptions), $assignedProductsArray);
248
+ }
249
 
250
+ if (!is_array($attributesSet)) {
251
+ $attributesSet = array($attributesSet);
252
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
253
 
254
+ $attributesSetArray = $this -> _prepareAttributesData($helper -> objectToArray($attributesSet), $assignedProductsArray);
 
 
 
 
255
 
256
+ foreach ($attributesSetArray as $key => $value) {
257
+ $attributesSetArray[$key]["id"] = NULL;
258
+ $attributesSetArray[$key]["position"] = NULL;
259
+ $attributesSetArray[$key]["store_label"] = isset($value['frontend_label']) ? $value['frontend_label'] : NULL;
260
+ //$attributesSetArray[$key]["use_default"] = 0;
261
 
262
+ if ($isUpdate == false) {
263
+ //check if attribute exists and available
264
+ $checkAttribute = Mage::getModel('catalog/resource_eav_attribute') -> loadByCode('catalog_product', $attributesSetArray[$key]["attribute_code"]);
265
 
266
+ if (!$checkAttribute -> getId() || !$this -> _isConfigurable($checkAttribute)) {
267
+ 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.');
268
+ }
269
+ }
 
270
 
271
+ }
272
+ return array($assignedProductsArray, $attributesSetArray);
273
+ }
 
274
 
275
+ protected function _isConfigurable($attribute) {
276
+ $isConfigurable = 0;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
277
 
278
+ if (isset($attribute['is_global']) && $attribute['is_global']) {
279
+ $attribute['scope'] = 'global';
280
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
281
 
282
+ if (($attribute['scope'] == 'global') && ($attribute['is_configurable'])) {
283
+ if (is_array($attribute['apply_to']) && sizeof($attribute['apply_to'])) {
284
+ if (in_array('simple', $attribute['apply_to'])) {
285
+ $isConfigurable = 1;
286
+ }
287
+ } elseif (is_string($attribute['apply_to']) && strlen($attribute['apply_to'])) {
288
+ if (strpos($attribute['apply_to'], 'simple') !== false) {
289
+ $isConfigurable = 1;
290
+ }
291
+ } else {
292
+ $isConfigurable = 1;
293
+ }
294
+ }
295
+ return $isConfigurable;
296
+ }
297
+
298
+ protected function _checkAssignedProductsOptions($availableOptions, &$assignedProductsArray) {
299
+ foreach ($assignedProductsArray as $id => $productOptions) {
300
+ foreach ($productOptions as $index => $option) {
301
+ if (isset($availableOptions[$option['attribute_id']][strtolower($option['label'])])) {
302
+ $assignedProductsArray[$id][$index]['value_index'] = $availableOptions[$option['attribute_id']][strtolower($option['label'])];
303
+ }
304
+ }
305
+ }
306
+ }
307
+
308
+ protected function _newConfigurableOptions($assignedProductsArray) {
309
+ $_attributesOptions = array();
310
+ foreach ($assignedProductsArray as $id => $productOptions) {
311
+ foreach ($productOptions as $option) {
312
+ if (isset($option['value_index']) && $option['value_index'] == '-1') {
313
+ if (isset($_attributesOptions[$option['attribute_id']])) {
314
+ $_attributesOptions[$option['attribute_id']][] = $option['label'];
315
+ } else {
316
+ $_attributesOptions[$option['attribute_id']] = array($option['label']);
317
+ }
318
+ }
319
+ }
320
+ }
321
+ return $_attributesOptions;
322
+ }
323
+
324
+ protected function _containsOption($attributeOption, $option) {
325
+ foreach ($attributeOption as $inArrayOption)
326
+ if ($inArrayOption['value_index'] == $option['value_index'])
327
+ return true;
328
+
329
+ return false;
330
+ }
331
+
332
+ protected function _prepareAttributesData($attributesSetArray, $assignedProductsArray) {
333
+
334
+ $_attributesOptions = array();
335
+ foreach ($assignedProductsArray as $id => $productOptions) {
336
+ foreach ($productOptions as $option) {
337
+ if (isset($_attributesOptions[$option['attribute_id']]) && !$this -> _containsOption($_attributesOptions[$option['attribute_id']], $option)) {
338
+ $_attributesOptions[$option['attribute_id']][] = $option;
339
+ } else if (!isset($_attributesOptions[$option['attribute_id']])) {
340
+ $_attributesOptions[$option['attribute_id']] = array();
341
+ $_attributesOptions[$option['attribute_id']][] = $option;
342
+ }
343
+ }
344
+ }
345
 
346
+ foreach ($attributesSetArray as $key => $attribute) {
347
+ if (isset($_attributesOptions[$attribute['attribute_id']])) {
348
+ $attributesSetArray[$key]['values'] = $_attributesOptions[$attribute['attribute_id']];
349
+ }
350
+ }
351
+
352
+ return $attributesSetArray;
353
+ }
354
+
355
+ protected function _updateConfigurable($store, $productId, $assignedProducts, $assignedAttributes, $identifierType, $isUpdate = false, $reindex = true) {
356
+ $magentoVer = $this -> _getCurrentVersion();
357
+ if ($magentoVer == 162) {
358
+ $store = Mage::app() -> getStore($store) -> getId();
359
+ } else {
360
+ $store = NULL;
361
+ }
362
+
363
+ $product = Mage::helper('catalog/product') -> getProduct($productId, $store, $identifierType);
364
+
365
+ $product -> setConfigurableProductsData($assignedProducts);
366
+
367
+ if ($isUpdate == false) {
368
+ $product -> setConfigurableAttributesData($assignedAttributes);
369
+ $product -> setCanSaveConfigurableAttributes(true);
370
+ }
371
+
372
+ try {
373
+ $result = $product -> save();
374
+ } catch (Exception $e) {
375
+ throw new Mage_Api_Exception('configurable_creating_error', $e -> getMessage());
376
+ }
377
+
378
+ //TODO obsolete
379
+ //if ($reindex === true) {
380
+ // try {
381
+ // $indexer = Mage::getSingleton('index/indexer');
382
+ // $process = $indexer -> getProcessByCode('catalog_product_price');
383
+ // $process -> reindexEverything();
384
+ // } catch (Mage_Core_Exception $e) {
385
+ // throw new Mage_Api_Exception('configurable_creating_error', $e -> getMessage());
386
+ // }
387
+ //}
388
+
389
+ return $result;
390
+ }
391
+
392
+ protected function _createProductsData($productData) {
393
+ $assignedProductsData = array();
394
+
395
+ if (is_array($productData)) {
396
+ foreach ($productData as $product) {
397
+ $assignedProductsData[$product -> product_id] = array();
398
+ $this -> _fillAssignedProductValues($product, $assignedProductsData);
399
+ }
400
+ } else {
401
+ $assignedProductsData[$productData -> product_id] = array();
402
+ $this -> _fillAssignedProductValues($product, $assignedProductsData);
403
+ }
404
+
405
+ return $assignedProductsData;
406
+ }
407
+
408
+ protected function _fillAssignedProductValues(&$product, &$assignedProductsData) {
409
+ if (is_array($product -> values)) {
410
+ foreach ($product->values as $productValue) {
411
+ $assignedProductsData[$product -> product_id][] = $productValue;
412
+ }
413
+ } else {
414
+ $assignedProductsData[$product -> product_id][] = $product -> values;
415
+ }
416
+ }
417
+
418
+ protected function _getCurrentVersion() {
419
+ $verInfo = Mage::getVersionInfo();
420
+
421
+ return intval($verInfo['major'] . $verInfo['minor'] . $verInfo['revision']);
422
+ }
423
+
424
+ protected function _removeIgnoredAttributes($attributesList) {
425
+ $_preparedAttributes = array();
426
+ if (is_array($attributesList) && count($attributesList) > 0) {
427
+ foreach ($attributesList as $key => $value) {
428
+ if (!in_array($key, $this -> _ignoredAttributes) && !is_array($value))
429
+ $_preparedAttributes[] = array('key' => $key, 'value' => $value);
430
+ }
431
+ }
432
 
433
+ return $_preparedAttributes;
434
+ }
 
 
 
 
435
 
436
+ protected function _productAttributeInfo($attribute_id, $attributeAPI) {
437
+ $model = Mage::getResourceModel('catalog/eav_attribute') -> setEntityTypeId(Mage::getModel('eav/entity') -> setType('catalog_product') -> getTypeId());
 
 
 
 
 
 
 
 
 
 
438
 
439
+ $model -> load($attribute_id);
 
 
440
 
441
+ if (!$model -> getId()) {
442
+ throw new Mage_Api_Exception('attribute_not_exists');
443
+ }
 
 
 
444
 
445
+ if ($model -> isScopeGlobal()) {
446
+ $scope = 'global';
447
+ } elseif ($model -> isScopeWebsite()) {
448
+ $scope = 'website';
449
+ } else {
450
+ $scope = 'store';
451
+ }
452
 
453
+ $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, );
 
 
 
 
 
 
 
 
 
 
454
 
455
+ // set options
456
+ $options = $attributeAPI -> options($model -> getId());
457
+ // remove empty first element
458
+ if ($model -> getFrontendInput() != 'boolean') {
459
+ array_shift($options);
460
+ }
461
 
462
+ if (count($options) > 0) {
463
+ $result['options'] = $options;
464
+ }
465
 
466
+ return $result;
467
+ }
 
 
 
 
 
 
 
 
 
 
 
468
 
469
+ protected function _log($message) {
470
+ Mage::log(print_r($message, true), null, 'LinnLiveExt.log');
471
+ }
472
 
473
+ /********************************Indexer block***********************************************/
474
+ /*****************************************************************************************/
475
+ /*****************************************************************************************/
476
+ public function disableIndexing() {
477
+ $states = array();
478
+ $blocked = array('cataloginventory_stock', 'catalog_product_flat', 'catalog_category_flat', 'catalogsearch_fulltext');
479
 
480
+ $processes = Mage::getSingleton('index/indexer') -> getProcessesCollection();
481
+ foreach ($processes as $process) {
 
 
 
 
 
 
 
 
 
 
 
 
482
 
483
+ $code = $process -> getIndexerCode();
 
 
484
 
485
+ if (in_array($code, $blocked) || $process -> getId() > 9) {
486
+ continue;
487
+ }
 
488
 
489
+ $states[] = array('key' => $code, 'value' => $process -> getMode());
 
 
490
 
491
+ $process -> setMode(Mage_Index_Model_Process::MODE_MANUAL) -> save();
492
+ }
493
+ return $states;
494
+ }
 
495
 
496
+ public function restoreIndexingById($data) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
497
 
498
+ foreach ($data as $key => $value) {
 
 
 
 
 
 
 
 
 
 
 
 
 
499
 
500
+ $process = Mage::getModel('index/indexer') -> getProcessByCode($key);
501
+ if ($process && $process -> getIndexerCode()) {
502
 
503
+ $value = $value == Mage_Index_Model_Process::MODE_MANUAL ? Mage_Index_Model_Process::MODE_MANUAL : Mage_Index_Model_Process::MODE_REAL_TIME;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
504
 
505
+ if ($process -> getMode() != $value) {
506
+ $process -> setMode($value) -> save();
507
+ }
 
 
508
 
509
+ if ($process -> getStatus() == Mage_Index_Model_Process::STATUS_REQUIRE_REINDEX) {
510
+ $process -> reindexEverything();
511
+ }
512
+ }
513
+ }
514
+ }
515
+
516
+ protected function reindexProducts() {
517
+ $processes = Mage::getSingleton('index/indexer') -> getProcessesCollection();
518
+ foreach ($processes as $process) {
519
+ if ($process -> getStatus() == Mage_Index_Model_Process::STATUS_REQUIRE_REINDEX) {
520
+ $process -> reindexEverything();
521
+ }
522
+ }
523
+ }
524
 
525
+ protected function lockIndexer() {
526
+ Mage::setIsDeveloperMode(true);
527
+ //Mage::getSingleton('index/indexer') -> getProcessesCollection() -> walk('lockAndBlock');
528
+ }
529
+
530
+ protected function unlockIndexer() {
531
+ //Mage::getSingleton('index/indexer') -> getProcessesCollection() -> walk('unlock');
532
+ Mage::setIsDeveloperMode(false);
533
+ }
534
+
535
+ protected function cleanCache() {
536
+ Mage::app() -> getCacheInstance() -> flush();
537
+ Mage::app() -> cleanCache();
538
+ }
539
+
540
+ protected function disableAllIndexing() {
541
+ $processes = Mage::getSingleton('index/indexer') -> getProcessesCollection();
542
+ $processes -> walk('setMode', array(Mage_Index_Model_Process::MODE_MANUAL));
543
+ $processes -> walk('save');
544
+ }
545
+
546
+ protected function enableAllIndexing() {
547
+ $processes = Mage::getSingleton('index/indexer') -> getProcessesCollection();
548
+ //$processes -> walk('reindexAll');
549
+ $processes -> walk('setMode', array(Mage_Index_Model_Process::MODE_REAL_TIME));
550
+ $processes -> walk('save');
551
+ }
552
+
553
+ }
554
+
555
+ class LinnLiveCommunity extends LinnLiveMain {
556
+
557
+ //obsolete
558
+ public function storesList() {
559
+ return ($this -> _getCurrentVersion() >= 160);
560
+ }
561
+
562
+ //obsolete
563
+ public function deleteAssigned($productId, $store = null, $identifierType = 'id') {
564
+ $helper = Mage::helper('linnLiveConnect');
565
+ $store = $helper -> currentStoreCode($store);
566
 
567
+ try {
568
+ $storeId = Mage::app() -> getStore($store) -> getId();
569
+ } catch (Mage_Core_Model_Store_Exception $e) {
570
+ throw new Mage_Api_Exception('store_not_exists', null);
571
+ }
572
+
573
+ $_loadedProduct = Mage::helper('catalog/product') -> getProduct($productId, $storeId, $identifierType);
574
+
575
+ if (!$_loadedProduct -> getId()) {
576
+ throw new Mage_Api_Exception('product_not_exists', null);
577
+ }
578
+
579
+ $currentWebsites = $_loadedProduct -> getWebsiteIds();
580
+ $websiteId = $helper -> getWebsiteId($store);
581
+
582
+ $newWebsiteIds = array();
583
+
584
+ if (in_array($websiteId, $currentWebsites) === true) {
585
+ for ($i = 0; $i < count($currentWebsites); $i++) {
586
+ if ($currentWebsites[$i] != $websiteId) {
587
+ $newWebsiteIds[] = $currentWebsites[$i];
588
  }
589
+ }
 
590
 
591
+ $_loadedProduct -> setWebsiteIds($newWebsiteIds);
592
 
593
+ $_loadedProduct -> save();
594
+ }
595
 
596
+ return true;
597
+ }
 
 
598
 
599
+ //obsolete
600
+ public function assignImages($productImages) {
601
+ $helper = Mage::helper('linnLiveConnect');
602
+ $store = $helper -> currentStoreCode(null);
603
 
604
+ foreach ($productImages as $imageData) {
605
+ $productId = intval($imageData -> product_id);
606
+ if ($productId < 1) {
607
+ throw new Mage_Api_Exception('product_not_exists', null);
608
+ }
609
 
610
+ $product = Mage::helper('catalog/product') -> getProduct($productId, $store, 'id');
 
 
611
 
612
+ $images = $imageData -> images;
 
 
 
 
 
 
613
 
614
+ $baseImageExist = false;
615
+ foreach ($images as $image) {
616
+ if (is_array($image -> types) && in_array('image', $image -> types)) {
617
+ $baseImageExist = true;
618
+ }
619
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
620
 
621
+ if ($baseImageExist == false && count($images) > 0) {
622
+ $images[0] -> types = array('image');
623
+ }
624
 
625
+ reset($images);
 
 
 
 
 
 
 
 
 
 
 
626
 
627
+ foreach ($images as $image) {
628
+ $catalogProductDir = Mage::getBaseDir('media') . DS . 'catalog/product';
629
+ $filePath = $catalogProductDir . $image -> image_name;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
630
 
631
+ if (is_array($image -> types) && count($image -> types) > 0) {
632
+ $imageTypes = $image -> types;
633
+ } else {
634
+ $imageTypes = "";
635
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
636
 
637
+ try {
638
+ $product -> addImageToMediaGallery($filePath, $imageTypes, false, false);
639
+ } catch (Exception $e) {
640
+ }
641
 
642
+ }
 
 
 
 
643
 
644
+ $product -> save();
645
+ }
646
+
647
+ return true;
648
+ }
649
+
650
+ /**
651
+ * Get products
652
+ * Implementation of catalogProductList because of bug in associativeArray.
653
+ * Extended to filter by category id too.
654
+ *
655
+ * Use 'entity_id' for product_id,
656
+ * 'type_id' instead of product type.
657
+ * @return array | mixed
658
+ */
659
+ public function getProductList($page, $perPage, $filters = null, $store = null) {
660
+ $helper = Mage::helper('linnLiveConnect');
661
+
662
+ //get store
663
+ try {
664
+ $storeId = Mage::app() -> getStore($helper -> currentStoreCode($store)) -> getId();
665
+ } catch (Mage_Core_Model_Store_Exception $e) {
666
+ throw new Mage_Api_Exception('store_not_exists', null);
667
+ }
668
+
669
+ //prepare and convert filters to array
670
+ $preparedFilters = $helper -> convertFiltersToArray($filters);
671
+ if (empty($preparedFilters)) {
672
+ throw new Mage_Api_Exception('filters_invalid', null);
673
+ }
674
+
675
+ //load collection
676
+ $collection = Mage::getModel('catalog/product') -> getCollection() -> addStoreFilter($storeId);
677
+
678
+ //filter collection by category if exists
679
+ if (isset($preparedFilters['category']) && is_string($preparedFilters['category'])) {
680
+ $_category = Mage::getModel('catalog/category') -> load(intval($preparedFilters['category']));
681
+
682
+ if ($_category -> getId()) {
683
+ $collection = $collection -> addCategoryFilter($_category);
684
+ }
685
 
686
+ unset($preparedFilters['category']);
687
+ }
688
+
689
+ //add prepared filters to collection
690
+ try {
691
+ foreach ($preparedFilters as $field => $data) {
692
+ if (is_array($data)) {
693
+ foreach ($data as $key => $value) {
694
+ $collection -> addFieldToFilter($field, array($key => $value));
695
+ }
696
+ } else {
697
+ $collection -> addFieldToFilter($field, $data);
698
+ }
699
+ }
700
+ } catch (Mage_Core_Exception $e) {
701
+ throw new Mage_Api_Exception('filters_invalid', $e -> getMessage());
702
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
703
 
704
+ if ($page == 1) {
705
+ //TODO: limit page size
706
+ $count = $collection -> count();
707
+ } else {
708
+ $count = 0;
709
+ $collection -> setPageSize($perPage) -> setCurPage($page);
710
+ }
 
 
 
711
 
712
+ $result = array('count' => $count, 'products' => array());
 
 
 
 
713
 
714
+ $_assignedIds = array();
715
+ $_fetchedIds = array();
716
 
717
+ $i = 0;
718
+ foreach ($collection as $_product) {
719
 
720
+ if ($i >= ($perPage * $page))
721
+ break;
722
+ //TODO remove
723
+ $_loadedProduct = Mage::helper('catalog/product') -> getProduct($_product -> getId(), $storeId, 'id');
724
 
725
+ $_allAttributes = $_loadedProduct -> getData();
 
 
 
 
 
726
 
727
+ $_description = isset($_allAttributes['description']) ? $_allAttributes['description'] : '';
 
 
 
 
 
728
 
729
+ $_productImages = $helper -> productImages($_allAttributes);
730
+ $_productAttributes = $this -> _removeIgnoredAttributes($_allAttributes);
731
 
732
+ $_fetchedIds[] = $_loadedProduct -> getId();
 
 
 
733
 
734
+ $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, );
 
 
 
735
 
736
+ if ($_loadedProduct -> getTypeId() == "configurable") {
737
+ $_typeInstance = $_loadedProduct -> getTypeInstance();
738
+ $result['products'][$i]['assigned_ids'] = $_typeInstance -> getUsedProductIds();
739
+ foreach ($_typeInstance->getConfigurableAttributes() as $attribute) {
740
+ $_prices = array();
741
+ foreach ($attribute->getPrices() as $price) {
742
+ $_prices[] = array('value_index' => $price['value_index'], 'is_fixed' => !$price['is_percent'], 'price_diff' => $price['pricing_value'], 'label' => $price['label'], );
743
+ }
744
 
745
+ $result['products'][$i]['conf_attrib_ids'][] = array('code' => $attribute -> getProductAttribute() -> getAttributeCode(), 'prices' => $_prices);
746
+ }
747
+ $_assignedIds = array_merge($_assignedIds, $result['products'][$i]['assigned_ids']);
748
+ }
 
 
749
 
750
+ $i++;
751
+ }
752
 
753
+ $_absentIds = array_diff($_assignedIds, $_fetchedIds);
 
 
 
 
754
 
755
+ if (count($_absentIds) > 0) {
756
+ $collection = Mage::getModel('catalog/product') -> getCollection() -> addIdFilter($_absentIds);
757
 
758
+ foreach ($collection as $_product) {
759
+ $_loadedProduct = Mage::helper('catalog/product') -> getProduct($_product -> getId(), $storeId, 'id');
 
 
 
760
 
761
+ $_allAttributes = $_product -> getData();
 
 
 
 
 
762
 
763
+ $_description = isset($_allAttributes['description']) ? $_allAttributes['description'] : '';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
764
 
765
+ $_productImages = $helper -> productImages($_allAttributes);
766
+ $_productAttributes = $this -> _removeIgnoredAttributes($_allAttributes);
767
 
768
+ $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()), );
769
+ }
770
+ }
 
771
 
772
+ return $result;
773
+ }
774
 
775
+ /**
776
+ * Get attribute set attrobites
777
+ *
778
+ * @return array | mixed
779
+ */
780
+ public function getProductAttributeOptions($setId) {
781
 
782
+ $result = array();
783
 
784
+ $setId = intval($setId);
785
+ if ($setId <= 0) {
786
+ return $result;
787
+ }
 
 
 
 
 
788
 
789
+ $attributeAPI = Mage::getModel('catalog/product_attribute_api');
790
 
791
+ $items = $attributeAPI -> items($setId);
 
792
 
793
+ $attributes = Mage::getModel('catalog/product') -> getResource() -> loadAllAttributes();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
794
 
795
+ foreach ($items as $item) {
796
+ if (!isset($item['attribute_id']) || empty($item['attribute_id']))
797
+ continue;
798
+ $attributeId = intval($item['attribute_id']);
799
+ if ($attributeId <= 0)
800
+ continue;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
801
 
802
+ $additionInfo = $this -> _productAttributeInfo($attributeId, $attributeAPI);
 
 
 
 
803
 
804
+ if (in_array($additionInfo['frontend_input'], $this -> _permittedAttributes) && !in_array($additionInfo['attribute_code'], $this -> _ignoredAttributes)) {
 
805
 
806
+ $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);
 
 
 
807
 
808
+ if (($additionInfo['frontend_input'] == 'select') || ($additionInfo['frontend_input'] == 'multiselect')) {
809
+ if (isset($additionInfo['options'])) {
 
810
 
811
+ if (sizeof($additionInfo['options']) && is_array($additionInfo['options'][0]['value'])) {
812
+ continue;
813
+ //ignore attributes with multidimensional options
814
+ }
815
+ $attribute['attribute_options'] = $additionInfo['options'];
816
+ }
817
 
818
+ $attribute['can_config'] = $this -> _isConfigurable($additionInfo);
819
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
820
 
821
+ $result[] = $attribute;
822
+ }
823
+ }
824
+
825
+ return $result;
826
+ }
827
 
828
+ /**
829
+ * Get general information about magento installation
830
+ *
831
+ * @return array | mixed
832
+ */
833
+ public function getGeneralInfo() {
834
+ $config = Mage::getStoreConfig("api/config");
835
+ $verInfo = Mage::getVersionInfo();
 
 
836
 
837
+ $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') && defined('COMPILER_COLLECT_PATH')), 'max_upload_size' => min((int)ini_get("upload_max_filesize"), (int)ini_get("post_max_size"), (int)ini_get("memory_limit")));
838
+
839
+ return $result;
840
+ }
841
+
842
+ /**
843
+ * Get store code
844
+ *
845
+ * @return string
846
+ */
847
+ public function getStoreCode($store = null) {
848
+ $helper = Mage::helper('linnLiveConnect');
849
+ return $helper -> currentStoreCode($store);
850
+ }
851
+
852
+ /**
853
+ * Get product url
854
+ *
855
+ * @return string
856
+ */
857
+ public function getProductStoreURL($productId, $store = null, $identifierType = 'id') {
858
+
859
+ $storeId = $this -> getStoreCode($store);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
860
 
861
+ $_loadedProduct = Mage::helper('catalog/product') -> getProduct($productId, $storeId, $identifierType);
862
+
863
+ if (!$_loadedProduct -> getId()) {
864
+ throw new Mage_Api_Exception('product_not_exists', null);
865
+ }
866
+
867
+ return $_loadedProduct -> getProductUrl();
868
+ }
869
+
870
+ /********************************Single block***********************************************/
871
+ /*****************************************************************************************/
872
+ /*****************************************************************************************/
873
+ /**
874
+ * Check if product exists
875
+ *
876
+ * @return boolean
877
+ */
878
+ protected function checkProduct($sku, $store = null, $identifierType = 'id') {
879
+ $product = Mage::helper('catalog/product') -> getProduct($sku, $store, $identifierType);
880
+ return ($product && $product -> getId());
881
+ }
882
+
883
+ /**
884
+ * Create simple product
885
+ *
886
+ * @return int
887
+ */
888
+ public function createSimpleProduct($type, $set, $sku, $productData, $store = null, $allowToUseInventoryProduct = true) {
889
+ $helper = Mage::helper('linnLiveConnect');
890
+
891
+ if($allowToUseInventoryProduct){
892
+ $product = $helper -> getProductBySku($sku);
893
+ if ($product) {
894
+ return $product -> getId();
895
+ }
896
  }
897
 
898
+ $store = $helper -> currentStoreCode($store);
 
899
 
900
+ $productData = $helper -> createProductData($productData);
 
901
 
902
+ $productData = $helper -> updateProperties($productData);
903
 
904
+ $productData = $helper -> fixAttributes($productData);
 
905
 
906
+ $productAPI = new Mage_Catalog_Model_Product_Api_V2_LL();
907
 
908
+ return $productAPI -> create($type, $set, $sku, $productData, $store);
909
+ }
910
 
911
+ /**
912
+ * Create configurable product
913
+ *
914
+ * @return int
915
+ */
916
+ public function createConfigurableProduct($set, $sku, $reindex, $productData, $productsSet, $attributesSet, $store = null) {
917
 
918
+ if (!$set || !$sku) {
919
+ throw new Mage_Api_Exception('data_invalid');
920
+ }
 
921
 
922
+ $helper = Mage::helper('linnLiveConnect');
923
 
924
+ $helper -> updateConfigurableQuantity($productData);
 
925
 
926
+ $productData = $helper -> createProductData($productData);
 
 
 
 
 
 
 
927
 
928
+ $productData = $helper -> fixAttributes($productData);
 
929
 
930
+ $store = $helper -> currentStoreCode($store);
 
 
 
 
 
 
 
931
 
932
+ //merge into 1?
933
+ $productAPI = new Mage_Catalog_Model_Product_Api_V2_LL();
934
+ $productId = $productAPI -> create('configurable', $set, $sku, $productData, $store);
935
 
936
+ list($assignedProductsArray, $attributesSetArray) = $this -> _prepareConfigurableData($productsSet, $attributesSet, false);
937
+ $this -> _updateConfigurable($store, $productId, $assignedProductsArray, $attributesSetArray, 'id', false, $reindex);
938
 
939
+ return $productId;
940
+ }
 
 
 
 
 
 
 
941
 
942
+ /**
943
+ * Create product image
944
+ *
945
+ * @return string
946
+ */
947
+ protected function createProductImage($productId, $data, $store = null, $identifierType = 'id') {
948
 
949
+ return Mage::getModel('catalog/product_attribute_media_api') -> create($productId, Mage::helper('linnLiveConnect') -> objectToArray($data), $store, $identifierType);
950
+ }
 
 
951
 
952
+ /**
953
+ * Create product link association
954
+ *
955
+ * @return boolean
956
+ */
957
+ protected function createRelatedProduct($type, $productId, $linkedProductId, $identifierType = 'id') {
958
 
959
+ return Mage::getModel('catalog/product_link_api') -> assign($type, $productId, $linkedProductId, null, $identifierType);
960
+ }
 
 
 
 
 
961
 
962
+ /**
963
+ * Update simple product
964
+ *
965
+ * @return boolean
966
+ */
967
+ public function updateSimpleProduct($productId, $productData, $store = null, $identifierType = 'id') {
968
 
969
+ $helper = Mage::helper('linnLiveConnect');
970
+ $store = $helper -> currentStoreCode($store);
971
 
972
+ $helper -> updateProductData($productId, $productData, $store, $identifierType);
 
 
973
 
974
+ $productData = $helper -> updateProperties($productData);
 
975
 
976
+ $productData = $helper -> fixAttributes($productData);
977
 
978
+ $productAPI = new Mage_Catalog_Model_Product_Api_V2();
 
 
 
 
979
 
980
+ return $productAPI -> update($productId, $productData, $store, $identifierType);
981
+ }
 
 
 
 
982
 
983
+ /**
984
+ * Update configurable product
985
+ *
986
+ * @return boolean
987
+ */
988
+ public function updateConfigurableProduct($productId, $reindex, $productData, $productsSet, $attributesSet, $store = null, $identifierType = 'id') {
989
 
990
+ $helper = Mage::helper('linnLiveConnect');
991
 
992
+ $helper -> updateConfigurableQuantity($productData);
993
 
994
+ $productData = $helper -> fixAttributes($productData);
995
 
996
+ $store = $helper -> currentStoreCode($store);
 
997
 
998
+ $helper -> updateProductData($productId, $productData, $store, $identifierType);
 
 
 
 
 
999
 
1000
+ $productAPI = new Mage_Catalog_Model_Product_Api_V2();
1001
 
1002
+ $productAPI -> update($productId, $productData, $store, $identifierType);
1003
 
1004
+ list($assignedProductsArray, $attributesSetArray) = $this -> _prepareConfigurableData($productsSet, $attributesSet, true);
1005
+
1006
+ return $this -> _updateConfigurable($store, $productId, $assignedProductsArray, $attributesSetArray, $identifierType, true, $reindex);
1007
+ }
1008
+
1009
+ /**
1010
+ * Update product image
1011
+ *
1012
+ * @return boolean
1013
+ */
1014
+ protected function updateProductImage($productId, $file, $data, $store = null, $identifierType = 'id') {
1015
+
1016
+ return Mage::getModel('catalog/product_attribute_media_api') -> update($productId, $file, Mage::helper('linnLiveConnect') -> objectToArray($data), $store, $identifierType);
1017
+ }
1018
 
1019
+ /**
1020
+ * Update product price
1021
+ *
1022
+ * @return boolean
1023
+ */
1024
+ protected function updateProductPrice($productId, $store = null, $identifierType = 'id') {
1025
+
1026
+ $product = Mage::helper('catalog/product') -> getProduct($productId, $store, $identifierType);
1027
+
1028
+ if ($product && $product -> getId()) {
1029
+ if ($product -> getPrice() != $d -> price) {
1030
+ $product -> setPrice($d -> price);
1031
+ $product -> save();
1032
  }
1033
+ return true;
1034
+ }
1035
+ return false;
1036
+ }
1037
+
1038
+ /**
1039
+ * Delete product
1040
+ *
1041
+ * @return boolean
1042
+ */
1043
+ protected function deleteProduct($productId, $store = null, $identifierType = 'id') {
1044
+ $product = Mage::helper('catalog/product') -> getProduct($productId, $store, $identifierType);
1045
+ if ($product && $product -> getId()) {
1046
+ return $product -> delete();
1047
+ }
1048
+ return false;
1049
+ }
1050
+
1051
+ /**
1052
+ * Delete product image
1053
+ *
1054
+ * @return boolean
1055
+ */
1056
+ protected function deleteProductImage($productId, $file, $identifierType = 'id') {
1057
+
1058
+ return Mage::getModel('catalog/product_attribute_media_api') -> remove($productId, $file, $identifierType);
1059
+ }
1060
+
1061
+ /**
1062
+ * Remove product link association
1063
+ *
1064
+ * @return boolean
1065
+ */
1066
+ protected function deleteRelatedProduct($type, $productId, $linkedProductId, $identifierType = 'id') {
1067
+
1068
+ return Mage::getModel('catalog/product_link_api') -> remove($type, $productId, $linkedProductId, $identifierType);
1069
+ }
1070
+
1071
+ /********************************Bulk block***********************************************/
1072
+ /*****************************************************************************************/
1073
+ /*****************************************************************************************/
1074
+ /**
1075
+ * Bulk check products by sku/productId
1076
+ */
1077
+ public function checkProducts($data) {
1078
+
1079
+ $response = array();
1080
+
1081
+ for ($i = 0; $i < sizeof($data); $i++) {
1082
+ $entity = $data[$i];
1083
+ $product = Mage::helper('catalog/product') -> getProduct();
1084
+ $response[] = array('sku' => $entity -> sku, 'success' => $this -> checkProduct($entity -> sku, $entity -> store, $entity -> identifierType));
1085
+ }
1086
+
1087
+ return $response;
1088
+
1089
+ }
1090
+
1091
+ /**
1092
+ * Bulk create simple products
1093
+ */
1094
+ public function createSimpleProducts($data) {
1095
+ $this -> lockIndexer();
1096
+
1097
+ $response = array();
1098
+
1099
+ for ($i = 0; $i < sizeof($data); $i++) {
1100
+ $entity = $data[$i];
1101
+ try {
1102
+ $productId = $this -> createSimpleProduct('simple', $entity -> set, $entity -> sku, $entity -> productData, $entity -> store, false);
1103
+ $response[] = array('sku' => $entity -> sku, 'productId' => $productId, 'isError' => ($productId < 1));
1104
+ } catch (Exception $e) {
1105
+ $response[] = array('sku' => $entity -> sku, 'productId' => 0, 'isError' => true, 'error' => $e -> getMessage());
1106
+ }
1107
+ }
1108
 
1109
+ $this -> unlockIndexer();
1110
 
1111
+ return $response;
1112
+ }
1113
 
1114
+ /**
1115
+ * Bulk create configurable products
1116
+ */
1117
+ public function createConfigurableProducts($data) {
1118
 
1119
+ $this -> lockIndexer();
 
 
 
1120
 
1121
+ $response = array();
1122
 
1123
+ for ($i = 0; $i < sizeof($data); $i++) {
1124
+ $entity = $data[$i];
1125
+ try {
1126
+ $productId = $this -> createConfigurableProduct($entity -> set, $entity -> sku, false, $entity -> productData, $entity -> productsSet, $entity -> attributesSet, $entity -> store);
1127
+ $response[] = array('sku' => $entity -> sku, 'productId' => $productId, 'isError' => ($productId < 1));
1128
 
1129
+ } catch (Exception $e) {
1130
+ $response[] = array('sku' => $entity -> sku, 'productId' => 0, 'isError' => true, 'error' => $e -> getMessage());
1131
+ }
1132
+ }
1133
 
1134
+ $this -> unlockIndexer();
 
 
 
1135
 
1136
+ return $response;
1137
+ }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1138
 
1139
+ /**
1140
+ * Bulk create related products
1141
+ */
1142
+ public function createRelatedProducts($data) {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1143
 
1144
+ $this -> lockIndexer();
 
 
 
 
 
 
 
 
 
 
 
1145
 
1146
+ $response = array();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1147
 
1148
+ for ($i = 0; $i < sizeof($data); $i++) {
1149
+ $entity = $data[$i];
1150
+ try {
1151
+ $result = $this -> createRelatedProduct($entity -> type, $entity -> productId, $entity -> linkedProductId, null, $entity -> identifierType);
1152
+ $response[] = array('relatedId' => $entity -> relatedId, 'productId' => $entity -> productId, 'isError' => !$result);
1153
+ } catch (Exception $e) {
1154
+ $response[] = array('relatedId' => $entity -> relatedId, 'productId' => $entity -> productId, 'isError' => true, 'error' => $e -> getMessage());
1155
+ }
1156
+ }
1157
 
1158
+ $this -> unlockIndexer();
1159
 
1160
+ return $response;
1161
+ }
1162
+
1163
+ /**
1164
+ * Bulk create product images
1165
+ */
1166
+ public function createProductImages($data) {
1167
+
1168
+ $this -> lockIndexer();
1169
+
1170
+ $response = array();
1171
+
1172
+ for ($i = 0; $i < sizeof($data); $i++) {
1173
+ $entity = $data[$i];
1174
+ try {
1175
+ $result = $this -> createProductImage($entity -> productId, $entity -> data, $entity -> store, $entity -> identifierType);
1176
+ $response[] = array('imageId' => $entity -> imageId, 'productId' => $entity -> productId, 'isError' => empty($result), 'file' => $result);
1177
+ } catch (Exception $e) {
1178
+ $response[] = array('imageId' => $entity -> imageId, 'productId' => $entity -> productId, 'isError' => true, 'error' => $e -> getMessage());
1179
+ }
1180
+ }
1181
+
1182
+ $this -> unlockIndexer();
1183
+
1184
+ return $response;
1185
+ }
1186
+
1187
+ /**
1188
+ * Bulk update product images
1189
+ */
1190
+ public function updateProductImages($data) {
1191
+
1192
+ $this -> lockIndexer();
1193
+
1194
+ $response = array();
1195
+
1196
+ for ($i = 0; $i < sizeof($data); $i++) {
1197
+ $entity = $data[$i];
1198
+ try {
1199
+ $result = $this -> updateProductImage($entity -> productId, $entity -> file, $entity -> data, $entity -> store, $entity -> identifierType);
1200
+ $response[] = array('imageId' => $entity -> imageId, 'productId' => $entity -> productId, 'isError' => !$result);
1201
+ } catch (Exception $e) {
1202
+ $response[] = array('imageId' => $entity -> imageId, 'productId' => $entity -> productId, 'isError' => true, 'error' => $e -> getMessage());
1203
+ }
1204
+ }
1205
+
1206
+ $this -> unlockIndexer();
1207
+
1208
+ return $response;
1209
+ }
1210
+
1211
+ /**
1212
+ * Bulk price update, TODO: success change to isError
1213
+ */
1214
+ public function updateProductPrices($data, $store, $identifierType = 'id') {
1215
+
1216
+ $this -> lockIndexer();
1217
+
1218
+ $response = array();
1219
+
1220
+ for ($i = 0; $i < sizeof($data); $i++) {
1221
+ $entity = $data[$i];
1222
+ try {
1223
+ $result = $this -> updateProductPrice($entity -> sku, $store, $identifierType);
1224
+ $response[] = array('sku' => $entity -> sku, 'success' => $result);
1225
+ } catch (Exception $e) {
1226
+ $response[] = array('sku' => $entity -> sku, 'success' => false);
1227
+ }
1228
+ }
1229
+
1230
+ $this -> unlockIndexer();
1231
+
1232
+ return $response;
1233
+ }
1234
+
1235
+ /**
1236
+ * Bulk update simple products
1237
+ */
1238
+ public function updateSimpleProducts($data) {
1239
+
1240
+ $this -> lockIndexer();
1241
+
1242
+ $response = array();
1243
+
1244
+ for ($i = 0; $i < sizeof($data); $i++) {
1245
+ $entity = $data[$i];
1246
+ try {
1247
+ $result = $this -> updateSimpleProduct($entity -> productId, $entity -> productData, $entity -> store, $entity -> identifierType);
1248
+ $response[] = array('sku' => $entity -> sku, 'productId' => $entity -> productId, 'isError' => !$result);
1249
+ } catch (Exception $e) {
1250
+ $response[] = array('sku' => $entity -> sku, 'productId' => $entity -> productId, 'isError' => true, 'error' => $e -> getMessage());
1251
+ }
1252
+ }
1253
+
1254
+ $this -> unlockIndexer();
1255
 
1256
+ return $response;
1257
+ }
1258
+
1259
+ /**
1260
+ * Bulk update configurable products
1261
+ */
1262
+ public function updateConfigurableProducts($data) {
1263
+
1264
+ $this -> lockIndexer();
1265
+
1266
+ $response = array();
1267
+
1268
+ for ($i = 0; $i < sizeof($data); $i++) {
1269
+ $entity = $data[$i];
1270
+
1271
+ try {
1272
+ $result = $this -> updateConfigurableProduct($entity -> productId, false, $entity -> productData, $entity -> productsSet, $entity -> attributesSet, $entity -> store, $entity -> identifierType);
1273
+ $response[] = array('sku' => $entity -> sku, 'productId' => $entity -> productId, 'isError' => !$result);
1274
+ } catch (Exception $e) {
1275
+ $response[] = array('sku' => $entity -> sku, 'productId' => $entity -> productId, 'isError' => true, 'error' => $e -> getMessage());
1276
+ }
1277
+ }
1278
+
1279
+ $this -> unlockIndexer();
1280
+
1281
+ return $response;
1282
+ }
1283
+
1284
+ /**
1285
+ * Bulk delete products
1286
+ */
1287
+ public function deleteProducts($data) {
1288
+
1289
+ $this -> lockIndexer();
1290
+
1291
+ $response = array();
1292
+
1293
+ for ($i = 0; $i < sizeof($data); $i++) {
1294
+ $entity = $data[$i];
1295
+ try {
1296
+ $result = $this -> deleteProduct($entity -> productId, $entity -> store, $entity -> identifierType);
1297
+
1298
+ $response[] = array('sku' => $entity -> sku, 'productId' => $entity -> productId, 'isError' => !$result);
1299
+
1300
+ } catch (Exception $e) {
1301
+ $response[] = array('sku' => $entity -> sku, 'productId' => $entity -> productId, 'isError' => true, 'error' => $e -> getMessage());
1302
+ }
1303
+ }
1304
+
1305
+ $this -> unlockIndexer();
1306
+
1307
+ return $response;
1308
+ }
1309
+
1310
+ /**
1311
+ * Bulk delete related products
1312
+ */
1313
+ public function deleteRelatedProducts($data) {
1314
+
1315
+ $this -> lockIndexer();
1316
+
1317
+ $response = array();
1318
+
1319
+ for ($i = 0; $i < sizeof($data); $i++) {
1320
+ $entity = $data[$i];
1321
+ try {
1322
+ $result = $this -> deleteRelatedProduct($entity -> type, $entity -> productId, $entity -> linkedProductId, $entity -> identifierType);
1323
+ $response[] = array('relatedId' => $entity -> relatedId, 'productId' => $entity -> productId, 'isError' => !$result);
1324
+ } catch (Exception $e) {
1325
+ $response[] = array('relatedId' => $entity -> relatedId, 'productId' => $entity -> productId, 'isError' => true, 'error' => $e -> getMessage());
1326
+ }
1327
+ }
1328
+
1329
+ $this -> unlockIndexer();
1330
+
1331
+ return $response;
1332
+ }
1333
+
1334
+ /**
1335
+ * Bulk delete product images
1336
+ */
1337
+ public function deleteProductImages($data) {
1338
+
1339
+ $this -> lockIndexer();
1340
+
1341
+ $response = array();
1342
+
1343
+ for ($i = 0; $i < sizeof($data); $i++) {
1344
+ $entity = $data[$i];
1345
+ try {
1346
+ $result = $this -> deleteProductImage($entity -> productId, $entity -> file, $entity -> identifierType);
1347
+ $response[] = array('imageId' => $entity -> imageId, 'productId' => $entity -> productId, 'isError' => !$result);
1348
+ } catch (Exception $e) {
1349
+ $response[] = array('imageId' => $entity -> imageId, 'productId' => $entity -> productId, 'isError' => true, 'error' => $e -> getMessage());
1350
+ }
1351
+ }
1352
+
1353
+ $this -> unlockIndexer();
1354
+
1355
+ return $response;
1356
+ }
1357
+
1358
+ }
1359
  ?>
app/code/local/LinnSystems/LinnLiveConnect/etc/api.xml CHANGED
@@ -60,6 +60,60 @@
60
  <title>Get information about current magento settings</title>
61
  <acl>linnLive/getGeneralInfo</acl>
62
  </getGeneralInfo>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
63
  </methods>
64
 
65
  <faults module="linnLiveConnect">
@@ -119,6 +173,10 @@
119
  <code>113</code>
120
  <message>Invalid attributes 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.</message>
121
  </invalid_variation_attribute>
 
 
 
 
122
  </faults>
123
  </linnLive>
124
  </resources>
@@ -171,6 +229,46 @@
171
  <getGeneralInfo translate="title" module="linnLiveConnect">
172
  <title>Get information about current magento settings</title>
173
  </getGeneralInfo>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
174
  </linnLive>
175
  </resources>
176
  </acl>
60
  <title>Get information about current magento settings</title>
61
  <acl>linnLive/getGeneralInfo</acl>
62
  </getGeneralInfo>
63
+ <checkProducts translate="title" module="linnLiveConnect">
64
+ <title>Check product sku</title>
65
+ <acl>linnLive/checkProducts</acl>
66
+ </checkProducts>
67
+ <createSimpleProducts translate="title" module="linnLiveConnect">
68
+ <title>Bulk create products</title>
69
+ <acl>linnLive/createSimpleProducts</acl>
70
+ </createSimpleProducts>
71
+ <createConfigurableProducts translate="title" module="linnLiveConnect">
72
+ <title>Bulk create configurable products</title>
73
+ <acl>linnLive/createConfigurableProducts</acl>
74
+ </createConfigurableProducts>
75
+ <updateSimpleProducts translate="title" module="linnLiveConnect">
76
+ <title>Bulk update products</title>
77
+ <acl>linnLive/updateSimpleProducts</acl>
78
+ </updateSimpleProducts>
79
+ <updateConfigurableProducts translate="title" module="linnLiveConnect">
80
+ <title>Bulk update configurable products</title>
81
+ <acl>linnLive/updateConfigurableProducts</acl>
82
+ </updateConfigurableProducts>
83
+ <deleteProducts translate="title" module="linnLiveConnect">
84
+ <title>Bulk delete products</title>
85
+ <acl>linnLive/deleteProducts</acl>
86
+ </deleteProducts>
87
+
88
+ <createRelatedProducts translate="title" module="linnLiveConnect">
89
+ <title>Bulk create related products</title>
90
+ <acl>linnLive/createRelatedProducts</acl>
91
+ </createRelatedProducts>
92
+ <deleteRelatedProducts translate="title" module="linnLiveConnect">
93
+ <title>Bulk delete related products</title>
94
+ <acl>linnLive/deleteRelatedProducts</acl>
95
+ </deleteRelatedProducts>
96
+ <createProductImages translate="title" module="linnLiveConnect">
97
+ <title>Bulk create product images</title>
98
+ <acl>linnLive/createProductImages</acl>
99
+ </createProductImages>
100
+ <updateProductImages translate="title" module="linnLiveConnect">
101
+ <title>Bulk update product images</title>
102
+ <acl>linnLive/updateProductImages</acl>
103
+ </updateProductImages>
104
+ <deleteProductImages translate="title" module="linnLiveConnect">
105
+ <title>Bulk delete product images</title>
106
+ <acl>linnLive/deleteProductImages</acl>
107
+ </deleteProductImages>
108
+ <disableIndexing translate="title" module="linnLiveConnect">
109
+ <title>Set manual indexing mode</title>
110
+ <acl>linnLive/disableIndexing</acl>
111
+ </disableIndexing>
112
+ <restoreIndexingById translate="title" module="linnLiveConnect">
113
+ <title>Restore indexing mode</title>
114
+ <acl>linnLive/restoreIndexingById</acl>
115
+ </restoreIndexingById>
116
+
117
  </methods>
118
 
119
  <faults module="linnLiveConnect">
173
  <code>113</code>
174
  <message>Invalid attributes 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.</message>
175
  </invalid_variation_attribute>
176
+ <image_not_exists>
177
+ <code>114</code>
178
+ <message>Image not found, it might have been deleted from Magento.</message>
179
+ </image_not_exists>
180
  </faults>
181
  </linnLive>
182
  </resources>
229
  <getGeneralInfo translate="title" module="linnLiveConnect">
230
  <title>Get information about current magento settings</title>
231
  </getGeneralInfo>
232
+ <checkProducts translate="title" module="linnLiveConnect">
233
+ <title>Check product sku</title>
234
+ </checkProducts>
235
+ <createSimpleProducts translate="title" module="linnLiveConnect">
236
+ <title>Bulk create products</title>
237
+ </createSimpleProducts>
238
+ <createConfigurableProducts translate="title" module="linnLiveConnect">
239
+ <title>Bulk create configurable products</title>
240
+ </createConfigurableProducts>
241
+ <updateSimpleProducts translate="title" module="linnLiveConnect">
242
+ <title>Bulk update products</title>
243
+ </updateSimpleProducts>
244
+ <updateConfigurableProducts translate="title" module="linnLiveConnect">
245
+ <title>Bulk update configurable products</title>
246
+ </updateConfigurableProducts>
247
+ <deleteProducts translate="title" module="linnLiveConnect">
248
+ <title>Bulk delete products</title>
249
+ </deleteProducts>
250
+ <createRelatedProducts translate="title" module="linnLiveConnect">
251
+ <title>Bulk create related products</title>
252
+ </createRelatedProducts>
253
+ <deleteRelatedProducts translate="title" module="linnLiveConnect">
254
+ <title>Bulk delete related products</title>
255
+ </deleteRelatedProducts>
256
+ <createProductImages translate="title" module="linnLiveConnect">
257
+ <title>Bulk create product images</title>
258
+ </createProductImages>
259
+ <updateProductImages translate="title" module="linnLiveConnect">
260
+ <title>Bulk update product images</title>
261
+ </updateProductImages>
262
+ <deleteProductImages translate="title" module="linnLiveConnect">
263
+ <title>Bulk delete product images</title>
264
+ </deleteProductImages>
265
+ <disableIndexing translate="title" module="linnLiveConnect">
266
+ <title>Set manual indexing mode</title>
267
+ </disableIndexing>
268
+ <restoreIndexingById translate="title" module="linnLiveConnect">
269
+ <title>Restore indexing mode</title>
270
+ </restoreIndexingById>
271
+
272
  </linnLive>
273
  </resources>
274
  </acl>
app/code/local/LinnSystems/LinnLiveConnect/etc/config.xml CHANGED
@@ -2,7 +2,7 @@
2
  <config>
3
  <modules>
4
  <LinnSystems_LinnLiveConnect>
5
- <version>1.1.52</version>
6
  </LinnSystems_LinnLiveConnect>
7
  </modules>
8
  <global>
2
  <config>
3
  <modules>
4
  <LinnSystems_LinnLiveConnect>
5
+ <version>1.1.53</version>
6
  </LinnSystems_LinnLiveConnect>
7
  </modules>
8
  <global>
app/code/local/LinnSystems/LinnLiveConnect/etc/wsi.xml CHANGED
@@ -15,6 +15,8 @@
15
  <xsd:element minOccurs="1" maxOccurs="1" name="magento_ver" type="xsd:string" />
16
  <xsd:element minOccurs="1" maxOccurs="1" name="php_ver" type="xsd:string" />
17
  <xsd:element minOccurs="0" maxOccurs="1" name="api_config" type="typens:linnLiveGetGeneralInfoApiConfigResponseDataEntity" />
 
 
18
  </xsd:sequence>
19
  </xsd:complexType>
20
 
@@ -201,7 +203,208 @@
201
  <xsd:element minOccurs="1" name="magento_ver" type="typens:linnLiveInfoMagentoVer" />
202
  </xsd:sequence>
203
  </xsd:complexType>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
204
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
205
  <!-- Products List data sets-->
206
  <xsd:complexType name="linnLiveImagesArray">
207
  <xsd:sequence>
@@ -512,6 +715,9 @@
512
  </xsd:complexType>
513
  </xsd:element>
514
 
 
 
 
515
  <xsd:element name="linnLiveUpdatePriceBulkRequestParam">
516
  <xsd:complexType>
517
  <xsd:sequence>
@@ -530,8 +736,233 @@
530
  </xsd:sequence>
531
  </xsd:complexType>
532
  </xsd:element>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
533
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
534
 
 
535
  <xsd:element name="linnLiveProductListRequestParam">
536
  <xsd:complexType>
537
  <xsd:sequence>
@@ -587,7 +1018,8 @@
587
  </xsd:sequence>
588
  </xsd:complexType>
589
  </xsd:element>
590
- </xsd:schema>
 
591
  </wsdl:types>
592
 
593
  <!-- Attribute options enchancement -->
@@ -648,7 +1080,6 @@
648
  <wsdl:part name="parameters" element="typens:linnLiveGetGeneralInfoResponseParam" />
649
  </wsdl:message>
650
 
651
-
652
  <wsdl:message name="linnLiveGetProductStoreURLRequest">
653
  <wsdl:part name="parameters" element="typens:linnLiveGetProductStoreURLRequestParam" />
654
  </wsdl:message>
@@ -656,6 +1087,21 @@
656
  <wsdl:part name="parameters" element="typens:linnLiveGetProductStoreURLResponseParam" />
657
  </wsdl:message>
658
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
659
  <wsdl:message name="linnLiveUpdatePriceBulkRequest">
660
  <wsdl:part name="parameters" element="typens:linnLiveUpdatePriceBulkRequestParam" />
661
  </wsdl:message>
@@ -663,6 +1109,87 @@
663
  <wsdl:part name="parameters" element="typens:linnLiveUpdatePriceBulkResponseParam" />
664
  </wsdl:message>
665
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
666
  <wsdl:message name="linnLiveProductListRequest">
667
  <wsdl:part name="parameters" element="typens:linnLiveProductListRequestParam" />
668
  </wsdl:message>
@@ -700,7 +1227,7 @@
700
  <wsdl:message name="catalogProductAttributeRemoveResponse">
701
  <wsdl:part name="parameters" element="typens:linnLiveAttributeRemoveResponseParam" />
702
  </wsdl:message>
703
- <!-- Stub parameters for catalogProductAttributeRemove end -->
704
 
705
 
706
 
@@ -751,12 +1278,91 @@
751
  <wsdl:output message="typens:linnLiveGetStoreCodeResponse" />
752
  </wsdl:operation>
753
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
754
  <wsdl:operation name="linnLiveGetProductStoreURL">
755
  <wsdl:documentation>Get product url</wsdl:documentation>
756
  <wsdl:input message="typens:linnLiveGetProductStoreURLRequest" />
757
  <wsdl:output message="typens:linnLiveGetProductStoreURLResponse" />
758
  </wsdl:operation>
759
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
760
  <wsdl:operation name="linnLiveGetGeneralInfo">
761
  <wsdl:documentation>Get general information</wsdl:documentation>
762
  <wsdl:input message="typens:linnLiveGetGeneralInfoRequest" />
@@ -781,7 +1387,7 @@
781
  <wsdl:input message="typens:catalogProductAttributeRemoveRequest" />
782
  <wsdl:output message="typens:catalogProductAttributeRemoveResponse" />
783
  </wsdl:operation>
784
- <!-- remove for 1.8 -->
785
 
786
  <wsdl:operation name="linnLiveInfo">
787
  <wsdl:documentation>Get information about current magento settings and installation</wsdl:documentation>
@@ -887,6 +1493,57 @@
887
  </wsdl:output>
888
  </wsdl:operation>
889
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
890
  <wsdl:operation name="linnLiveGetProductStoreURL">
891
  <soap:operation soapAction="" />
892
  <wsdl:input>
@@ -897,6 +1554,88 @@
897
  </wsdl:output>
898
  </wsdl:operation>
899
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
900
  <wsdl:operation name="linnLiveGetGeneralInfo">
901
  <soap:operation soapAction="" />
902
  <wsdl:input>
15
  <xsd:element minOccurs="1" maxOccurs="1" name="magento_ver" type="xsd:string" />
16
  <xsd:element minOccurs="1" maxOccurs="1" name="php_ver" type="xsd:string" />
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
 
203
  <xsd:element minOccurs="1" name="magento_ver" type="typens:linnLiveInfoMagentoVer" />
204
  </xsd:sequence>
205
  </xsd:complexType>
206
+
207
+ <!-- check products start-->
208
+ <xsd:complexType name="linnLiveCheckProductsRequestEntity">
209
+ <xsd:sequence>
210
+ <xsd:element minOccurs="1" maxOccurs="1" name="sku" type="xsd:string" />
211
+ <xsd:element minOccurs="1" maxOccurs="1" name="store" type="xsd:string" />
212
+ <xsd:element minOccurs="1" maxOccurs="1" name="identifierType" type="xsd:string" />
213
+ </xsd:sequence>
214
+ </xsd:complexType>
215
+
216
+ <xsd:complexType name="linnLiveCheckProductsRequestArray">
217
+ <xsd:sequence>
218
+ <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:linnLiveCheckProductsRequestEntity" />
219
+ </xsd:sequence>
220
+ </xsd:complexType>
221
+ <!-- check products end-->
222
+
223
+ <!-- create products start-->
224
+ <xsd:complexType name="linnLiveCreateProductsRequestEntity">
225
+ <xsd:sequence>
226
+ <xsd:element minOccurs="1" maxOccurs="1" name="sku" type="xsd:string" />
227
+ <xsd:element minOccurs="1" maxOccurs="1" name="productData" type="typens:linnLiveProductCreateEntity" />
228
+ <xsd:element minOccurs="0" maxOccurs="1" name="set" type="xsd:string" />
229
+ <xsd:element minOccurs="0" maxOccurs="1" name="productsSet" type="typens:linnLiveConfigurableAssignedProductsArray" />
230
+ <xsd:element minOccurs="0" maxOccurs="1" name="attributesSet" type="typens:linnLiveConfigurableAssignedAttributesArray" />
231
+ <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
232
+ </xsd:sequence>
233
+ </xsd:complexType>
234
+
235
+ <xsd:complexType name="linnLiveCreateProductsRequestArray">
236
+ <xsd:sequence>
237
+ <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:linnLiveCreateProductsRequestEntity" />
238
+ </xsd:sequence>
239
+ </xsd:complexType>
240
+ <!-- create products end-->
241
+
242
+
243
+
244
+ <!-- update products start-->
245
+ <xsd:complexType name="linnLiveUpdateProductsRequestEntity">
246
+ <xsd:sequence>
247
+ <xsd:element minOccurs="1" maxOccurs="1" name="sku" type="xsd:string" />
248
+ <xsd:element minOccurs="1" maxOccurs="1" name="productId" type="xsd:string" />
249
+ <xsd:element minOccurs="1" maxOccurs="1" name="productData" type="typens:linnLiveProductCreateEntity" />
250
+ <xsd:element minOccurs="0" maxOccurs="1" name="productsSet" type="typens:linnLiveConfigurableAssignedProductsArray" />
251
+ <xsd:element minOccurs="0" maxOccurs="1" name="attributesSet" type="typens:linnLiveConfigurableAssignedAttributesArray" />
252
+ <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
253
+ <xsd:element minOccurs="1" maxOccurs="1" name="identifierType" type="xsd:string" />
254
+ </xsd:sequence>
255
+ </xsd:complexType>
256
+
257
+ <xsd:complexType name="linnLiveUpdateProductsRequestArray">
258
+ <xsd:sequence>
259
+ <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:linnLiveUpdateProductsRequestEntity" />
260
+ </xsd:sequence>
261
+ </xsd:complexType>
262
+ <!-- update products end-->
263
+
264
+ <!-- delete products start-->
265
+ <xsd:complexType name="linnLiveDeleteProductsRequestEntity">
266
+ <xsd:sequence>
267
+ <xsd:element minOccurs="1" maxOccurs="1" name="sku" type="xsd:string" />
268
+ <xsd:element minOccurs="1" maxOccurs="1" name="productId" type="xsd:string" />
269
+ <xsd:element minOccurs="1" maxOccurs="1" name="store" type="xsd:string" />
270
+ <xsd:element minOccurs="1" maxOccurs="1" name="identifierType" type="xsd:string" />
271
+ </xsd:sequence>
272
+ </xsd:complexType>
273
+
274
+ <xsd:complexType name="linnLiveDeleteProductsRequestArray">
275
+ <xsd:sequence>
276
+ <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:linnLiveDeleteProductsRequestEntity" />
277
+ </xsd:sequence>
278
+ </xsd:complexType>
279
+ <!-- delete products end-->
280
+
281
+
282
+ <!-- bulk related products start-->
283
+ <xsd:complexType name="linnLiveRelatedProductsRequestEntity">
284
+ <xsd:sequence>
285
+ <xsd:element minOccurs="1" maxOccurs="1" name="relatedId" type="xsd:string" />
286
+ <xsd:element minOccurs="1" maxOccurs="1" name="productId" type="xsd:string" />
287
+ <xsd:element minOccurs="1" maxOccurs="1" name="linkedProductId" type="xsd:string" />
288
+ <xsd:element minOccurs="1" maxOccurs="1" name="type" type="xsd:string"/>
289
+ </xsd:sequence>
290
+ </xsd:complexType>
291
+
292
+ <xsd:complexType name="linnLiveRelatedProductsRequestArray">
293
+ <xsd:sequence>
294
+ <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:linnLiveRelatedProductsRequestEntity" />
295
+ </xsd:sequence>
296
+ </xsd:complexType>
297
+ <!-- bulk related products end-->
298
+
299
+
300
+ <!-- bulk general response start-->
301
+ <xsd:complexType name="linnLiveBulkResultResponseEntity">
302
+ <xsd:sequence>
303
+ <xsd:element minOccurs="1" name="sku" type="xsd:string" />
304
+ <xsd:element minOccurs="1" name="productId" type="xsd:int" />
305
+ <xsd:element minOccurs="1" name="isError" type="xsd:boolean" />
306
+ <xsd:element minOccurs="0" name="error" type="xsd:string" />
307
+ </xsd:sequence>
308
+ </xsd:complexType>
309
+
310
+ <xsd:complexType name="linnLiveBulkResultResponseArray">
311
+ <xsd:sequence>
312
+ <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:linnLiveBulkResultResponseEntity" />
313
+ </xsd:sequence>
314
+ </xsd:complexType>
315
+ <!-- bulk general response end-->
316
 
317
+ <!-- bulk image response start-->
318
+ <xsd:complexType name="linnLiveBulkImageResponseEntity">
319
+ <xsd:sequence>
320
+ <xsd:element minOccurs="1" name="imageId" type="xsd:string" />
321
+ <xsd:element minOccurs="1" name="productId" type="xsd:int" />
322
+ <xsd:element minOccurs="1" name="isError" type="xsd:boolean" />
323
+ <xsd:element minOccurs="0" name="error" type="xsd:string" />
324
+ <xsd:element minOccurs="0" name="file" type="xsd:string" />
325
+ </xsd:sequence>
326
+ </xsd:complexType>
327
+
328
+ <xsd:complexType name="linnLiveBulkImageResponseArray">
329
+ <xsd:sequence>
330
+ <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:linnLiveBulkImageResponseEntity" />
331
+ </xsd:sequence>
332
+ </xsd:complexType>
333
+ <!-- bulk product response end-->
334
+
335
+
336
+ <!-- bulk related response start-->
337
+ <xsd:complexType name="linnLiveBulkRelatedProductsResponseEntity">
338
+ <xsd:sequence>
339
+ <xsd:element minOccurs="1" name="relatedId" type="xsd:string" />
340
+ <xsd:element minOccurs="1" name="productId" type="xsd:int" />
341
+ <xsd:element minOccurs="1" name="isError" type="xsd:boolean" />
342
+ <xsd:element minOccurs="0" name="error" type="xsd:string" />
343
+ </xsd:sequence>
344
+ </xsd:complexType>
345
+
346
+ <xsd:complexType name="linnLiveBulkRelatedProductsResponseArray">
347
+ <xsd:sequence>
348
+ <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:linnLiveBulkRelatedProductsResponseEntity" />
349
+ </xsd:sequence>
350
+ </xsd:complexType>
351
+ <!-- bulk related response end-->
352
+
353
+ <!-- create image start-->
354
+ <xsd:complexType name="linnLiveCreateProductImagesRequestEntity">
355
+ <xsd:sequence>
356
+ <xsd:element minOccurs="1" maxOccurs="1" name="imageId" type="xsd:string" />
357
+ <xsd:element minOccurs="1" maxOccurs="1" name="productId" type="xsd:string" />
358
+ <xsd:element minOccurs="1" maxOccurs="1" name="data" type="typens:catalogProductAttributeMediaCreateEntity" />
359
+ <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
360
+ <xsd:element minOccurs="0" maxOccurs="1" name="identifierType" type="xsd:string" />
361
+ </xsd:sequence>
362
+ </xsd:complexType>
363
+
364
+ <xsd:complexType name="linnLiveCreateProductImagesRequestArray">
365
+ <xsd:sequence>
366
+ <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:linnLiveCreateProductImagesRequestEntity" />
367
+ </xsd:sequence>
368
+ </xsd:complexType>
369
+ <!-- create image end-->
370
+
371
+ <!-- update image start-->
372
+ <xsd:complexType name="linnLiveUpdateProductImagesRequestEntity">
373
+ <xsd:sequence>
374
+ <xsd:element minOccurs="1" maxOccurs="1" name="imageId" type="xsd:string" />
375
+ <xsd:element minOccurs="1" maxOccurs="1" name="productId" type="xsd:string" />
376
+ <xsd:element minOccurs="1" maxOccurs="1" name="file" type="xsd:string" />
377
+ <xsd:element minOccurs="1" maxOccurs="1" name="data" type="typens:catalogProductAttributeMediaCreateEntity" />
378
+ <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
379
+ <xsd:element minOccurs="0" maxOccurs="1" name="identifierType" type="xsd:string" />
380
+ </xsd:sequence>
381
+ </xsd:complexType>
382
+
383
+ <xsd:complexType name="linnLiveUpdateProductImagesRequestArray">
384
+ <xsd:sequence>
385
+ <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:linnLiveUpdateProductImagesRequestEntity" />
386
+ </xsd:sequence>
387
+ </xsd:complexType>
388
+ <!-- update image end-->
389
+
390
+ <!-- delete image start-->
391
+ <xsd:complexType name="linnLiveDeleteProductImagesRequestEntity">
392
+ <xsd:sequence>
393
+ <xsd:element minOccurs="1" maxOccurs="1" name="imageId" type="xsd:string" />
394
+ <xsd:element minOccurs="1" maxOccurs="1" name="productId" type="xsd:string"></xsd:element>
395
+ <xsd:element minOccurs="1" maxOccurs="1" name="file" type="xsd:string"></xsd:element>
396
+ <xsd:element minOccurs="0" maxOccurs="1" name="identifierType" type="xsd:string"></xsd:element>
397
+ </xsd:sequence>
398
+ </xsd:complexType>
399
+
400
+ <xsd:complexType name="linnLiveDeleteProductImagesRequestArray">
401
+ <xsd:sequence>
402
+ <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:linnLiveDeleteProductImagesRequestEntity" />
403
+ </xsd:sequence>
404
+ </xsd:complexType>
405
+ <!-- delete image end-->
406
+
407
+
408
  <!-- Products List data sets-->
409
  <xsd:complexType name="linnLiveImagesArray">
410
  <xsd:sequence>
715
  </xsd:complexType>
716
  </xsd:element>
717
 
718
+
719
+
720
+
721
  <xsd:element name="linnLiveUpdatePriceBulkRequestParam">
722
  <xsd:complexType>
723
  <xsd:sequence>
736
  </xsd:sequence>
737
  </xsd:complexType>
738
  </xsd:element>
739
+
740
+ <xsd:element name="linnLiveDisableIndexingRequestParam">
741
+ <xsd:complexType>
742
+ <xsd:sequence>
743
+ <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
744
+ <xsd:element minOccurs="1" maxOccurs="1" name="version" type="xsd:int" />
745
+ </xsd:sequence>
746
+ </xsd:complexType>
747
+ </xsd:element>
748
+ <xsd:element name="linnLiveDisableIndexingResponseParam">
749
+ <xsd:complexType>
750
+ <xsd:sequence>
751
+ <xsd:element name="result" minOccurs="0" type="typens:associativeArray"/>
752
+ </xsd:sequence>
753
+ </xsd:complexType>
754
+ </xsd:element>
755
+
756
+ <xsd:element name="linnLiveRestoreIndexingByIdRequestParam">
757
+ <xsd:complexType>
758
+ <xsd:sequence>
759
+ <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
760
+ <xsd:element minOccurs="1" maxOccurs="1" name="version" type="xsd:int" />
761
+ <xsd:element name="data" minOccurs="0" type="typens:associativeArray"/>
762
+ </xsd:sequence>
763
+ </xsd:complexType>
764
+ </xsd:element>
765
+ <xsd:element name="linnLiveRestoreIndexingByIdResponseParam">
766
+ <xsd:complexType>
767
+ <xsd:sequence>
768
+ <xsd:element minOccurs="0" name="result" type="xsd:boolean" />
769
+ </xsd:sequence>
770
+ </xsd:complexType>
771
+ </xsd:element>
772
+
773
+
774
+ <xsd:element name="linnLiveCheckProductsRequestParam">
775
+ <xsd:complexType>
776
+ <xsd:sequence>
777
+ <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
778
+ <xsd:element minOccurs="1" maxOccurs="1" name="version" type="xsd:int" />
779
+ <xsd:element minOccurs="1" maxOccurs="1" name="data" type="typens:linnLiveCheckProductsRequestArray" />
780
+ </xsd:sequence>
781
+ </xsd:complexType>
782
+ </xsd:element>
783
+ <xsd:element name="linnLiveCheckProductsResponseParam">
784
+ <xsd:complexType>
785
+ <xsd:sequence>
786
+ <xsd:element name="result" minOccurs="0" type="typens:linnLiveBulkResultResponseArray"/>
787
+ </xsd:sequence>
788
+ </xsd:complexType>
789
+ </xsd:element>
790
+
791
+ <xsd:element name="linnLiveCreateSimpleProductsRequestParam">
792
+ <xsd:complexType>
793
+ <xsd:sequence>
794
+ <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
795
+ <xsd:element minOccurs="1" maxOccurs="1" name="version" type="xsd:int" />
796
+ <xsd:element minOccurs="1" maxOccurs="1" name="data" type="typens:linnLiveCreateProductsRequestArray" />
797
+ </xsd:sequence>
798
+ </xsd:complexType>
799
+ </xsd:element>
800
+ <xsd:element name="linnLiveCreateSimpleProductsResponseParam">
801
+ <xsd:complexType>
802
+ <xsd:sequence>
803
+ <xsd:element name="result" minOccurs="0" type="typens:linnLiveBulkResultResponseArray"/>
804
+ </xsd:sequence>
805
+ </xsd:complexType>
806
+ </xsd:element>
807
 
808
+ <xsd:element name="linnLiveCreateConfigurableProductsRequestParam">
809
+ <xsd:complexType>
810
+ <xsd:sequence>
811
+ <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
812
+ <xsd:element minOccurs="1" maxOccurs="1" name="version" type="xsd:int" />
813
+ <xsd:element minOccurs="1" maxOccurs="1" name="data" type="typens:linnLiveCreateProductsRequestArray" />
814
+ </xsd:sequence>
815
+ </xsd:complexType>
816
+ </xsd:element>
817
+ <xsd:element name="linnLiveCreateConfigurableProductsResponseParam">
818
+ <xsd:complexType>
819
+ <xsd:sequence>
820
+ <xsd:element name="result" minOccurs="0" type="typens:linnLiveBulkResultResponseArray"/>
821
+ </xsd:sequence>
822
+ </xsd:complexType>
823
+ </xsd:element>
824
+
825
+
826
+ <xsd:element name="linnLiveUpdateSimpleProductsRequestParam">
827
+ <xsd:complexType>
828
+ <xsd:sequence>
829
+ <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
830
+ <xsd:element minOccurs="1" maxOccurs="1" name="version" type="xsd:int" />
831
+ <xsd:element minOccurs="1" maxOccurs="1" name="data" type="typens:linnLiveUpdateProductsRequestArray" />
832
+ </xsd:sequence>
833
+ </xsd:complexType>
834
+ </xsd:element>
835
+ <xsd:element name="linnLiveUpdateSimpleProductsResponseParam">
836
+ <xsd:complexType>
837
+ <xsd:sequence>
838
+ <xsd:element name="result" minOccurs="0" type="typens:linnLiveBulkResultResponseArray"/>
839
+ </xsd:sequence>
840
+ </xsd:complexType>
841
+ </xsd:element>
842
+
843
+
844
+ <xsd:element name="linnLiveUpdateConfigurableProductsRequestParam">
845
+ <xsd:complexType>
846
+ <xsd:sequence>
847
+ <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
848
+ <xsd:element minOccurs="1" maxOccurs="1" name="version" type="xsd:int" />
849
+ <xsd:element minOccurs="1" maxOccurs="1" name="data" type="typens:linnLiveUpdateProductsRequestArray" />
850
+ </xsd:sequence>
851
+ </xsd:complexType>
852
+ </xsd:element>
853
+ <xsd:element name="linnLiveUpdateConfigurableProductsResponseParam">
854
+ <xsd:complexType>
855
+ <xsd:sequence>
856
+ <xsd:element name="result" minOccurs="0" type="typens:linnLiveBulkResultResponseArray"/>
857
+ </xsd:sequence>
858
+ </xsd:complexType>
859
+ </xsd:element>
860
+
861
+
862
+ <xsd:element name="linnLiveDeleteProductsRequestParam">
863
+ <xsd:complexType>
864
+ <xsd:sequence>
865
+ <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
866
+ <xsd:element minOccurs="1" maxOccurs="1" name="version" type="xsd:int" />
867
+ <xsd:element minOccurs="1" maxOccurs="1" name="data" type="typens:linnLiveDeleteProductsRequestArray" />
868
+ </xsd:sequence>
869
+ </xsd:complexType>
870
+ </xsd:element>
871
+ <xsd:element name="linnLiveDeleteProductsResponseParam">
872
+ <xsd:complexType>
873
+ <xsd:sequence>
874
+ <xsd:element name="result" minOccurs="0" type="typens:linnLiveBulkResultResponseArray"/>
875
+ </xsd:sequence>
876
+ </xsd:complexType>
877
+ </xsd:element>
878
+
879
+ <xsd:element name="linnLiveCreateRelatedProductsRequestParam">
880
+ <xsd:complexType>
881
+ <xsd:sequence>
882
+ <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
883
+ <xsd:element minOccurs="1" maxOccurs="1" name="version" type="xsd:int" />
884
+ <xsd:element minOccurs="1" maxOccurs="1" name="data" type="typens:linnLiveRelatedProductsRequestArray" />
885
+ </xsd:sequence>
886
+ </xsd:complexType>
887
+ </xsd:element>
888
+ <xsd:element name="linnLiveCreateRelatedProductsResponseParam">
889
+ <xsd:complexType>
890
+ <xsd:sequence>
891
+ <xsd:element name="result" minOccurs="0" type="typens:linnLiveBulkRelatedProductsResponseArray"/>
892
+ </xsd:sequence>
893
+ </xsd:complexType>
894
+ </xsd:element>
895
+
896
+ <xsd:element name="linnLiveDeleteRelatedProductsRequestParam">
897
+ <xsd:complexType>
898
+ <xsd:sequence>
899
+ <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
900
+ <xsd:element minOccurs="1" maxOccurs="1" name="version" type="xsd:int" />
901
+ <xsd:element minOccurs="1" maxOccurs="1" name="data" type="typens:linnLiveRelatedProductsRequestArray" />
902
+ </xsd:sequence>
903
+ </xsd:complexType>
904
+ </xsd:element>
905
+ <xsd:element name="linnLiveDeleteRelatedProductsResponseParam">
906
+ <xsd:complexType>
907
+ <xsd:sequence>
908
+ <xsd:element name="result" minOccurs="0" type="typens:linnLiveBulkRelatedProductsResponseArray"/>
909
+ </xsd:sequence>
910
+ </xsd:complexType>
911
+ </xsd:element>
912
+
913
+ <xsd:element name="linnLiveCreateProductImagesRequestParam">
914
+ <xsd:complexType>
915
+ <xsd:sequence>
916
+ <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
917
+ <xsd:element minOccurs="1" maxOccurs="1" name="version" type="xsd:int" />
918
+ <xsd:element minOccurs="1" maxOccurs="1" name="data" type="typens:linnLiveCreateProductImagesRequestArray" />
919
+ </xsd:sequence>
920
+ </xsd:complexType>
921
+ </xsd:element>
922
+ <xsd:element name="linnLiveCreateProductImagesResponseParam">
923
+ <xsd:complexType>
924
+ <xsd:sequence>
925
+ <xsd:element name="result" minOccurs="0" type="typens:linnLiveBulkImageResponseArray"/>
926
+ </xsd:sequence>
927
+ </xsd:complexType>
928
+ </xsd:element>
929
+
930
+ <xsd:element name="linnLiveUpdateProductImagesRequestParam">
931
+ <xsd:complexType>
932
+ <xsd:sequence>
933
+ <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
934
+ <xsd:element minOccurs="1" maxOccurs="1" name="version" type="xsd:int" />
935
+ <xsd:element minOccurs="1" maxOccurs="1" name="data" type="typens:linnLiveUpdateProductImagesRequestArray" />
936
+ </xsd:sequence>
937
+ </xsd:complexType>
938
+ </xsd:element>
939
+ <xsd:element name="linnLiveUpdateProductImagesResponseParam">
940
+ <xsd:complexType>
941
+ <xsd:sequence>
942
+ <xsd:element name="result" minOccurs="0" type="typens:linnLiveBulkImageResponseArray"/>
943
+ </xsd:sequence>
944
+ </xsd:complexType>
945
+ </xsd:element>
946
+
947
+ <xsd:element name="linnLiveDeleteProductImagesRequestParam">
948
+ <xsd:complexType>
949
+ <xsd:sequence>
950
+ <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
951
+ <xsd:element minOccurs="1" maxOccurs="1" name="version" type="xsd:int" />
952
+ <xsd:element minOccurs="1" maxOccurs="1" name="data" type="typens:linnLiveDeleteProductImagesRequestArray" />
953
+ </xsd:sequence>
954
+ </xsd:complexType>
955
+ </xsd:element>
956
+ <xsd:element name="linnLiveDeleteProductImagesResponseParam">
957
+ <xsd:complexType>
958
+ <xsd:sequence>
959
+ <xsd:element name="result" minOccurs="0" type="typens:linnLiveBulkImageResponseArray"/>
960
+ </xsd:sequence>
961
+ </xsd:complexType>
962
+ </xsd:element>
963
+
964
 
965
+
966
  <xsd:element name="linnLiveProductListRequestParam">
967
  <xsd:complexType>
968
  <xsd:sequence>
1018
  </xsd:sequence>
1019
  </xsd:complexType>
1020
  </xsd:element>
1021
+
1022
+ </xsd:schema>
1023
  </wsdl:types>
1024
 
1025
  <!-- Attribute options enchancement -->
1080
  <wsdl:part name="parameters" element="typens:linnLiveGetGeneralInfoResponseParam" />
1081
  </wsdl:message>
1082
 
 
1083
  <wsdl:message name="linnLiveGetProductStoreURLRequest">
1084
  <wsdl:part name="parameters" element="typens:linnLiveGetProductStoreURLRequestParam" />
1085
  </wsdl:message>
1087
  <wsdl:part name="parameters" element="typens:linnLiveGetProductStoreURLResponseParam" />
1088
  </wsdl:message>
1089
 
1090
+
1091
+ <wsdl:message name="linnLiveDisableIndexingRequest">
1092
+ <wsdl:part name="parameters" element="typens:linnLiveDisableIndexingRequestParam" />
1093
+ </wsdl:message>
1094
+ <wsdl:message name="linnLiveDisableIndexingResponse">
1095
+ <wsdl:part name="parameters" element="typens:linnLiveDisableIndexingResponseParam" />
1096
+ </wsdl:message>
1097
+
1098
+ <wsdl:message name="linnLiveRestoreIndexingByIdRequest">
1099
+ <wsdl:part name="parameters" element="typens:linnLiveRestoreIndexingByIdRequestParam" />
1100
+ </wsdl:message>
1101
+ <wsdl:message name="linnLiveRestoreIndexingByIdResponse">
1102
+ <wsdl:part name="parameters" element="typens:linnLiveRestoreIndexingByIdResponseParam" />
1103
+ </wsdl:message>
1104
+
1105
  <wsdl:message name="linnLiveUpdatePriceBulkRequest">
1106
  <wsdl:part name="parameters" element="typens:linnLiveUpdatePriceBulkRequestParam" />
1107
  </wsdl:message>
1109
  <wsdl:part name="parameters" element="typens:linnLiveUpdatePriceBulkResponseParam" />
1110
  </wsdl:message>
1111
 
1112
+
1113
+
1114
+ <wsdl:message name="linnLiveCheckProductsRequest">
1115
+ <wsdl:part name="parameters" element="typens:linnLiveCheckProductsRequestParam" />
1116
+ </wsdl:message>
1117
+ <wsdl:message name="linnLiveCheckProductsResponse">
1118
+ <wsdl:part name="parameters" element="typens:linnLiveCheckProductsResponseParam" />
1119
+ </wsdl:message>
1120
+
1121
+ <wsdl:message name="linnLiveCreateSimpleProductsRequest">
1122
+ <wsdl:part name="parameters" element="typens:linnLiveCreateSimpleProductsRequestParam" />
1123
+ </wsdl:message>
1124
+ <wsdl:message name="linnLiveCreateSimpleProductsResponse">
1125
+ <wsdl:part name="parameters" element="typens:linnLiveCreateSimpleProductsResponseParam" />
1126
+ </wsdl:message>
1127
+
1128
+ <wsdl:message name="linnLiveCreateConfigurableProductsRequest">
1129
+ <wsdl:part name="parameters" element="typens:linnLiveCreateConfigurableProductsRequestParam" />
1130
+ </wsdl:message>
1131
+ <wsdl:message name="linnLiveCreateConfigurableProductsResponse">
1132
+ <wsdl:part name="parameters" element="typens:linnLiveCreateConfigurableProductsResponseParam" />
1133
+ </wsdl:message>
1134
+
1135
+ <wsdl:message name="linnLiveUpdateSimpleProductsRequest">
1136
+ <wsdl:part name="parameters" element="typens:linnLiveUpdateSimpleProductsRequestParam" />
1137
+ </wsdl:message>
1138
+ <wsdl:message name="linnLiveUpdateSimpleProductsResponse">
1139
+ <wsdl:part name="parameters" element="typens:linnLiveUpdateSimpleProductsResponseParam" />
1140
+ </wsdl:message>
1141
+
1142
+ <wsdl:message name="linnLiveUpdateConfigurableProductsRequest">
1143
+ <wsdl:part name="parameters" element="typens:linnLiveUpdateConfigurableProductsRequestParam" />
1144
+ </wsdl:message>
1145
+ <wsdl:message name="linnLiveUpdateConfigurableProductsResponse">
1146
+ <wsdl:part name="parameters" element="typens:linnLiveUpdateConfigurableProductsResponseParam" />
1147
+ </wsdl:message>
1148
+
1149
+ <wsdl:message name="linnLiveDeleteProductsRequest">
1150
+ <wsdl:part name="parameters" element="typens:linnLiveDeleteProductsRequestParam" />
1151
+ </wsdl:message>
1152
+ <wsdl:message name="linnLiveDeleteProductsResponse">
1153
+ <wsdl:part name="parameters" element="typens:linnLiveDeleteProductsResponseParam" />
1154
+ </wsdl:message>
1155
+
1156
+ <wsdl:message name="linnLiveCreateRelatedProductsRequest">
1157
+ <wsdl:part name="parameters" element="typens:linnLiveCreateRelatedProductsRequestParam" />
1158
+ </wsdl:message>
1159
+ <wsdl:message name="linnLiveCreateRelatedProductsResponse">
1160
+ <wsdl:part name="parameters" element="typens:linnLiveCreateRelatedProductsResponseParam" />
1161
+ </wsdl:message>
1162
+
1163
+ <wsdl:message name="linnLiveDeleteRelatedProductsRequest">
1164
+ <wsdl:part name="parameters" element="typens:linnLiveDeleteRelatedProductsRequestParam" />
1165
+ </wsdl:message>
1166
+ <wsdl:message name="linnLiveDeleteRelatedProductsResponse">
1167
+ <wsdl:part name="parameters" element="typens:linnLiveDeleteRelatedProductsResponseParam" />
1168
+ </wsdl:message>
1169
+
1170
+ <wsdl:message name="linnLiveCreateProductImagesRequest">
1171
+ <wsdl:part name="parameters" element="typens:linnLiveCreateProductImagesRequestParam" />
1172
+ </wsdl:message>
1173
+ <wsdl:message name="linnLiveCreateProductImagesResponse">
1174
+ <wsdl:part name="parameters" element="typens:linnLiveCreateProductImagesResponseParam" />
1175
+ </wsdl:message>
1176
+
1177
+ <wsdl:message name="linnLiveUpdateProductImagesRequest">
1178
+ <wsdl:part name="parameters" element="typens:linnLiveUpdateProductImagesRequestParam" />
1179
+ </wsdl:message>
1180
+ <wsdl:message name="linnLiveUpdateProductImagesResponse">
1181
+ <wsdl:part name="parameters" element="typens:linnLiveUpdateProductImagesResponseParam" />
1182
+ </wsdl:message>
1183
+
1184
+ <wsdl:message name="linnLiveDeleteProductImagesRequest">
1185
+ <wsdl:part name="parameters" element="typens:linnLiveDeleteProductImagesRequestParam" />
1186
+ </wsdl:message>
1187
+ <wsdl:message name="linnLiveDeleteProductImagesResponse">
1188
+ <wsdl:part name="parameters" element="typens:linnLiveDeleteProductImagesResponseParam" />
1189
+ </wsdl:message>
1190
+
1191
+
1192
+
1193
  <wsdl:message name="linnLiveProductListRequest">
1194
  <wsdl:part name="parameters" element="typens:linnLiveProductListRequestParam" />
1195
  </wsdl:message>
1227
  <wsdl:message name="catalogProductAttributeRemoveResponse">
1228
  <wsdl:part name="parameters" element="typens:linnLiveAttributeRemoveResponseParam" />
1229
  </wsdl:message>
1230
+ <!-- Stub parameters for catalogProductAttributeRemove end -->
1231
 
1232
 
1233
 
1278
  <wsdl:output message="typens:linnLiveGetStoreCodeResponse" />
1279
  </wsdl:operation>
1280
 
1281
+ <wsdl:operation name="linnLiveCreateRelatedProducts">
1282
+ <wsdl:documentation>Create bulk related products</wsdl:documentation>
1283
+ <wsdl:input message="typens:linnLiveCreateRelatedProductsRequest" />
1284
+ <wsdl:output message="typens:linnLiveCreateRelatedProductsResponse" />
1285
+ </wsdl:operation>
1286
+
1287
+ <wsdl:operation name="linnLiveDeleteRelatedProducts">
1288
+ <wsdl:documentation>Delete bulk related products</wsdl:documentation>
1289
+ <wsdl:input message="typens:linnLiveDeleteRelatedProductsRequest" />
1290
+ <wsdl:output message="typens:linnLiveDeleteRelatedProductsResponse" />
1291
+ </wsdl:operation>
1292
+
1293
+ <wsdl:operation name="linnLiveCreateProductImages">
1294
+ <wsdl:documentation>Create bulk product images</wsdl:documentation>
1295
+ <wsdl:input message="typens:linnLiveCreateProductImagesRequest" />
1296
+ <wsdl:output message="typens:linnLiveCreateProductImagesResponse" />
1297
+ </wsdl:operation>
1298
+
1299
+ <wsdl:operation name="linnLiveUpdateProductImages">
1300
+ <wsdl:documentation>Update bulk product images</wsdl:documentation>
1301
+ <wsdl:input message="typens:linnLiveUpdateProductImagesRequest" />
1302
+ <wsdl:output message="typens:linnLiveUpdateProductImagesResponse" />
1303
+ </wsdl:operation>
1304
+
1305
+ <wsdl:operation name="linnLiveDeleteProductImages">
1306
+ <wsdl:documentation>Delete bulk product images</wsdl:documentation>
1307
+ <wsdl:input message="typens:linnLiveDeleteProductImagesRequest" />
1308
+ <wsdl:output message="typens:linnLiveDeleteProductImagesResponse" />
1309
+ </wsdl:operation>
1310
+
1311
  <wsdl:operation name="linnLiveGetProductStoreURL">
1312
  <wsdl:documentation>Get product url</wsdl:documentation>
1313
  <wsdl:input message="typens:linnLiveGetProductStoreURLRequest" />
1314
  <wsdl:output message="typens:linnLiveGetProductStoreURLResponse" />
1315
  </wsdl:operation>
1316
 
1317
+ <wsdl:operation name="linnLiveDisableIndexing">
1318
+ <wsdl:documentation>Set indexers mode to manual save</wsdl:documentation>
1319
+ <wsdl:input message="typens:linnLiveDisableIndexingRequest" />
1320
+ <wsdl:output message="typens:linnLiveDisableIndexingResponse" />
1321
+ </wsdl:operation>
1322
+
1323
+ <wsdl:operation name="linnLiveRestoreIndexingById">
1324
+ <wsdl:documentation>Restore indexers modes</wsdl:documentation>
1325
+ <wsdl:input message="typens:linnLiveRestoreIndexingByIdRequest" />
1326
+ <wsdl:output message="typens:linnLiveRestoreIndexingByIdResponse" />
1327
+ </wsdl:operation>
1328
+
1329
+
1330
+ <wsdl:operation name="linnLiveCheckProducts">
1331
+ <wsdl:documentation>Check products</wsdl:documentation>
1332
+ <wsdl:input message="typens:linnLiveCheckProductsRequest" />
1333
+ <wsdl:output message="typens:linnLiveCheckProductsResponse" />
1334
+ </wsdl:operation>
1335
+
1336
+ <wsdl:operation name="linnLiveCreateSimpleProducts">
1337
+ <wsdl:documentation>Create products</wsdl:documentation>
1338
+ <wsdl:input message="typens:linnLiveCreateSimpleProductsRequest" />
1339
+ <wsdl:output message="typens:linnLiveCreateSimpleProductsResponse" />
1340
+ </wsdl:operation>
1341
+
1342
+ <wsdl:operation name="linnLiveCreateConfigurableProducts">
1343
+ <wsdl:documentation>Create configurable products</wsdl:documentation>
1344
+ <wsdl:input message="typens:linnLiveCreateConfigurableProductsRequest" />
1345
+ <wsdl:output message="typens:linnLiveCreateConfigurableProductsResponse" />
1346
+ </wsdl:operation>
1347
+
1348
+ <wsdl:operation name="linnLiveUpdateSimpleProducts">
1349
+ <wsdl:documentation>updatep products</wsdl:documentation>
1350
+ <wsdl:input message="typens:linnLiveUpdateSimpleProductsRequest" />
1351
+ <wsdl:output message="typens:linnLiveUpdateSimpleProductsResponse" />
1352
+ </wsdl:operation>
1353
+
1354
+ <wsdl:operation name="linnLiveUpdateConfigurableProducts">
1355
+ <wsdl:documentation>Update configurable products</wsdl:documentation>
1356
+ <wsdl:input message="typens:linnLiveUpdateConfigurableProductsRequest" />
1357
+ <wsdl:output message="typens:linnLiveUpdateConfigurableProductsResponse" />
1358
+ </wsdl:operation>
1359
+
1360
+ <wsdl:operation name="linnLiveDeleteProducts">
1361
+ <wsdl:documentation>Delete products</wsdl:documentation>
1362
+ <wsdl:input message="typens:linnLiveDeleteProductsRequest" />
1363
+ <wsdl:output message="typens:linnLiveDeleteProductsResponse" />
1364
+ </wsdl:operation>
1365
+
1366
  <wsdl:operation name="linnLiveGetGeneralInfo">
1367
  <wsdl:documentation>Get general information</wsdl:documentation>
1368
  <wsdl:input message="typens:linnLiveGetGeneralInfoRequest" />
1387
  <wsdl:input message="typens:catalogProductAttributeRemoveRequest" />
1388
  <wsdl:output message="typens:catalogProductAttributeRemoveResponse" />
1389
  </wsdl:operation>
1390
+ <!-- remove for 1.8 -->
1391
 
1392
  <wsdl:operation name="linnLiveInfo">
1393
  <wsdl:documentation>Get information about current magento settings and installation</wsdl:documentation>
1493
  </wsdl:output>
1494
  </wsdl:operation>
1495
 
1496
+ <wsdl:operation name="linnLiveCreateRelatedProducts">
1497
+ <soap:operation soapAction="" />
1498
+ <wsdl:input>
1499
+ <soap:body use="literal" />
1500
+ </wsdl:input>
1501
+ <wsdl:output>
1502
+ <soap:body use="literal" />
1503
+ </wsdl:output>
1504
+ </wsdl:operation>
1505
+
1506
+ <wsdl:operation name="linnLiveDeleteRelatedProducts">
1507
+ <soap:operation soapAction="" />
1508
+ <wsdl:input>
1509
+ <soap:body use="literal" />
1510
+ </wsdl:input>
1511
+ <wsdl:output>
1512
+ <soap:body use="literal" />
1513
+ </wsdl:output>
1514
+ </wsdl:operation>
1515
+
1516
+
1517
+ <wsdl:operation name="linnLiveCreateProductImages">
1518
+ <soap:operation soapAction="" />
1519
+ <wsdl:input>
1520
+ <soap:body use="literal" />
1521
+ </wsdl:input>
1522
+ <wsdl:output>
1523
+ <soap:body use="literal" />
1524
+ </wsdl:output>
1525
+ </wsdl:operation>
1526
+
1527
+ <wsdl:operation name="linnLiveUpdateProductImages">
1528
+ <soap:operation soapAction="" />
1529
+ <wsdl:input>
1530
+ <soap:body use="literal" />
1531
+ </wsdl:input>
1532
+ <wsdl:output>
1533
+ <soap:body use="literal" />
1534
+ </wsdl:output>
1535
+ </wsdl:operation>
1536
+
1537
+ <wsdl:operation name="linnLiveDeleteProductImages">
1538
+ <soap:operation soapAction="" />
1539
+ <wsdl:input>
1540
+ <soap:body use="literal" />
1541
+ </wsdl:input>
1542
+ <wsdl:output>
1543
+ <soap:body use="literal" />
1544
+ </wsdl:output>
1545
+ </wsdl:operation>
1546
+
1547
  <wsdl:operation name="linnLiveGetProductStoreURL">
1548
  <soap:operation soapAction="" />
1549
  <wsdl:input>
1554
  </wsdl:output>
1555
  </wsdl:operation>
1556
 
1557
+ <wsdl:operation name="linnLiveDisableIndexing">
1558
+ <soap:operation soapAction="" />
1559
+ <wsdl:input>
1560
+ <soap:body use="literal" />
1561
+ </wsdl:input>
1562
+ <wsdl:output>
1563
+ <soap:body use="literal" />
1564
+ </wsdl:output>
1565
+ </wsdl:operation>
1566
+
1567
+ <wsdl:operation name="linnLiveRestoreIndexingById">
1568
+ <soap:operation soapAction="" />
1569
+ <wsdl:input>
1570
+ <soap:body use="literal" />
1571
+ </wsdl:input>
1572
+ <wsdl:output>
1573
+ <soap:body use="literal" />
1574
+ </wsdl:output>
1575
+ </wsdl:operation>
1576
+
1577
+
1578
+ <wsdl:operation name="linnLiveCheckProducts">
1579
+ <soap:operation soapAction="" />
1580
+ <wsdl:input>
1581
+ <soap:body use="literal" />
1582
+ </wsdl:input>
1583
+ <wsdl:output>
1584
+ <soap:body use="literal" />
1585
+ </wsdl:output>
1586
+ </wsdl:operation>
1587
+
1588
+ <wsdl:operation name="linnLiveCreateSimpleProducts">
1589
+ <soap:operation soapAction="" />
1590
+ <wsdl:input>
1591
+ <soap:body use="literal" />
1592
+ </wsdl:input>
1593
+ <wsdl:output>
1594
+ <soap:body use="literal" />
1595
+ </wsdl:output>
1596
+ </wsdl:operation>
1597
+
1598
+ <wsdl:operation name="linnLiveCreateConfigurableProducts">
1599
+ <soap:operation soapAction="" />
1600
+ <wsdl:input>
1601
+ <soap:body use="literal" />
1602
+ </wsdl:input>
1603
+ <wsdl:output>
1604
+ <soap:body use="literal" />
1605
+ </wsdl:output>
1606
+ </wsdl:operation>
1607
+
1608
+ <wsdl:operation name="linnLiveUpdateSimpleProducts">
1609
+ <soap:operation soapAction="" />
1610
+ <wsdl:input>
1611
+ <soap:body use="literal" />
1612
+ </wsdl:input>
1613
+ <wsdl:output>
1614
+ <soap:body use="literal" />
1615
+ </wsdl:output>
1616
+ </wsdl:operation>
1617
+
1618
+ <wsdl:operation name="linnLiveUpdateConfigurableProducts">
1619
+ <soap:operation soapAction="" />
1620
+ <wsdl:input>
1621
+ <soap:body use="literal" />
1622
+ </wsdl:input>
1623
+ <wsdl:output>
1624
+ <soap:body use="literal" />
1625
+ </wsdl:output>
1626
+ </wsdl:operation>
1627
+
1628
+
1629
+ <wsdl:operation name="linnLiveDeleteProducts">
1630
+ <soap:operation soapAction="" />
1631
+ <wsdl:input>
1632
+ <soap:body use="literal" />
1633
+ </wsdl:input>
1634
+ <wsdl:output>
1635
+ <soap:body use="literal" />
1636
+ </wsdl:output>
1637
+ </wsdl:operation>
1638
+
1639
  <wsdl:operation name="linnLiveGetGeneralInfo">
1640
  <soap:operation soapAction="" />
1641
  <wsdl:input>
package.xml CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>LinnLiveConnect</name>
4
- <version>1.1.52</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>mapping fix</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-08-25</date>
15
- <time>07:38:35</time>
16
- <contents><target name="magelocal"><dir name="LinnSystems"><dir name="LinnLiveConnect"><dir name="Helper"><file name="Data.php" hash="5fe5216de67d4e69a0f418b0cd7780ee"/></dir><dir name="Model"><dir name="Api"><file name="V2.php" hash="d1d407d83c02ba7fe85a1de1386ee463"/></dir></dir><dir name="etc"><file name="api.xml" hash="f24d33b8241c0b29c58c4cffb93162e6"/><file name="config.xml" hash="fa5ee3ecddfbc3605d33524f7cc57f71"/><file name="wsdl.xml" hash="2b450fd6a6332d20583aaa4fc52012b6"/><file name="wsi.xml" hash="67b9b8ae64b953805556a5d243e148bc"/></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.53</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>bulk methods added</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-10-20</date>
15
+ <time>09:31:29</time>
16
+ <contents><target name="magelocal"><dir name="LinnSystems"><dir name="LinnLiveConnect"><dir name="Helper"><file name="Data.php" hash="c70112ed95d9f8a1f75014caffe3a366"/><file name="Settings.php" hash="086ba912d38dc66964a2f40f685394a5"/></dir><dir name="Model"><dir name="Api"><file name="V2.php" hash="e5e3687e5193ae5144b44f8404278947"/></dir></dir><dir name="etc"><file name="api.xml" hash="aa9ab1b014d9104852748905cc3e89bf"/><file name="config.xml" hash="8e86bbaef2c9f68566b88b5d1636dd0e"/><file name="wsdl.xml" hash="2b450fd6a6332d20583aaa4fc52012b6"/><file name="wsi.xml" hash="2d8d0381622fb19cc398082e23ef78f8"/></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>