LinnLiveConnect - Version 1.1.37

Version Notes

Bug fixes:
* Version fix.

Download this release

Release Info

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


Version 1.1.37

app/code/local/LinnSystems/LinnLiveConnect/Helper/Data.php ADDED
@@ -0,0 +1,4 @@
 
 
 
 
1
+ <?php
2
+ class LinnSystems_LinnLiveConnect_Helper_Data extends Mage_Core_Helper_Abstract
3
+ {
4
+ }
app/code/local/LinnSystems/LinnLiveConnect/Model/Api/V2.php ADDED
@@ -0,0 +1,1433 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ class Settings {
3
+ static $VERSION = 37;
4
+ }
5
+
6
+ class LinnSystems_LinnLiveConnect_Model_Api_V2{
7
+
8
+ public function configurableProduct($version, $set, $sku, $reindex, $productData, $productsSet, $attributesSet, $store=null)
9
+ {
10
+ $worker = Factory::createWorker($version);
11
+ return $worker->configurableProduct($set, $sku, $reindex, $productData, $productsSet, $attributesSet, $store);
12
+ }
13
+
14
+ public function updateConfigurableProduct($version, $productId, $reindex, $productData, $productsSet, $attributesSet, $store=null, $identifierType='id')
15
+ {
16
+ $worker = Factory::createWorker($version);
17
+ return $worker->updateConfigurableProduct($productId, $reindex, $productData, $productsSet, $attributesSet, $store, $identifierType);
18
+ }
19
+
20
+ public function storesList($version)
21
+ {
22
+ $worker = Factory::createWorker($version);
23
+ return $worker->storesList();
24
+ }
25
+
26
+ public function getStoreCode($version, $store=null)
27
+ {
28
+ $worker = Factory::createWorker($version);
29
+ return $worker->getStoreCode($store);
30
+ }
31
+
32
+ public function deleteAssigned($version, $productId, $store=null, $identifierType='id')
33
+ {
34
+ $worker = Factory::createWorker($version);
35
+ return $worker->deleteAssigned($productId, $store, $identifierType);
36
+ }
37
+
38
+ public function assignImages($version, $productImages)
39
+ {
40
+ $worker = Factory::createWorker($version);
41
+ return $worker->assignImages($productImages);
42
+ }
43
+
44
+ public function productList($version, $page, $perPage, $filters = null, $store = null)
45
+ {
46
+ $worker = Factory::createWorker($version);
47
+ return $worker->productList($page, $perPage, $filters, $store);
48
+ }
49
+
50
+ public function productAttributeOptions($version, $setId)
51
+ {
52
+ $worker = Factory::createWorker($version);
53
+ return $worker->productAttributeOptions($setId);
54
+ }
55
+
56
+ public function update($version, $productId, $productData, $store = null, $identifierType = 'id')
57
+ {
58
+ $worker = Factory::createWorker($version);
59
+ return $worker->update($productId, $productData, $store, $identifierType);
60
+ }
61
+
62
+ public function create($version, $type, $set, $sku, $productData, $store = null)
63
+ {
64
+ $worker = Factory::createWorker($version);
65
+ return $worker->create($type, $set, $sku, $productData, $store);
66
+ }
67
+
68
+ public function debugInfo()
69
+ {
70
+ $worker = Factory::createWorker(Settings::$VERSION);
71
+ return $worker->debugInfo();
72
+ }
73
+ }
74
+
75
+ class Factory{
76
+
77
+ private function _checkVersion($version)
78
+ {
79
+ $version = intval($version);
80
+
81
+ if ($version == 0)
82
+ throw new Mage_Api_Exception('version is not specified');
83
+ if (Settings::$VERSION < $version )
84
+ throw new Mage_Api_Exception('wrong_version');
85
+ }
86
+
87
+
88
+ public static function createWorker($version)
89
+ {
90
+ self::_checkVersion($version);
91
+
92
+ if(Mage::GetEdition() == Mage::EDITION_COMMUNITY)
93
+ {
94
+ return new LinnLiveCommunity();
95
+ }
96
+ else if (Mage::GetEdition() == Mage::EDITION_ENTERPRISE)
97
+ {
98
+ return new LinnLiveEnterprise();
99
+ }
100
+ else
101
+ {
102
+ throw new Mage_Api_Exception('unsupported_edition');
103
+ }
104
+
105
+ }
106
+ }
107
+
108
+ class LinnLiveMain extends Mage_Core_Model_Abstract{
109
+
110
+
111
+ private $_ignoredAttributes = array(
112
+ 'created_at',
113
+ 'updated_at',
114
+ 'category_ids',
115
+ 'required_options',
116
+ 'old_id',
117
+ 'url_key',
118
+ 'url_path',
119
+ 'has_options',
120
+ 'image_label',
121
+ 'small_image_label',
122
+ 'thumbnail_label',
123
+ 'image',
124
+ 'small_image',
125
+ 'thumbnail',
126
+ 'options_container',
127
+ 'entity_id',
128
+ 'entity_type_id',
129
+ 'attribute_set_id',
130
+ 'type_id',
131
+ 'sku',
132
+ 'name',
133
+ 'status',
134
+ 'stock_item',
135
+ 'description',
136
+ );
137
+
138
+ private $_permittedAttributes = array (
139
+ 'select',
140
+ 'multiselect',
141
+ 'text',
142
+ 'textarea',
143
+ 'date',
144
+ 'price'
145
+ );
146
+
147
+ private function _prepareConfigurableData(
148
+ & $store, & $productData, & $assignedProductsArray,
149
+ & $attributesSetArray, $productsSet, $attributesSet)
150
+ {
151
+ $store = $this->_currentStoreCode($store);
152
+
153
+ $this->_updateConfigurableQuantity($productData);
154
+
155
+ $productData = $this->_fixAttributes($productData);
156
+
157
+ if (!is_array($attributesSet))
158
+ {
159
+ $tmpSet = $attributesSet;
160
+ $attributesSet = array();
161
+ $attributesSet[] = $tmpSet;
162
+ }
163
+
164
+ $assignedProductsData = $this->_createProductsData($productsSet);
165
+ $assignedProductsArray = $this->_objectToArray($assignedProductsData);
166
+
167
+ $_newAttributeOptions = $this->_newConfigurableOptions($assignedProductsArray);
168
+ if (count($_newAttributeOptions) > 0)
169
+ {
170
+ $_availableOptions = $this->_createOptions($_newAttributeOptions);
171
+ $this->_checkAssignedProductsOptions($_availableOptions, $assignedProductsArray);
172
+ }
173
+
174
+ $attributesSetArray = $this->_objectToArray($attributesSet);
175
+ $attributesSetArray = $this->_prepareAttributesData($attributesSetArray, $assignedProductsArray);
176
+
177
+ foreach($attributesSetArray as $key=>$value)
178
+ {
179
+ $attributesSetArray[$key]["id"] = NULL;
180
+ $attributesSetArray[$key]["position"] = NULL;
181
+
182
+ }
183
+
184
+ }
185
+
186
+ private function _checkAssignedProductsOptions($availableOptions, & $assignedProductsArray)
187
+ {
188
+ foreach ($assignedProductsArray as $id => $productOptions)
189
+ {
190
+ foreach($productOptions as $index => $option)
191
+ {
192
+ if (isset($availableOptions[$option['attribute_id']][strtolower($option['label'])]))
193
+ {
194
+ $assignedProductsArray[$id][$index]['value_index'] = $availableOptions[$option['attribute_id']][strtolower($option['label'])];
195
+ }
196
+ }
197
+ }
198
+ }
199
+
200
+ private function _createOptions($newOptions)
201
+ {
202
+ $installer = new Mage_Eav_Model_Entity_Setup('core_setup');
203
+ $attributeApi = Mage::getModel('catalog/product_attribute_api');
204
+ $helperCatalog = Mage::helper('catalog');
205
+
206
+ $installer->startSetup();
207
+
208
+ $attributesList = array();
209
+
210
+ foreach($newOptions as $attribute_id=>$options)
211
+ {
212
+ $aOption = array();
213
+ $aOption['attribute_id'] = $attribute_id;
214
+ $attributesList[] = $attribute_id;
215
+
216
+ $i=0;
217
+ foreach($options as $option)
218
+ {
219
+ $optionTitle = $helperCatalog->stripTags($option);
220
+
221
+ $aOption['value']['option'.$i][0] = $optionTitle;
222
+ $i++;
223
+ }
224
+ $installer->addAttributeOption($aOption);
225
+ }
226
+ $installer->endSetup();
227
+
228
+ Mage::app()->cleanCache(array(Mage_Core_Model_Translate::CACHE_TAG));
229
+
230
+
231
+ $currentOptions = array();
232
+ $attributeApi = Mage::getModel('catalog/product_attribute_api');
233
+ foreach($attributesList as $attribute_id)
234
+ {
235
+ if (!isset($currentOptions[$attribute_id]))
236
+ $currentOptions[$attribute_id] = array();
237
+
238
+ $attributeOptions = $attributeApi->options($attribute_id);
239
+
240
+ foreach ($attributeOptions as $opts)
241
+ {
242
+ $label = strtolower($opts['label']);
243
+ $optionId = $opts['value'];
244
+ if (!isset($currentOptions[$attribute_id][$label]))
245
+ $currentOptions[$attribute_id][$label] = $optionId;
246
+ else {
247
+ $oldId = $currentOptions[$attribute_id][$label];
248
+ if ($oldId > $optionId)
249
+ {
250
+ $attributeApi->removeOption($attribute_id, $oldId);
251
+ $currentOptions[$attribute_id][$label] = $optionId;
252
+ }
253
+ else
254
+ {
255
+ $attributeApi->removeOption($attribute_id, $optionId);
256
+ }
257
+ }
258
+ }
259
+ }
260
+
261
+ return $currentOptions;
262
+ }
263
+
264
+ private function _newConfigurableOptions($assignedProductsArray)
265
+ {
266
+ $_attributesOptions = array();
267
+ foreach ($assignedProductsArray as $id => $productOptions)
268
+ {
269
+ foreach($productOptions as $option)
270
+ {
271
+ if (isset($option['value_index']) && $option['value_index'] == '-1')
272
+ {
273
+ if (isset($_attributesOptions[$option['attribute_id']]))
274
+ {
275
+ $_attributesOptions[$option['attribute_id']][] = $option['label'];
276
+ }
277
+ else
278
+ {
279
+ $_attributesOptions[$option['attribute_id']] = array($option['label']);
280
+ }
281
+ }
282
+ }
283
+ }
284
+ return $_attributesOptions;
285
+ }
286
+
287
+ private function _newOptions($productData)
288
+ {
289
+ $_attributesOptions = array();
290
+
291
+ if (property_exists($productData, 'additional_attributes')) {
292
+ $_attributes = $productData->additional_attributes;
293
+ if (is_array($_attributes)) {
294
+ foreach($_attributes as $_attribute) {
295
+ if (($_attribute->type == 'select' || $_attribute->type == 'multiselect') && $_attribute->value == "-1")
296
+ {
297
+ if (isset($_attributesOptions[$_attribute->attribute_id]))
298
+ {
299
+ $_attributesOptions[$_attribute->attribute_id][] = $_attribute->label;
300
+ }
301
+ else
302
+ {
303
+ $_attributesOptions[$_attribute->attribute_id] = array($_attribute->label);
304
+ }
305
+ }
306
+ }
307
+ }
308
+ else
309
+ {
310
+ if (($_attributes->type == 'select' || $_attributes->type == 'multiselect') && $_attributes->value == "-1")
311
+ {
312
+ if (isset($_attributesOptions[$_attributes->attribute_id]))
313
+ {
314
+ $_attributesOptions[$_attributes->attribute_id][] = $_attributes->label;
315
+ }
316
+ else
317
+ {
318
+ $_attributesOptions[$_attributes->attribute_id] = array($_attributes->label);
319
+ }
320
+ }
321
+ }
322
+
323
+ }
324
+
325
+ return $_attributesOptions;
326
+ }
327
+
328
+ private function _containsOption($attributeOption, $option)
329
+ {
330
+ foreach ($attributeOption as $inArrayOption)
331
+ if ($inArrayOption['value_index'] == $option['value_index']) return true;
332
+
333
+ return false;
334
+ }
335
+
336
+ private function _prepareAttributesData($attributesSetArray, $assignedProductsArray)
337
+ {
338
+ $_attributesOptions = array();
339
+ foreach ($assignedProductsArray as $id => $productOptions)
340
+ {
341
+ foreach($productOptions as $option)
342
+ {
343
+ if (isset($_attributesOptions[$option['attribute_id']]) &&
344
+ !$this->_containsOption($_attributesOptions[$option['attribute_id']], $option))
345
+ {
346
+ $_attributesOptions[$option['attribute_id']][] = $option;
347
+ }
348
+ else if (!isset($_attributesOptions[$option['attribute_id']]))
349
+ {
350
+ $_attributesOptions[$option['attribute_id']] = array();
351
+ $_attributesOptions[$option['attribute_id']][] = $option;
352
+ }
353
+ }
354
+ }
355
+
356
+ foreach($attributesSetArray as $key => $attribute)
357
+ {
358
+ if (isset($_attributesOptions[$attribute['attribute_id']]))
359
+ $attributesSetArray[$key]['values'] = $_attributesOptions[$attribute['attribute_id']];
360
+ }
361
+
362
+ return $attributesSetArray;
363
+ }
364
+
365
+ private function _updateConfigurable($store, $productId, $productData, $assignedProducts, $assignedAttributes, $identifierType, $isUpdate=false, $reindex=true)
366
+ {
367
+ $magentoVer = $this->_getCurrentVersion();
368
+ if ($magentoVer == 162)
369
+ {
370
+ $store = Mage::app()->getStore($store)->getId();
371
+ }
372
+
373
+ $product = Mage::helper('catalog/product')->getProduct($productId, $store, $identifierType);
374
+
375
+ $product->setConfigurableProductsData($assignedProducts);
376
+ if (!$isUpdate)
377
+ $product->setConfigurableAttributesData($assignedAttributes);
378
+ $product->setCanSaveConfigurableAttributes(true);
379
+
380
+ try {
381
+ $result = $product->save();
382
+ }
383
+ catch (Exception $e){
384
+ throw new Mage_Api_Exception('configurable_creating_error', $e->getMessage());
385
+ }
386
+
387
+ if ($reindex === true)
388
+ {
389
+ try {
390
+ $indexer = Mage::getSingleton('index/indexer');
391
+ $process = $indexer->getProcessByCode('catalog_product_price');
392
+ $process->reindexEverything();
393
+ } catch (Mage_Core_Exception $e) {
394
+ throw new Mage_Api_Exception('configurable_creating_error', $e->getMessage());
395
+ }
396
+ }
397
+
398
+ return $result;
399
+ }
400
+
401
+ private function _createProductsData($productData)
402
+ {
403
+ $assignedProductsData = array();
404
+
405
+ if (is_array($productData))
406
+ {
407
+ foreach ($productData as $product)
408
+ {
409
+ $assignedProductsData[$product->product_id] = array();
410
+ $this->_fillAssignedProductValues($product, $assignedProductsData);
411
+ }
412
+ }
413
+ else
414
+ {
415
+ $assignedProductsData[$productData->product_id] = array();
416
+ $this->_fillAssignedProductValues($product, $assignedProductsData);
417
+ }
418
+
419
+
420
+ return $assignedProductsData;
421
+ }
422
+
423
+ private function _fillAssignedProductValues(& $product, & $assignedProductsData)
424
+ {
425
+ if (is_array($product->values))
426
+ {
427
+ foreach ($product->values as $productValue)
428
+ {
429
+ $assignedProductsData[$product->product_id][] = $productValue;
430
+ }
431
+ }
432
+ else
433
+ {
434
+ $assignedProductsData[$product->product_id][] = $product->values;
435
+ }
436
+ }
437
+
438
+ private function _updateConfigurableQuantity( & $productData)
439
+ {
440
+ $this->_updateQuantity($productData);
441
+
442
+ if (!property_exists($productData, 'stock_data'))
443
+ {
444
+ $productData->stock_data = new stdClass();
445
+ }
446
+
447
+ $productData->stock_data->manage_stock = 1;
448
+ $productData->stock_data->is_in_stock = 1;
449
+ }
450
+
451
+ private function _updateQuantity( & $productData)
452
+ {
453
+ if (property_exists($productData, 'stock_data') && property_exists($productData->stock_data, 'qty')) {
454
+ $productData->stock_data->qty = intval($productData->stock_data->qty);
455
+ $productData->stock_data->is_in_stock = 1;
456
+ $productData->stock_data->manage_stock = 1;
457
+ }
458
+ }
459
+
460
+ private function _objectToArray( $result )
461
+ {
462
+ $array = array();
463
+ foreach ($result as $key=>$value)
464
+ {
465
+ if (is_object($value) || is_array($value))
466
+ {
467
+ $array[$key]=$this->_objectToArray($value);
468
+ }
469
+ else
470
+ {
471
+ $array[$key]=$value;
472
+ }
473
+ }
474
+ return $array;
475
+ }
476
+
477
+ private function _getCurrentVersion()
478
+ {
479
+ $verInfo = Mage::getVersionInfo();
480
+
481
+ return intval($verInfo['major'].$verInfo['minor'].$verInfo['revision']);
482
+ }
483
+
484
+ private function _productImages($attributesList)
485
+ {
486
+ $_images = array();
487
+
488
+ if (is_array($attributesList) && count($attributesList) > 0 && isset($attributesList['media_gallery']))
489
+ {
490
+ $small = empty($attributesList['small_image']) ? false : $attributesList['small_image'];
491
+ $base = empty($attributesList['image']) ? false : $attributesList['image'];
492
+ $thumb = empty($attributesList['thumbnail']) ? false : $attributesList['thumbnail'];
493
+
494
+ foreach($attributesList['media_gallery']['images'] as $key=>$value)
495
+ {
496
+ $newImage = array();
497
+ $newImage['file'] = $value['file'];
498
+ $newImage['label'] = $value['label'];
499
+ $newImage['disabled'] = $value['disabled'] ? true : false;
500
+
501
+ $newImage['small_image'] = $small == $newImage['file'];
502
+ $newImage['image'] = $base == $newImage['file'];
503
+ $newImage['thumbnail'] = $thumb == $newImage['file'];
504
+
505
+ $_images[] = $newImage;
506
+ }
507
+ }
508
+
509
+ return $_images;
510
+ }
511
+
512
+ private function _removeIgnoredAttributes($attributesList)
513
+ {
514
+ $_preparedAttributes = array();
515
+ if (is_array($attributesList) && count($attributesList) > 0)
516
+ {
517
+ foreach($attributesList as $key=>$value)
518
+ {
519
+ if (!in_array($key, $this->_ignoredAttributes) && !is_array($value))
520
+ $_preparedAttributes[]= array('key' => $key, 'value' => $value);
521
+ }
522
+ }
523
+
524
+ return $_preparedAttributes;
525
+ }
526
+
527
+ private function _currentStoreCode($store=null)
528
+ {
529
+ if ($store != null)
530
+ return $store;
531
+
532
+ return $this->_getStore()->getCode();
533
+ }
534
+
535
+ private function _getStore($storeCode=null)
536
+ {
537
+ if (Mage::app()->isSingleStoreMode()) {
538
+ return Mage::app()->getWebsite(true)->getDefaultStore();
539
+ }
540
+
541
+ $mageRunCode = isset($_SERVER['MAGE_RUN_CODE']) ? $_SERVER['MAGE_RUN_CODE'] : '';
542
+ $mageRunType = isset($_SERVER['MAGE_RUN_TYPE']) ? $_SERVER['MAGE_RUN_TYPE'] : 'store';
543
+
544
+ if ($storeCode != null)
545
+ return Mage::getModel('core/store')->load( $storeCode, 'code');
546
+
547
+ if ($mageRunType == 'store') {
548
+ if (!empty($mageRunCode))
549
+ {
550
+ return Mage::getModel('core/store')->load( $mageRunCode, 'code');
551
+ }
552
+ }
553
+ else {
554
+ if ($mageRunType == 'website')
555
+ $websiteCode = empty($mageRunCode) ? '' : $mageRunCode;
556
+ else
557
+ $websiteCode = empty($mageRunType) ? '' : $mageRunType;
558
+
559
+ if (!empty($websiteCode))
560
+ {
561
+ $currentWebSite = Mage::getModel('core/website')->load( $websiteCode, 'code');
562
+ $defaultStore = $currentWebSite->getDefaultStore();
563
+ if (isset($defaultStore))
564
+ return $defaultStore;
565
+ }
566
+ }
567
+
568
+
569
+ return Mage::app()->getWebsite(true)->getDefaultStore();//Mage::app()->getStore();
570
+ }
571
+
572
+ private function _getWebsiteId($store=null)
573
+ {
574
+ return array($this->_getStore($store)->getWebsiteId());
575
+ }
576
+
577
+ private function _productAttributeInfo($attribute_id, $attributeAPI)
578
+ {
579
+ $model = Mage::getResourceModel('catalog/eav_attribute')
580
+ ->setEntityTypeId(Mage::getModel('eav/entity')->setType('catalog_product')->getTypeId());
581
+
582
+ $model->load($attribute_id);
583
+
584
+ if (!$model->getId()) {
585
+ throw new Mage_Api_Exception('attribute_not_exists');
586
+ }
587
+
588
+ if ($model->isScopeGlobal()) {
589
+ $scope = 'global';
590
+ } elseif ($model->isScopeWebsite()) {
591
+ $scope = 'website';
592
+ } else {
593
+ $scope = 'store';
594
+ }
595
+
596
+ $result = array(
597
+ 'attribute_id' => $model->getId(),
598
+ 'attribute_code' => $model->getAttributeCode(),
599
+ 'frontend_input' => $model->getFrontendInput(),
600
+ 'default_value' => $model->getDefaultValue(),
601
+ 'is_unique' => $model->getIsUnique(),
602
+ 'is_required' => $model->getIsRequired(),
603
+ 'apply_to' => $model->getApplyTo(),
604
+ 'is_configurable' => $model->getIsConfigurable(),
605
+ 'is_searchable' => $model->getIsSearchable(),
606
+ 'is_visible_in_advanced_search' => $model->getIsVisibleInAdvancedSearch(),
607
+ 'is_comparable' => $model->getIsComparable(),
608
+ 'is_used_for_promo_rules' => $model->getIsUsedForPromoRules(),
609
+ 'is_visible_on_front' => $model->getIsVisibleOnFront(),
610
+ 'used_in_product_listing' => $model->getUsedInProductListing(),
611
+ 'scope' => $scope,
612
+ );
613
+
614
+ // set options
615
+ $options = $attributeAPI->options($model->getId());
616
+ // remove empty first element
617
+ if ($model->getFrontendInput() != 'boolean') {
618
+ array_shift($options);
619
+ }
620
+
621
+ if (count($options) > 0) {
622
+ $result['options'] = $options;
623
+ }
624
+
625
+ return $result;
626
+ }
627
+
628
+ //Fix for buggy associativeArray implementation
629
+ private function _fixAttributes($productData)
630
+ {
631
+ $_newAttributeOptions = $this->_newOptions($productData);
632
+ $_availableOptions = array();
633
+ if (count($_newAttributeOptions) > 0)
634
+ {
635
+ $_availableOptions = $this->_createOptions($_newAttributeOptions);
636
+ }
637
+
638
+ if (property_exists($productData, 'additional_attributes')) {
639
+ $tmpAttr = $productData->additional_attributes;
640
+ if (count($tmpAttr) == 0)
641
+ {
642
+ unset($productData->additional_attributes);
643
+ return $productData;
644
+ }
645
+
646
+ $i=0;
647
+ if (is_array($tmpAttr))
648
+ {
649
+ foreach ($tmpAttr as $option) {
650
+ $code = $option->code;
651
+ if ( ($option->type == 'multiselect') && (is_array($productData->$code) == false) )
652
+ {
653
+ $productData->$code = array();
654
+ }
655
+ if (isset($_availableOptions[$option->attribute_id][strtolower($option->label)]))
656
+ {
657
+ if ($option->type == 'multiselect')
658
+ {
659
+ array_push($productData->$code, $_availableOptions[$option->attribute_id][strtolower($option->label)]);
660
+ }
661
+ else
662
+ {
663
+ $productData->$code = $_availableOptions[$option->attribute_id][strtolower($option->label)];
664
+ }
665
+ }
666
+ else
667
+ {
668
+ if ($option->type == 'multiselect')
669
+ {
670
+ array_push($productData->$code, $option->value);
671
+ }
672
+ else
673
+ {
674
+ $productData->$code = $option->value;
675
+ }
676
+ }
677
+
678
+ }
679
+ }
680
+ else
681
+ {
682
+ $code = $tmpAttr->code;
683
+ if (isset($_availableOptions[$tmpAttr->attribute_id][strtolower($tmpAttr->label)]))
684
+ $productData->$code = $_availableOptions[$tmpAttr->attribute_id][strtolower($tmpAttr->label)];
685
+ else
686
+ $productData->$code = $tmpAttr->value;
687
+ }
688
+ }
689
+
690
+ unset($productData->additional_attributes);
691
+
692
+ return $productData;
693
+ }
694
+
695
+
696
+
697
+ /*
698
+ *
699
+ * Public functions(API)
700
+ *
701
+ */
702
+ public function configurableProduct($set, $sku, $reindex, $productData, $productsSet, $attributesSet, $store=null)
703
+ {
704
+ if (!$set || !$sku) {
705
+ throw new Mage_Api_Exception('data_invalid');
706
+ }
707
+
708
+ $this->_prepareConfigurableData($store, $productData, $assignedProductsArray,
709
+ $attributesSetArray, $productsSet, $attributesSet);
710
+
711
+ $DefaultStore = $this->_getStore();
712
+
713
+ if (property_exists($productData, 'websites') === false && isset($DefaultStore) ) {
714
+ $productData->websites = array($DefaultStore->getWebsiteId());
715
+ }
716
+
717
+ if (property_exists($productData, 'category_ids') && !is_array($productData->category_ids))
718
+ {
719
+ if (is_string($productData->category_ids)) {
720
+ $productData->category_ids = array($productData->category_ids);
721
+ }
722
+ }
723
+ else if (property_exists($productData, 'category_ids') === false)
724
+ {
725
+ $productData->category_ids = array();
726
+ }
727
+
728
+ $productData->categories = $productData->category_ids;
729
+
730
+ $productAPI = new Mage_Catalog_Model_Product_Api_V2();
731
+ $productId = $productAPI->create('configurable', $set, $sku, $productData, $store);
732
+
733
+ $this->_updateConfigurable($store, $productId, $productData, $assignedProductsArray, $attributesSetArray, 'id', false, $reindex);
734
+
735
+ return $productId;
736
+ }
737
+
738
+ public function updateConfigurableProduct($productId, $reindex, $productData, $productsSet, $attributesSet, $store=null, $identifierType='id')
739
+ {
740
+ if ($identifierType == 'id')
741
+ {
742
+ $productId = intval($productId);
743
+
744
+ if ($productId < 1) {
745
+ throw new Mage_Api_Exception('product_not_exists', null);
746
+ }
747
+ }
748
+
749
+ $this->_prepareConfigurableData($store, $productData, $assignedProductsArray,
750
+ $attributesSetArray, $productsSet, $attributesSet);
751
+
752
+ try {
753
+ $storeId = Mage::app()->getStore($store)->getId();
754
+ } catch (Mage_Core_Model_Store_Exception $e) {
755
+ throw new Mage_Api_Exception('store_not_exists', null);
756
+ }
757
+
758
+ $_loadedProduct = Mage::helper('catalog/product')->getProduct($productId, $storeId, $identifierType);
759
+
760
+ $_categoryIds = $_loadedProduct->getCategoryIds();
761
+ if (property_exists($productData, 'category_ids'))
762
+ {
763
+
764
+ if (!is_array($productData->category_ids))
765
+ {
766
+ $productData->category_ids = array($productData->category_ids);
767
+ }
768
+
769
+ $productData->category_ids = array_merge($_categoryIds, $productData->category_ids);
770
+
771
+ }
772
+ else
773
+ {
774
+ $productData->category_ids = $_categoryIds;
775
+ }
776
+
777
+ $productData->category_ids = array_unique($productData->category_ids);
778
+
779
+ if ( (property_exists($productData, 'removed_categories') === true)
780
+ && (is_array($productData->removed_categories) === true)
781
+ && (count($productData->removed_categories) > 0) )
782
+ {
783
+ $tmpCats = array();
784
+
785
+ $productData->category_ids = array_diff($productData->category_ids, $productData->removed_categories);
786
+ }
787
+
788
+ $productData->categories = $productData->category_ids;
789
+
790
+ if (property_exists($productData, 'add_to_websites') && $productData->add_to_websites === true)
791
+ {
792
+ $currentWebsites = $_loadedProduct->getWebsiteIds();
793
+ $websiteId = $this->_getWebsiteId();
794
+ $websiteId = $websiteId[0];
795
+
796
+ if (in_array($websiteId, $currentWebsites) === false)
797
+ {
798
+ $currentWebsites[] = $websiteId;
799
+ $productData->websites = $currentWebsites;
800
+ }
801
+ }
802
+
803
+ $productAPI = new Mage_Catalog_Model_Product_Api_V2();
804
+
805
+ $productAPI->update($productId, $productData, $store, $identifierType);
806
+
807
+ return $this->_updateConfigurable($store, $productId, $productData, $assignedProductsArray, $attributesSetArray, $identifierType, true, $reindex);
808
+ }
809
+
810
+ /*
811
+ * Checks if this Magento server has valid Extension installed
812
+ */
813
+ public function storesList()
814
+ {
815
+ return ($this->_getCurrentVersion() >= 160);
816
+ }
817
+
818
+ public function getStoreCode($store=null)
819
+ {
820
+ return $this->_currentStoreCode($store);
821
+ }
822
+
823
+ public function deleteAssigned($productId, $store=null, $identifierType='id')
824
+ {
825
+ if ($identifierType == 'id')
826
+ {
827
+ $productId = intval($productId);
828
+
829
+ if ($productId < 1) {
830
+ throw new Mage_Api_Exception('product_not_exists', null);
831
+ }
832
+ }
833
+
834
+ $store = $this->_currentStoreCode($store);
835
+
836
+ try {
837
+ $storeId = Mage::app()->getStore($store)->getId();
838
+ } catch (Mage_Core_Model_Store_Exception $e) {
839
+ throw new Mage_Api_Exception('store_not_exists', null);
840
+ }
841
+
842
+ $_loadedProduct = Mage::helper('catalog/product')->getProduct($productId, $storeId, $identifierType);
843
+ $currentWebsites = $_loadedProduct->getWebsiteIds();
844
+ $websiteId = $this->_getWebsiteId($store);
845
+ $websiteId = $websiteId[0];
846
+
847
+ $newWebsiteIds = array();
848
+
849
+ if (in_array($websiteId, $currentWebsites) === true)
850
+ {
851
+ for($i = 0; $i < count($currentWebsites); $i++)
852
+ {
853
+ if ($currentWebsites[$i] != $websiteId)
854
+ {
855
+ $newWebsiteIds[] = $currentWebsites[$i];
856
+ }
857
+ }
858
+
859
+ $_loadedProduct->setWebsiteIds($newWebsiteIds);
860
+
861
+ $_loadedProduct->save();
862
+ }
863
+
864
+ return true;
865
+ }
866
+
867
+
868
+ public function assignImages($productImages)
869
+ {
870
+ $store = $this->_currentStoreCode(null);
871
+
872
+ foreach($productImages as $imageData)
873
+ {
874
+ $productId = intval($imageData->product_id);
875
+ if ($productId < 1) {
876
+ throw new Mage_Api_Exception('product_not_exists', null);
877
+ }
878
+
879
+ $product = Mage::helper('catalog/product')->getProduct($productId, $store, 'id');
880
+
881
+ $images = $imageData->images;
882
+
883
+ $baseImageExist = false;
884
+ foreach($images as $image)
885
+ {
886
+ if (is_array($image->types) && in_array('image', $image->types))
887
+ {
888
+ $baseImageExist = true;
889
+ }
890
+ }
891
+
892
+ if ($baseImageExist == false && count($images) > 0)
893
+ {
894
+ $images[0]->types = array('image');
895
+ }
896
+
897
+ reset($images);
898
+
899
+ foreach($images as $image)
900
+ {
901
+ $catalogProductDir = Mage::getBaseDir('media') . DS . 'catalog/product';
902
+ $filePath = $catalogProductDir.$image->image_name;
903
+
904
+ if (is_array($image->types) && count($image->types) > 0)
905
+ {
906
+ $imageTypes = $image->types;
907
+ }
908
+ else
909
+ {
910
+ $imageTypes = "";
911
+ }
912
+
913
+ try
914
+ {
915
+ $product->addImageToMediaGallery($filePath, $imageTypes, false, false);
916
+ }
917
+ catch (Exception $e) { }
918
+
919
+ }
920
+
921
+ $product->save();
922
+ }
923
+
924
+ return true;
925
+ }
926
+
927
+ /*
928
+ * Implementation of catalogProductList because of bug in associativeArray.
929
+ * Extended to filter by category id too.
930
+ *
931
+ * Use 'entity_id' for product_id,
932
+ * 'type_id' instead of product type.
933
+ */
934
+ public function productList($page, $perPage, $filters = null, $store = null)
935
+ {
936
+ $arrayParams = array(
937
+ 'nin',
938
+ 'in',
939
+ );
940
+
941
+ $store = $this->_currentStoreCode($store);
942
+
943
+ try {
944
+ $storeId = Mage::app()->getStore($store)->getId();
945
+ } catch (Mage_Core_Model_Store_Exception $e) {
946
+ throw new Mage_Api_Exception('store_not_exists', null);
947
+ }
948
+
949
+ $preparedFilters = array();
950
+ if (isset($filters->filter)) {
951
+ foreach ($filters->filter as $_key => $_value) {
952
+ $preparedFilters[$_key] = $_value;
953
+ }
954
+ }
955
+ if (isset($filters->complex_filter)) {
956
+ foreach ($filters->complex_filter as $_key => $_filter) {
957
+ $_op = $_filter->key;
958
+ $_filterVal = $_filter->value;
959
+
960
+ if (in_array($_op, $arrayParams)) {
961
+ $values = implode(',', $_filterVal);
962
+ }
963
+ else {
964
+ $values = $_filterVal;
965
+ }
966
+ $preparedFilters[$_key] = array(
967
+ $_op => $values
968
+ );
969
+ }
970
+ }
971
+
972
+ if (isset($preparedFilters['category']) &&
973
+ is_string($preparedFilters['category']))
974
+ {
975
+ $_categoryId = intval($preparedFilters['category']);
976
+ unset($preparedFilters['category']);
977
+ }
978
+ else {
979
+ $_categoryId = 0;
980
+ }
981
+
982
+ if (!empty($preparedFilters)) {
983
+ if ($_categoryId > 0)
984
+ {
985
+ $_category = Mage::getModel('catalog/category')->load($_categoryId);
986
+ $collection = Mage::getModel('catalog/product')->getCollection()
987
+ ->addStoreFilter($storeId)
988
+ ->addCategoryFilter($_category);
989
+ }
990
+ else
991
+ {
992
+ $collection = Mage::getModel('catalog/product')->getCollection()
993
+ ->addStoreFilter($storeId);
994
+ }
995
+
996
+ try {
997
+ foreach ($preparedFilters as $field => $value) {
998
+ $collection->addFieldToFilter($field, $value);
999
+ }
1000
+ } catch (Mage_Core_Exception $e) {
1001
+ throw new Mage_Api_Exception('filters_invalid', $e->getMessage());
1002
+ }
1003
+ }
1004
+
1005
+ if ($page == 1)
1006
+ {
1007
+ $count = $collection->count();
1008
+ }
1009
+ else
1010
+ {
1011
+ $collection->setPageSize($perPage)
1012
+ ->setCurPage($page);
1013
+ $count = 0;
1014
+ }
1015
+
1016
+ $result = array();
1017
+ $result['count'] = $count;
1018
+ $result['products'] = array();
1019
+
1020
+ $_assignedIds = array();
1021
+ $_fetchedIds = array();
1022
+
1023
+ $i = 0;
1024
+ foreach ($collection as $_product) {
1025
+ if ($i >= ($perPage * $page)) break;
1026
+ $_loadedProduct = Mage::helper('catalog/product')->getProduct($_product->getId(), $storeId, 'id');
1027
+
1028
+ $_allAttributes = $_loadedProduct->getData();
1029
+
1030
+
1031
+ $_description = isset($_allAttributes['description']) ? $_allAttributes['description'] : '';
1032
+
1033
+ $_productImages = $this->_productImages($_allAttributes);
1034
+ $_productAttributes = $this->_removeIgnoredAttributes($_allAttributes);
1035
+
1036
+ $_fetchedIds[] = $_loadedProduct->getId();
1037
+
1038
+ $result['products'][$i] = array(
1039
+ 'product_id' => $_loadedProduct->getId(),
1040
+ 'sku' => $_loadedProduct->getSku(),
1041
+ 'name' => $_loadedProduct->GetName(),
1042
+ 'set' => $_loadedProduct->getAttributeSetId(),
1043
+ 'type' => $_loadedProduct->getTypeId(),
1044
+ 'price' => $_loadedProduct->getPrice(),
1045
+ 'status' => $_loadedProduct->getStatus(),
1046
+ 'description' => $_description,
1047
+ 'category_ids' => $_loadedProduct->getCategoryIds(),
1048
+ 'website_ids' => $_loadedProduct->getWebsiteIds(),
1049
+ 'assigned_ids' => array(),
1050
+ 'conf_attrib_ids' => array(),
1051
+ 'images' => $_productImages,
1052
+ 'attributes' => $_productAttributes,
1053
+ );
1054
+ if($_loadedProduct->getTypeId() == "configurable")
1055
+ {
1056
+ $_typeInstance = $_loadedProduct->getTypeInstance();
1057
+ $result['products'][$i]['assigned_ids'] = $_typeInstance->getUsedProductIds();
1058
+ foreach($_typeInstance->getConfigurableAttributes() as $attribute){
1059
+ $_prices = array();
1060
+ foreach($attribute->getPrices() as $price)
1061
+ {
1062
+ $_prices[] = array(
1063
+ 'value_index' => $price['value_index'],
1064
+ 'is_fixed' => !$price['is_percent'],
1065
+ 'price_diff' => $price['pricing_value'],
1066
+ 'label' => $price['label'],
1067
+ );
1068
+
1069
+ }
1070
+
1071
+ $result['products'][$i]['conf_attrib_ids'][] = array(
1072
+ 'code' => $attribute->getProductAttribute()->getAttributeCode(),
1073
+ 'prices' => $_prices
1074
+ );
1075
+ }
1076
+ $_assignedIds = array_merge($_assignedIds, $result['products'][$i]['assigned_ids']);
1077
+ }
1078
+
1079
+ $i++;
1080
+ }
1081
+
1082
+ $_absentIds = array_diff($_assignedIds, $_fetchedIds);
1083
+
1084
+ if (count($_absentIds) > 0)
1085
+ {
1086
+ $collection = Mage::getModel('catalog/product')->getCollection()->addIdFilter($_absentIds);
1087
+
1088
+ foreach ($collection as $_product) {
1089
+ $_loadedProduct = Mage::helper('catalog/product')->getProduct($_product->getId(), $storeId, 'id');
1090
+
1091
+ $_allAttributes = $_product->getData();
1092
+
1093
+ $_description = isset($_allAttributes['description']) ? $_allAttributes['description'] : '';
1094
+
1095
+ $_productImages = $this->_productImages($_allAttributes);
1096
+ $_productAttributes = $this->_removeIgnoredAttributes($_allAttributes);
1097
+
1098
+ $result['products'][] = array(
1099
+ 'product_id' => $_loadedProduct->getId(),
1100
+ 'sku' => $_loadedProduct->getSku(),
1101
+ 'name' => $_loadedProduct->GetName(),
1102
+ 'set' => $_loadedProduct->getAttributeSetId(),
1103
+ 'type' => $_loadedProduct->getTypeId(),
1104
+ 'price' => $_loadedProduct->getPrice(),
1105
+ 'status' => $_loadedProduct->getStatus(),
1106
+ 'description' => $_description,
1107
+ 'category_ids' => $_loadedProduct->getCategoryIds(),
1108
+ 'website_ids' => $_loadedProduct->getWebsiteIds(),
1109
+ 'assigned_ids' => array(),
1110
+ 'conf_attrib_ids' => array(),
1111
+ 'images' => $_productImages,
1112
+ 'attributes' => $this->_removeIgnoredAttributes($_loadedProduct->getData()),
1113
+ );
1114
+ }
1115
+ }
1116
+
1117
+ return $result;
1118
+ }
1119
+
1120
+ public function productAttributeOptions($setId)
1121
+ {
1122
+ $result = array();
1123
+
1124
+ $setId = intval($setId);
1125
+ if ($setId <= 0) return $result;
1126
+
1127
+ $attributeAPI = Mage::getModel('catalog/product_attribute_api');
1128
+
1129
+ $items = $attributeAPI->items($setId);
1130
+
1131
+ $attributes = Mage::getModel('catalog/product')->getResource()
1132
+ ->loadAllAttributes();
1133
+
1134
+ $i=0;
1135
+ foreach ($items as $item) {
1136
+ if (!isset($item['attribute_id']) || empty($item['attribute_id'])) continue;
1137
+ $attributeId = intval($item['attribute_id']);
1138
+ if ($attributeId <= 0) continue;
1139
+
1140
+ $additionInfo = $this->_productAttributeInfo($attributeId, $attributeAPI);
1141
+
1142
+ if (in_array($additionInfo['frontend_input'], $this->_permittedAttributes) &&
1143
+ !in_array($additionInfo['attribute_code'], $this->_ignoredAttributes))
1144
+ {
1145
+ $result[$i] = array(
1146
+ 'attribute_id' => $additionInfo['attribute_id'],
1147
+ 'code' => $additionInfo['attribute_code'],
1148
+ 'type' => $additionInfo['frontend_input'],
1149
+ 'required' => $additionInfo['is_required'],
1150
+ 'scope' => $additionInfo['scope'],
1151
+ 'can_config' => 0
1152
+ );
1153
+
1154
+ if ( ($additionInfo['frontend_input'] == 'select') || ($additionInfo['frontend_input'] == 'multiselect') ) {
1155
+ if (($additionInfo['scope'] == 'global') &&
1156
+ ($additionInfo['is_configurable']))
1157
+ {
1158
+ foreach ($additionInfo['apply_to'] as $applyTo)
1159
+ {
1160
+ if ($applyTo == 'simple')
1161
+ {
1162
+ $result[$i]['can_config'] = 1;
1163
+ break;
1164
+ }
1165
+ }
1166
+
1167
+ }
1168
+ if (isset($additionInfo['options']))
1169
+ $result[$i]['attribute_options'] = $additionInfo['options'];
1170
+ }
1171
+ $i++;
1172
+ }
1173
+ }
1174
+
1175
+ return $result;
1176
+ }
1177
+
1178
+ public function update($productId, $productData, $store = null, $identifierType = 'id')
1179
+ {
1180
+ if ($identifierType == 'id')
1181
+ {
1182
+ $productId = intval($productId);
1183
+
1184
+ if ($productId < 1) {
1185
+ throw new Mage_Api_Exception('product_not_exists', null);
1186
+ }
1187
+ }
1188
+
1189
+ $store = $this->_currentStoreCode($store);
1190
+ try {
1191
+ $storeId = Mage::app()->getStore($store)->getId();
1192
+ } catch (Mage_Core_Model_Store_Exception $e) {
1193
+ throw new Mage_Api_Exception('store_not_exists', null);
1194
+ }
1195
+
1196
+ $_loadedProduct = Mage::helper('catalog/product')->getProduct($productId, $storeId, $identifierType);
1197
+
1198
+ $_categoryIds = $_loadedProduct->getCategoryIds();
1199
+ if (property_exists($productData, 'category_ids'))
1200
+ {
1201
+ if (!is_array($productData->category_ids))
1202
+ {
1203
+ $productData->category_ids = array($productData->category_ids);
1204
+ }
1205
+
1206
+ $productData->category_ids = array_merge($_categoryIds, $productData->category_ids);
1207
+ }
1208
+ else
1209
+ {
1210
+ $productData->category_ids = $_categoryIds;
1211
+ }
1212
+
1213
+ $productData->category_ids = array_unique($productData->category_ids);
1214
+
1215
+ if ( (property_exists($productData, 'removed_categories') === true)
1216
+ && (is_array($productData->removed_categories) === true)
1217
+ && (count($productData->removed_categories) > 0) )
1218
+ {
1219
+ $tmpCats = array();
1220
+
1221
+ $productData->category_ids = array_diff($productData->category_ids, $productData->removed_categories);
1222
+ }
1223
+
1224
+ $productData->categories = $productData->category_ids;
1225
+
1226
+ if (property_exists($productData, 'add_to_websites') && $productData->add_to_websites === true)
1227
+ {
1228
+ $currentWebsites = $_loadedProduct->getWebsiteIds();
1229
+ $websiteId = $this->_getWebsiteId();
1230
+ $websiteId = $websiteId[0];
1231
+
1232
+ if (in_array($websiteId, $currentWebsites) === false)
1233
+ {
1234
+ $currentWebsites[] = $websiteId;
1235
+ $productData->websites = $currentWebsites;
1236
+ }
1237
+ }
1238
+
1239
+ $this->_updateQuantity($productData);
1240
+
1241
+ $productData = $this->_fixAttributes($productData);
1242
+
1243
+ $productAPI = new Mage_Catalog_Model_Product_Api_V2();
1244
+
1245
+ $result = $productAPI->update($productId, $productData, $store, $identifierType);
1246
+
1247
+ return $result;
1248
+ }
1249
+
1250
+ public function create($type, $set, $sku, $productData, $store = null)
1251
+ {
1252
+ $store = $this->_currentStoreCode($store);
1253
+
1254
+ $DefaultStore = $this->_getStore();
1255
+
1256
+ if (property_exists($productData, 'websites') === false && isset($DefaultStore)) {
1257
+ $productData->websites = array($DefaultStore->getWebsiteId());
1258
+ }
1259
+
1260
+ if (property_exists($productData, 'category_ids') && !is_array($productData->category_ids)) {
1261
+ if (is_string($productData->category_ids))
1262
+ $productData->category_ids = array($productData->category_ids);
1263
+ }
1264
+ else if (property_exists($productData, 'category_ids') === false)
1265
+ {
1266
+ $productData->category_ids = array();
1267
+ }
1268
+
1269
+ $productData->categories = $productData->category_ids;
1270
+
1271
+ $this->_updateQuantity($productData);
1272
+
1273
+ $productData = $this->_fixAttributes($productData);
1274
+
1275
+ $productAPI = new Mage_Catalog_Model_Product_Api_V2();
1276
+
1277
+ return $productAPI->create($type, $set, $sku, $productData, $store);
1278
+ }
1279
+
1280
+ public function debugInfo()
1281
+ {
1282
+ $verInfo = Mage::getVersionInfo();
1283
+
1284
+ $result = array(
1285
+ 'llc_ver' => Settings::$VERSION,
1286
+ 'magento_ver' => $verInfo
1287
+ );
1288
+
1289
+ return $result;
1290
+ }
1291
+ }
1292
+
1293
+ class LinnLiveEnterprise extends LinnLiveMain{
1294
+
1295
+ public function productAttributeOptions($setId)
1296
+ {
1297
+ $result = array();
1298
+
1299
+ $setId = intval($setId);
1300
+ if ($setId <= 0) return $result;
1301
+
1302
+ $attributeAPI = Mage::getModel('catalog/product_attribute_api');
1303
+
1304
+ $attributes = Mage::getModel('catalog/product')->getResource()
1305
+ ->loadAllAttributes()
1306
+ ->getSortedAttributes($setId);
1307
+
1308
+ $i=0;
1309
+
1310
+ foreach ($attributes as $attribute) {
1311
+
1312
+ if ((!$attribute->getId() || $attribute->isInSet($setId))
1313
+ && !in_array($attribute->getAttributeCode(), $this->_ignoredAttributes)
1314
+ && in_array($attribute->getFrontendInput(), $this->_permittedAttributes)) {
1315
+
1316
+ if (!$attribute->getId() || $attribute->isScopeGlobal()) {
1317
+ $scope = 'global';
1318
+ } elseif ($attribute->isScopeWebsite()) {
1319
+ $scope = 'website';
1320
+ } else {
1321
+ $scope = 'store';
1322
+ }
1323
+
1324
+ $result[] = array(
1325
+ 'attribute_id' => $attribute->getId(),
1326
+ 'code' => $attribute->getAttributeCode(),
1327
+ 'type' => $attribute->getFrontendInput(),
1328
+ 'required' => $attribute->getIsRequired(),
1329
+ 'scope' => $scope,
1330
+ 'can_config' => 0
1331
+ );
1332
+
1333
+ if ( ($attribute->getFrontendInput() == 'select') || ($attribute->getFrontendInput() == 'multiselect') ) {
1334
+ if (($scope == 'global') &&
1335
+ $attribute->getIsConfigurable())
1336
+ {
1337
+ if (strpos($attribute->getApplyTo(), 'simple') !== false)
1338
+ $result[$i]['can_config'] = 1;
1339
+ }
1340
+
1341
+ $options = $attributeAPI->options($attribute->getId());
1342
+
1343
+ // remove empty first element
1344
+ if ($attribute->getFrontendInput() != 'boolean') {
1345
+ array_shift($options);
1346
+ }
1347
+
1348
+ if (count($options) > 0) {
1349
+ $result[$i]['attribute_options'] = $options;
1350
+ }
1351
+ }
1352
+ $i++;
1353
+ }
1354
+ }
1355
+
1356
+ return $result;
1357
+ }
1358
+
1359
+ //Fix for buggy associativeArray implementation
1360
+ private function _fixAttributes($productData)
1361
+ {
1362
+ $_newAttributeOptions = $this->_newOptions($productData);
1363
+ $_availableOptions = array();
1364
+ if (count($_newAttributeOptions) > 0)
1365
+ {
1366
+ $_availableOptions = $this->_createOptions($_newAttributeOptions);
1367
+ }
1368
+
1369
+ if (property_exists($productData, 'additional_attributes')) {
1370
+ $tmpAttr = $productData->additional_attributes;
1371
+ if (count($tmpAttr) == 0)
1372
+ {
1373
+ unset($productData->additional_attributes);
1374
+ return $productData;
1375
+ }
1376
+ $productData->additional_attributes = new stdClass();
1377
+ $productData->additional_attributes->single_data = array();
1378
+ $i=0;
1379
+ if (is_array($tmpAttr))
1380
+ {
1381
+ foreach ($tmpAttr as $option) {
1382
+ $productData->additional_attributes->single_data[$i] = new stdClass();
1383
+ $productData->additional_attributes->single_data[$i]->key = $option->code;
1384
+
1385
+ if ( ($option->type == 'multiselect') && (is_array($productData->additional_attributes->single_data[$i]->value) == false) )
1386
+ {
1387
+ $productData->additional_attributes->single_data[$i]->value = array();
1388
+ }
1389
+
1390
+ if (isset($_availableOptions[$option->attribute_id][strtolower($option->label)]))
1391
+ {
1392
+ if ($option->type == 'multiselect')
1393
+ {
1394
+ array_push($productData->additional_attributes->single_data[$i]->value, $_availableOptions[$option->attribute_id][strtolower($option->label)]);
1395
+ }
1396
+ else
1397
+ {
1398
+ $productData->additional_attributes->single_data[$i]->value = $_availableOptions[$option->attribute_id][strtolower($option->label)];
1399
+ }
1400
+ }
1401
+ else
1402
+ {
1403
+ if ($option->type == 'multiselect')
1404
+ {
1405
+ array_push($productData->additional_attributes->single_data[$i]->value, $option->value);
1406
+ }
1407
+ else
1408
+ {
1409
+ $productData->additional_attributes->single_data[$i]->value = $option->value;
1410
+ }
1411
+ }
1412
+ $i++;
1413
+ }
1414
+ }
1415
+ else
1416
+ {
1417
+ $productData->additional_attributes->single_data[0] = new stdClass();
1418
+ $productData->additional_attributes->single_data[0]->key = $tmpAttr->code;
1419
+ if (isset($_availableOptions[$tmpAttr->attribute_id][strtolower($tmpAttr->label)]))
1420
+ $productData->additional_attributes->single_data[0]->value = $_availableOptions[$tmpAttr->attribute_id][strtolower($tmpAttr->label)];
1421
+ else
1422
+ $productData->additional_attributes->single_data[0]->value = $tmpAttr->value;
1423
+ }
1424
+ }
1425
+
1426
+ return $productData;
1427
+ }
1428
+ }
1429
+
1430
+ class LinnLiveCommunity extends LinnLiveMain{
1431
+
1432
+ }
1433
+ ?>
app/code/local/LinnSystems/LinnLiveConnect/etc/api.xml ADDED
@@ -0,0 +1,147 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <api>
4
+ <resources>
5
+ <linnLive translate="title" module="linnLiveConnect">
6
+ <title>LinnLive connect module</title>
7
+ <model>linnLiveConnect/api</model>
8
+ <methods>
9
+ <configurableProduct translate="title" module="linnLiveConnect">
10
+ <title>Configurable products creation</title>
11
+ <acl>linnLive/configurableCreate</acl>
12
+ </configurableProduct>
13
+ <updateConfigurableProduct translate="title" module="linnLiveConnect">
14
+ <title>Configurable products creation</title>
15
+ <acl>linnLive/configrableUpdate</acl>
16
+ </updateConfigurableProduct>
17
+ <createProduct translate="title" module="linnLiveConnect">
18
+ <title>Create product (extended version)</title>
19
+ <method>create</method>
20
+ <acl>linnLive/create</acl>
21
+ </createProduct>
22
+ <updateProduct translate="title" module="linnLiveConnect">
23
+ <title>Update product (extended version)</title>
24
+ <method>update</method>
25
+ <acl>linnLive/update</acl>
26
+ </updateProduct>
27
+ <productAttributeOptions translate="title" module="linnLiveConnect">
28
+ <title>Get attributes by attribute Set id</title>
29
+ <acl>linnLive/attributeOptions</acl>
30
+ </productAttributeOptions>
31
+ <storesList translate="title" module="linnLiveConnect">
32
+ <title>Retreive list of install stores</title>
33
+ <acl>linnLive/storesList</acl>
34
+ </storesList>
35
+ <getStoreCode translate="title" module="linnLiveConnect">
36
+ <title>Get current store code</title>
37
+ <acl>linnLive/getStoreCode</acl>
38
+ </getStoreCode>
39
+ <productList translate="title" module="linnLiveConnect">
40
+ <title>Get current store code</title>
41
+ <acl>linnLive/productList</acl>
42
+ </productList>
43
+ <info translate="title" module="linnLiveConnect">
44
+ <title>Get information about current magento settings and installation</title>
45
+ <method>debugInfo</method>
46
+ <acl>linnLive/info</acl>
47
+ </info>
48
+ <assignImages translate="title" module="linnLiveConnect">
49
+ <title>Assigns configurable product images to children products</title>
50
+ <acl>linnLive/assignImages</acl>
51
+ </assignImages>
52
+ <deleteAssigned translate="title" module="linnLiveConnect">
53
+ <title>Remove assigned item from inventory</title>
54
+ <acl>linnLive/deleteAssigned</acl>
55
+ </deleteAssigned>
56
+ </methods>
57
+ <faults module="linnLiveConnect">
58
+ <data_invalid>
59
+ <code>100</code>
60
+ <message>Invalid data given. Details in error message.</message>
61
+ </data_invalid>
62
+ <product_type_not_exists>
63
+ <code>101</code>
64
+ <message>Product type is not in allowed types.</message>
65
+ </product_type_not_exists>
66
+ <product_attribute_set_not_exists>
67
+ <code>102</code>
68
+ <message>Product attribute set is not existed</message>
69
+ </product_attribute_set_not_exists>
70
+ <product_attribute_set_not_valid>
71
+ <code>103</code>
72
+ <message>Product attribute set is not belong catalog product entity type</message>
73
+ </product_attribute_set_not_valid>
74
+ <products_not_suitable>
75
+ <code>104</code>
76
+ <message>Product not suitable to be used in configurable product </message>
77
+ </products_not_suitable>
78
+ <configurable_creating_error>
79
+ <code>105</code>
80
+ <message>Configurable product creating error </message>
81
+ </configurable_creating_error>
82
+ <wrong_version>
83
+ <code>106</code>
84
+ <message>Wrong extended API version, please update your LinnLive Magento extension.
85
+ Go to System->Magento Connect->Magento Connect Manager in your Magento Admin panel,
86
+ and click on "Check for Upgrades", and upgrade you LinnLiveConnect extension to last one.</message>
87
+ </wrong_version>
88
+ <attribute_not_exists>
89
+ <code>107</code>
90
+ <message>Attribute not found</message>
91
+ </attribute_not_exists>
92
+ </faults>
93
+ </linnLive>
94
+ </resources>
95
+ <acl>
96
+ <resources>
97
+ <linnLive translate="title" module="linnLiveConnect">
98
+ <title>LinnLive</title>
99
+ <create translate="title" module="linnLiveConnect">
100
+ <title>Product creation (extended)</title>
101
+ </create>
102
+ <update translate="title" module="linnLiveConnect">
103
+ <title>Product update (extended)</title>
104
+ </update>
105
+ <attributeOptions translate="title" module="linnLiveConnect">
106
+ <title>Attribute options by set id</title>
107
+ </attributeOptions>
108
+ <storesList translate="title" module="linnLiveConnect">
109
+ <title>Get stores list</title>
110
+ </storesList>
111
+ <createImage translate="title" module="linnLiveConnect">
112
+ <title>Create image</title>
113
+ </createImage>
114
+ <updateImage translate="title" module="linnLiveConnect">
115
+ <title>Update image</title>
116
+ </updateImage>
117
+ <getStoreCode translate="title" module="linnLiveConnect">
118
+ <title>get current store code</title>
119
+ </getStoreCode>
120
+ <configurableCreate translate="title" module="linnLiveConnect">
121
+ <title>Configurable product creation</title>
122
+ </configurableCreate>
123
+ <configurableUpdate translate="title" module="linnLiveConnect">
124
+ <title>Configurable product update</title>
125
+ </configurableUpdate>
126
+ <productList translate="title" module="linnLiveConnect">
127
+ <title>Retrieve products list by filters</title>
128
+ </productList>
129
+ <info translate="title" module="linnLiveConnect">
130
+ <title>Get information about current magento settings and installation</title>
131
+ </info>
132
+ <assignImages translate="title" module="linnLiveConnect">
133
+ <title>Assigns configurable product images to children's products</title>
134
+ </assignImages>
135
+ <deleteAssigned translate="title" module="linnLiveConnect">
136
+ <title>Remove assigned item from inventory</title>
137
+ </deleteAssigned>
138
+ </linnLive>
139
+ </resources>
140
+ </acl>
141
+ <v2>
142
+ <resources_function_prefix>
143
+ <linnLive>linnLive</linnLive>
144
+ </resources_function_prefix>
145
+ </v2>
146
+ </api>
147
+ </config>
app/code/local/LinnSystems/LinnLiveConnect/etc/config.xml ADDED
@@ -0,0 +1,20 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <config>
3
+ <modules>
4
+ <LinnSystems_LinnLiveConnect>
5
+ <version>1.0.19</version>
6
+ </LinnSystems_LinnLiveConnect>
7
+ </modules>
8
+ <global>
9
+ <helpers>
10
+ <linnLiveConnect>
11
+ <class>LinnSystems_LinnLiveConnect_Helper</class>
12
+ </linnLiveConnect>
13
+ </helpers>
14
+ <models>
15
+ <linnLiveConnect>
16
+ <class>LinnSystems_LinnLiveConnect_Model</class>
17
+ </linnLiveConnect>
18
+ </models>
19
+ </global>
20
+ </config>
app/code/local/LinnSystems/LinnLiveConnect/etc/wsdl.xml ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <definitions xmlns:typens="urn:{{var wsdl.name}}" xmlns:xsd="http://www.w3.org/2001/XMLSchema" xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
3
+ xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/" xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/" xmlns="http://schemas.xmlsoap.org/wsdl/"
4
+ name="{{var wsdl.name}}" targetNamespace="urn:{{var wsdl.name}}">
5
+ <types>
6
+ <schema xmlns="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:Magento">
7
+ <import namespace="http://schemas.xmlsoap.org/soap/encoding/" schemaLocation="http://schemas.xmlsoap.org/soap/encoding/" />
8
+ <complexType name="linnLiveConfigurableName">
9
+ <all>
10
+ <element name="name" type="xsd:string" />
11
+ </all>
12
+ </complexType>
13
+ <!--complexType name="resourceNameEntityArray">
14
+ <complexContent>
15
+ <restriction base="soapenc:Array">
16
+ <attribute ref="soapenc:arrayType" wsdl:arrayType="typens:resourceNameEntity[]" />
17
+ </restriction>
18
+ </complexContent>
19
+ </complexType-->
20
+ </schema>
21
+ </types>
22
+ <message name="linnLiveConfigurableProductRequest">
23
+ <part name="sessionId" type="xsd:string" />
24
+ </message>
25
+ <message name="linnLiveConfigurableProductResponse">
26
+ <part name="result" type="xsd:string" />
27
+ </message>
28
+ <portType name="{{var wsdl.handler}}PortType">
29
+ <operation name="linnLiveConfigurableProduct">
30
+ <documentation>Test method</documentation>
31
+ <input message="typens:linnLiveConfigurableProductRequest" />
32
+ <output message="typens:linnLiveConfigurableProductResponse" />
33
+ </operation>
34
+ </portType>
35
+ <binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
36
+ <soap:binding style="rpc" transport="http://schemas.xmlsoap.org/soap/http" />
37
+ <operation name="linnLiveConfigurableProduct">
38
+ <soap:operation soapAction="urn:{{var wsdl.handler}}Action" />
39
+ <input>
40
+ <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
41
+ </input>
42
+ <output>
43
+ <soap:body namespace="urn:{{var wsdl.name}}" use="encoded" encodingStyle="http://schemas.xmlsoap.org/soap/encoding/" />
44
+ </output>
45
+ </operation>
46
+ </binding>
47
+ <service name="{{var wsdl.name}}Service">
48
+ <port name="{{var wsdl.handler}}Port" binding="typens:{{var wsdl.handler}}Binding">
49
+ <soap:address location="{{var wsdl.url}}" />
50
+ </port>
51
+ </service>
52
+ </definitions>
app/code/local/LinnSystems/LinnLiveConnect/etc/wsi.xml ADDED
@@ -0,0 +1,759 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0" encoding="UTF-8"?>
2
+ <wsdl:definitions xmlns:typens="urn:{{var wsdl.name}}"
3
+ xmlns:xsd="http://www.w3.org/2001/XMLSchema"
4
+ xmlns:soap="http://schemas.xmlsoap.org/wsdl/soap/"
5
+ xmlns:soapenc="http://schemas.xmlsoap.org/soap/encoding/"
6
+ xmlns:wsdl="http://schemas.xmlsoap.org/wsdl/"
7
+ name="{{var wsdl.name}}"
8
+ targetNamespace="urn:{{var wsdl.name}}">
9
+ <wsdl:types>
10
+ <xsd:schema xmlns:xsd="http://www.w3.org/2001/XMLSchema" targetNamespace="urn:{{var wsdl.name}}">
11
+ <!-- Enchanced Filters -->
12
+ <xsd:complexType name="complexDownloadFilter">
13
+ <xsd:sequence>
14
+ <xsd:element name="key" type="xsd:string"/>
15
+ <xsd:element name="value" type="typens:associativeEntity"/>
16
+ </xsd:sequence>
17
+ </xsd:complexType>
18
+ <xsd:complexType name="complexDownloadFilterArray">
19
+ <xsd:sequence>
20
+ <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:complexDownloadFilter"/>
21
+ </xsd:sequence>
22
+ </xsd:complexType>
23
+ <xsd:complexType name="downloadFilters">
24
+ <xsd:sequence>
25
+ <xsd:element name="filter" type="typens:associativeArray" minOccurs="0" />
26
+ <xsd:element name="complex_filter" type="typens:complexDownloadFilterArray" minOccurs="0" />
27
+ </xsd:sequence>
28
+ </xsd:complexType>
29
+ <!-- END of Enchanced Filters -->
30
+
31
+ <xsd:complexType name="linnLiveAssignImagesEntitiesArray">
32
+ <xsd:sequence>
33
+ <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:linnLiveAssignImagesEntity" />
34
+ </xsd:sequence>
35
+ </xsd:complexType>
36
+ <xsd:complexType name="linnLiveAssignImagesEntity">
37
+ <xsd:sequence>
38
+ <xsd:element minOccurs="1" name="image_name" type="xsd:string" />
39
+ <xsd:element minOccurs="1" name="types" type="typens:ArrayOfString" />
40
+ <xsd:element minOccurs="0" name="label" type="xsd:string" />
41
+ </xsd:sequence>
42
+ </xsd:complexType>
43
+
44
+ <xsd:complexType name="linnLiveAssignImagesProductEntitiesArray">
45
+ <xsd:sequence>
46
+ <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:linnLiveAssignImagesProductEntity" />
47
+ </xsd:sequence>
48
+ </xsd:complexType>
49
+ <xsd:complexType name="linnLiveAssignImagesProductEntity">
50
+ <xsd:sequence>
51
+ <xsd:element minOccurs="1" name="product_id" type="xsd:int" />
52
+ <xsd:element minOccurs="1" name="images" type="typens:linnLiveAssignImagesEntitiesArray" />
53
+ </xsd:sequence>
54
+ </xsd:complexType>
55
+
56
+ <!-- Attribute options enchancement -->
57
+ <xsd:complexType name="linnLiveAttributeOptionsListArray">
58
+ <xsd:sequence>
59
+ <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:linnLiveAttributeOptionEntityArray" />
60
+ </xsd:sequence>
61
+ </xsd:complexType>
62
+ <xsd:complexType name="linnLiveAttributeOptionEntityArray">
63
+ <xsd:sequence>
64
+ <xsd:element minOccurs="1" name="attribute_id" type="xsd:string" />
65
+ <xsd:element minOccurs="1" name="code" type="xsd:string" />
66
+ <xsd:element minOccurs="1" name="type" type="xsd:string" />
67
+ <xsd:element minOccurs="1" name="required" type="xsd:int" />
68
+ <xsd:element minOccurs="1" name="scope" type="xsd:string" />
69
+ <xsd:element minOccurs="1" name="can_config" type="xsd:int" />
70
+ <xsd:element minOccurs="0" name="attribute_options" type="typens:catalogAttributeOptionEntityArray" />
71
+ </xsd:sequence>
72
+ </xsd:complexType>
73
+ <xsd:element name="linnLiveAttributeOptionsResponseParam">
74
+ <xsd:complexType>
75
+ <xsd:sequence>
76
+ <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:linnLiveAttributeOptionsListArray" />
77
+ </xsd:sequence>
78
+ </xsd:complexType>
79
+ </xsd:element>
80
+ <xsd:element name="linnLiveAttributesOptionsRequestParam">
81
+ <xsd:complexType>
82
+ <xsd:sequence>
83
+ <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
84
+ <xsd:element minOccurs="1" name="version" type="xsd:int" />
85
+ <xsd:element minOccurs="1" maxOccurs="1" name="setId" type="xsd:int" />
86
+ </xsd:sequence>
87
+ </xsd:complexType>
88
+ </xsd:element>
89
+ <!-- Attribute options enchancement end -->
90
+ <!-- Configurable product data sets -->
91
+ <xsd:complexType name="linnLiveConfigurableAssignedProductsArray">
92
+ <xsd:sequence>
93
+ <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:linnLiveConfigurableAssignedProduct" />
94
+ </xsd:sequence>
95
+ </xsd:complexType>
96
+ <xsd:complexType name="linnLiveConfigurableAssignedProduct">
97
+ <xsd:sequence>
98
+ <xsd:element minOccurs="1" name="product_id" type="xsd:int" />
99
+ <xsd:element minOccurs="1" name="values" type="typens:linnLiveConfigurableAttributesArray" />
100
+ </xsd:sequence>
101
+ </xsd:complexType>
102
+
103
+
104
+ <xsd:complexType name="linnLiveConfigurableAssignedAttributesArray">
105
+ <xsd:sequence>
106
+ <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:linnLiveConfigurableAssignedAttribute" />
107
+ </xsd:sequence>
108
+ </xsd:complexType>
109
+ <xsd:complexType name="linnLiveConfigurableAssignedAttribute">
110
+ <xsd:sequence>
111
+ <!--xsd:element minOccurs="1" name="id" type="xsd:int" /-->
112
+ <xsd:element minOccurs="1" name="label" type="xsd:string" />
113
+ <!--xsd:element minOccurs="1" name="position" type="xsd:int" /-->
114
+ <!--xsd:element minOccurs="1" name="values" type="typens:linnLiveConfigurableAttributesArray" /-->
115
+ <xsd:element minOccurs="1" name="attribute_id" type="xsd:int" />
116
+ <xsd:element minOccurs="1" name="attribute_code" type="xsd:string" />
117
+ <xsd:element minOccurs="1" name="frontend_label" type="xsd:string" />
118
+ <xsd:element minOccurs="1" name="html_id" type="xsd:string" />
119
+ </xsd:sequence>
120
+ </xsd:complexType>
121
+
122
+
123
+ <xsd:complexType name="linnLiveConfigurableAttributesArray">
124
+ <xsd:sequence>
125
+ <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:linnLiveConfigurableAttribute" />
126
+ </xsd:sequence>
127
+ </xsd:complexType>
128
+ <xsd:complexType name="linnLiveConfigurableAttribute">
129
+ <xsd:sequence>
130
+ <xsd:element minOccurs="1" name="attribute_id" type="xsd:int" />
131
+ <xsd:element minOccurs="1" name="label" type="xsd:string" />
132
+ <xsd:element minOccurs="1" name="value_index" type="xsd:string" />
133
+ <xsd:element minOccurs="1" name="is_percent" type="xsd:boolean" />
134
+ <xsd:element minOccurs="1" name="pricing_value" type="xsd:double" />
135
+ </xsd:sequence>
136
+ </xsd:complexType>
137
+ <!-- Configurable product data sets end -->
138
+
139
+ <xsd:complexType name="linnLiveInfoMagentoVer">
140
+ <xsd:sequence>
141
+ <xsd:element minOccurs="1" name="major" type="xsd:string" />
142
+ <xsd:element minOccurs="1" name="minor" type="xsd:string" />
143
+ <xsd:element minOccurs="1" name="revision" type="xsd:string" />
144
+ <xsd:element minOccurs="1" name="patch" type="xsd:string" />
145
+ <xsd:element minOccurs="1" name="stability" type="xsd:string" />
146
+ <xsd:element minOccurs="1" name="number" type="xsd:string" />
147
+ </xsd:sequence>
148
+ </xsd:complexType>
149
+
150
+ <xsd:complexType name="linnLiveInfoData">
151
+ <xsd:sequence>
152
+ <xsd:element minOccurs="1" name="llc_ver" type="xsd:int" />
153
+ <xsd:element minOccurs="1" name="magento_ver" type="typens:linnLiveInfoMagentoVer" />
154
+ </xsd:sequence>
155
+ </xsd:complexType>
156
+
157
+ <!-- Products List data sets-->
158
+
159
+ <xsd:complexType name="linnLiveImagesArray">
160
+ <xsd:sequence>
161
+ <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:linnLiveImageEntity" />
162
+ </xsd:sequence>
163
+ </xsd:complexType>
164
+ <xsd:complexType name="linnLiveImageEntity">
165
+ <xsd:sequence>
166
+ <xsd:element minOccurs="1" name="file" type="xsd:string" />
167
+ <xsd:element minOccurs="1" name="label" type="xsd:string" />
168
+ <xsd:element minOccurs="1" name="image" type="xsd:boolean" />
169
+ <xsd:element minOccurs="1" name="small_image" type="xsd:boolean" />
170
+ <xsd:element minOccurs="1" name="thumbnail" type="xsd:boolean" />
171
+ <xsd:element minOccurs="1" name="disabled" type="xsd:boolean" />
172
+ </xsd:sequence>
173
+ </xsd:complexType>
174
+ <xsd:complexType name="linnLiveProductsList">
175
+ <xsd:sequence>
176
+ <xsd:element minOccurs="1" name="count" type="xsd:int" />
177
+ <xsd:element minOccurs="1" maxOccurs="1" name="products" type="typens:linnLiveProductEntityArray" />
178
+ </xsd:sequence>
179
+ </xsd:complexType>
180
+
181
+ <xsd:complexType name="linnLiveProductEntityArray">
182
+ <xsd:sequence>
183
+ <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:linnLiveProductEntity" />
184
+ </xsd:sequence>
185
+ </xsd:complexType>
186
+
187
+ <xsd:complexType name="linnLiveConfigurableOptionsArray">
188
+ <xsd:sequence>
189
+ <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:linnLiveConfigurableOption" />
190
+ </xsd:sequence>
191
+ </xsd:complexType>
192
+
193
+ <xsd:complexType name="linnLiveConfigurableOption">
194
+ <xsd:sequence>
195
+ <xsd:element minOccurs="1" name="code" type="xsd:string" />
196
+ <xsd:element minOccurs="1" maxOccurs="unbounded" name="prices" type="typens:linnLiveConfigurablePriceEntityArray" />
197
+ </xsd:sequence>
198
+ </xsd:complexType>
199
+
200
+ <xsd:complexType name="linnLiveConfigurablePriceEntityArray">
201
+ <xsd:sequence>
202
+ <xsd:element minOccurs="1" maxOccurs="1" name="value_index" type="xsd:int" />
203
+ <xsd:element minOccurs="1" maxOccurs="1" name="is_fixed" type="xsd:boolean" />
204
+ <xsd:element minOccurs="1" maxOccurs="1" name="price_diff" type="xsd:string" />
205
+ <xsd:element minOccurs="1" maxOccurs="1" name="label" type="xsd:string" />
206
+ </xsd:sequence>
207
+ </xsd:complexType>
208
+
209
+ <xsd:complexType name="linnLiveProductEntity">
210
+ <xsd:sequence>
211
+ <xsd:element minOccurs="1" maxOccurs="1" name="product_id" type="xsd:int" />
212
+ <xsd:element minOccurs="1" maxOccurs="1" name="sku" type="xsd:string" />
213
+ <xsd:element minOccurs="1" maxOccurs="1" name="name" type="xsd:string" />
214
+ <xsd:element minOccurs="1" maxOccurs="1" name="set" type="xsd:string" />
215
+ <xsd:element minOccurs="1" maxOccurs="1" name="type" type="xsd:string" />
216
+ <xsd:element minOccurs="1" maxOccurs="1" name="price" type="xsd:string" />
217
+ <xsd:element minOccurs="1" maxOccurs="1" name="status" type="xsd:boolean" />
218
+ <xsd:element minOccurs="1" maxOccurs="1" name="description" type="xsd:string" />
219
+ <xsd:element minOccurs="1" maxOccurs="1" name="assigned_ids" type="typens:ArrayOfInt" />
220
+ <xsd:element minOccurs="1" maxOccurs="1" name="conf_attrib_ids" type="typens:linnLiveConfigurableOptionsArray" />
221
+ <xsd:element minOccurs="1" maxOccurs="1" name="attributes" type="typens:associativeArray" />
222
+ <xsd:element minOccurs="1" maxOccurs="1" name="category_ids" type="typens:ArrayOfString" />
223
+ <xsd:element minOccurs="1" maxOccurs="1" name="images" type="typens:linnLiveImagesArray" />
224
+ <xsd:element minOccurs="1" maxOccurs="1" name="website_ids" type="typens:ArrayOfString" />
225
+ </xsd:sequence>
226
+ </xsd:complexType>
227
+ <!-- Products List data sets end-->
228
+ <!-- Product create date-->
229
+ <xsd:complexType name="linnLiveProductCreateEntity">
230
+ <xsd:sequence>
231
+ <xsd:element name="categories" type="typens:ArrayOfString" minOccurs="0" />
232
+ <xsd:element name="removed_categories" type="typens:ArrayOfInt" minOccurs="0" />
233
+ <xsd:element name="websites" type="typens:ArrayOfString" minOccurs="0" />
234
+ <xsd:element name="add_to_websites" type="xsd:boolean" minOccurs="1" />
235
+ <xsd:element name="name" type="xsd:string" minOccurs="0" />
236
+ <xsd:element name="description" type="xsd:string" minOccurs="0" />
237
+ <xsd:element name="short_description" type="xsd:string" minOccurs="0" />
238
+ <xsd:element name="weight" type="xsd:string" minOccurs="0" />
239
+ <xsd:element name="status" type="xsd:string" minOccurs="0" />
240
+ <xsd:element name="url_key" type="xsd:string" minOccurs="0" />
241
+ <xsd:element name="url_path" type="xsd:string" minOccurs="0" />
242
+ <xsd:element name="visibility" type="xsd:string" minOccurs="0" />
243
+ <xsd:element name="category_ids" type="typens:ArrayOfString" minOccurs="0" />
244
+ <xsd:element name="website_ids" type="typens:ArrayOfString" minOccurs="0" />
245
+ <xsd:element name="has_options" type="xsd:string" minOccurs="0" />
246
+ <xsd:element name="gift_message_available" type="xsd:string" minOccurs="0" />
247
+ <xsd:element name="price" type="xsd:string" minOccurs="0" />
248
+ <xsd:element name="special_price" type="xsd:string" minOccurs="0" />
249
+ <xsd:element name="special_from_date" type="xsd:string" minOccurs="0" />
250
+ <xsd:element name="special_to_date" type="xsd:string" minOccurs="0" />
251
+ <xsd:element name="tax_class_id" type="xsd:string" minOccurs="0" />
252
+ <xsd:element name="tier_price" type="typens:catalogProductTierPriceEntityArray" minOccurs="0" />
253
+ <xsd:element name="meta_title" type="xsd:string" minOccurs="0" />
254
+ <xsd:element name="meta_keyword" type="xsd:string" minOccurs="0" />
255
+ <xsd:element name="meta_description" type="xsd:string" minOccurs="0" />
256
+ <xsd:element name="custom_design" type="xsd:string" minOccurs="0" />
257
+ <xsd:element name="custom_layout_update" type="xsd:string" minOccurs="0" />
258
+ <xsd:element name="options_container" type="xsd:string" minOccurs="0" />
259
+ <xsd:element name="additional_attributes" type="typens:linnLiveAdditionaAttributesArray" minOccurs="0" />
260
+ <xsd:element name="stock_data" type="typens:catalogInventoryStockItemUpdateEntity" minOccurs="0" />
261
+ </xsd:sequence>
262
+ </xsd:complexType>
263
+ <xsd:complexType name="linnLiveAdditionaAttributesArray">
264
+ <xsd:sequence>
265
+ <xsd:element minOccurs="0" maxOccurs="unbounded" name="complexObjectArray" type="typens:linnLiveAdditionaAttribute" />
266
+ </xsd:sequence>
267
+ </xsd:complexType>
268
+ <xsd:complexType name="linnLiveAdditionaAttribute">
269
+ <xsd:sequence>
270
+ <xsd:element minOccurs="1" name="attribute_id" type="xsd:string" />
271
+ <xsd:element minOccurs="1" name="code" type="xsd:string" />
272
+ <xsd:element minOccurs="1" name="label" type="xsd:string" />
273
+ <xsd:element minOccurs="1" name="type" type="xsd:string" />
274
+ <xsd:element minOccurs="1" name="value" type="xsd:string" />
275
+ </xsd:sequence>
276
+ </xsd:complexType>
277
+ <!-- Product create date end-->
278
+ <xsd:element name="linnLiveConfigurableProductRequestParam">
279
+ <xsd:complexType>
280
+ <xsd:sequence>
281
+ <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
282
+ <xsd:element minOccurs="1" maxOccurs="1" name="version" type="xsd:int" />
283
+ <xsd:element minOccurs="1" maxOccurs="1" name="set" type="xsd:string" />
284
+ <xsd:element minOccurs="1" maxOccurs="1" name="sku" type="xsd:string" />
285
+ <xsd:element minOccurs="1" maxOccurs="1" name="reindex" type="xsd:boolean" />
286
+ <xsd:element minOccurs="1" maxOccurs="1" name="productData" type="typens:linnLiveProductCreateEntity" />
287
+ <xsd:element minOccurs="1" maxOccurs="1" name="productsSet" type="typens:linnLiveConfigurableAssignedProductsArray" />
288
+ <xsd:element minOccurs="1" maxOccurs="1" name="attributesSet" type="typens:linnLiveConfigurableAssignedAttributesArray" />
289
+ <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
290
+ </xsd:sequence>
291
+ </xsd:complexType>
292
+ </xsd:element>
293
+ <xsd:element name="linnLiveConfigurableProductResponseParam">
294
+ <xsd:complexType>
295
+ <xsd:sequence>
296
+ <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
297
+ </xsd:sequence>
298
+ </xsd:complexType>
299
+ </xsd:element>
300
+
301
+ <xsd:element name="linnLiveUpdateConfigurableProductRequestParam">
302
+ <xsd:complexType>
303
+ <xsd:sequence>
304
+ <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
305
+ <xsd:element minOccurs="1" maxOccurs="1" name="version" type="xsd:int" />
306
+ <xsd:element minOccurs="1" maxOccurs="1" name="productId" type="xsd:string" />
307
+ <xsd:element minOccurs="1" maxOccurs="1" name="reindex" type="xsd:boolean" />
308
+ <xsd:element minOccurs="1" maxOccurs="1" name="productData" type="typens:linnLiveProductCreateEntity" />
309
+ <xsd:element minOccurs="1" maxOccurs="1" name="productsSet" type="typens:linnLiveConfigurableAssignedProductsArray" />
310
+ <xsd:element minOccurs="1" maxOccurs="1" name="attributesSet" type="typens:linnLiveConfigurableAssignedAttributesArray" />
311
+ <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
312
+ <xsd:element minOccurs="0" maxOccurs="1" name="identifierType" type="xsd:string" />
313
+ </xsd:sequence>
314
+ </xsd:complexType>
315
+ </xsd:element>
316
+ <xsd:element name="linnLiveUpdateConfigurableProductResponseParam">
317
+ <xsd:complexType>
318
+ <xsd:sequence>
319
+ <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:boolean" />
320
+ </xsd:sequence>
321
+ </xsd:complexType>
322
+ </xsd:element>
323
+
324
+ <xsd:element name="linnLiveCreateProductRequestParam">
325
+ <xsd:complexType>
326
+ <xsd:sequence>
327
+ <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
328
+ <xsd:element minOccurs="1" maxOccurs="1" name="version" type="xsd:int" />
329
+ <xsd:element minOccurs="1" maxOccurs="1" name="type" type="xsd:string" />
330
+ <xsd:element minOccurs="1" maxOccurs="1" name="set" type="xsd:string" />
331
+ <xsd:element minOccurs="1" maxOccurs="1" name="sku" type="xsd:string" />
332
+ <xsd:element minOccurs="1" maxOccurs="1" name="productData" type="typens:linnLiveProductCreateEntity" />
333
+ <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
334
+ </xsd:sequence>
335
+ </xsd:complexType>
336
+ </xsd:element>
337
+ <xsd:element name="linnLiveCreateProductResponseParam">
338
+ <xsd:complexType>
339
+ <xsd:sequence>
340
+ <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:int" />
341
+ </xsd:sequence>
342
+ </xsd:complexType>
343
+ </xsd:element>
344
+
345
+ <xsd:element name="linnLiveUpdateProductRequestParam">
346
+ <xsd:complexType>
347
+ <xsd:sequence>
348
+ <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
349
+ <xsd:element minOccurs="1" maxOccurs="1" name="version" type="xsd:int" />
350
+ <xsd:element minOccurs="1" maxOccurs="1" name="productId" type="xsd:string" />
351
+ <xsd:element minOccurs="1" maxOccurs="1" name="productData" type="typens:linnLiveProductCreateEntity" />
352
+ <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
353
+ <xsd:element minOccurs="0" maxOccurs="1" name="identifierType" type="xsd:string" />
354
+ </xsd:sequence>
355
+ </xsd:complexType>
356
+ </xsd:element>
357
+ <xsd:element name="linnLiveUpdateProductResponseParam">
358
+ <xsd:complexType>
359
+ <xsd:sequence>
360
+ <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:boolean" />
361
+ </xsd:sequence>
362
+ </xsd:complexType>
363
+ </xsd:element>
364
+
365
+ <xsd:element name="linnLiveStoresListRequestParam">
366
+ <xsd:complexType>
367
+ <xsd:sequence>
368
+ <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
369
+ <xsd:element minOccurs="1" maxOccurs="1" name="version" type="xsd:int" />
370
+ </xsd:sequence>
371
+ </xsd:complexType>
372
+ </xsd:element>
373
+ <xsd:element name="linnLiveStoresListResponseParam">
374
+ <xsd:complexType>
375
+ <xsd:sequence>
376
+ <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:boolean" />
377
+ </xsd:sequence>
378
+ </xsd:complexType>
379
+ </xsd:element>
380
+
381
+ <!-- Stub parameters for catalogProductAttributeRemove -->
382
+ <xsd:element name="linnLiveAttributeRemoveRequestParam">
383
+ <xsd:complexType>
384
+ <xsd:sequence>
385
+ <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
386
+ <xsd:element minOccurs="1" maxOccurs="1" name="version" type="xsd:int" />
387
+ </xsd:sequence>
388
+ </xsd:complexType>
389
+ </xsd:element>
390
+ <xsd:element name="linnLiveAttributeRemoveResponseParam">
391
+ <xsd:complexType>
392
+ <xsd:sequence>
393
+ <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:string" />
394
+ </xsd:sequence>
395
+ </xsd:complexType>
396
+ </xsd:element>
397
+ <!-- Stub parameters for catalogProductAttributeRemove end -->
398
+
399
+ <xsd:element name="linnLiveInfoRequestParam">
400
+ <xsd:complexType>
401
+ <xsd:sequence>
402
+ <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
403
+ <xsd:element minOccurs="1" maxOccurs="1" name="version" type="xsd:int" />
404
+ </xsd:sequence>
405
+ </xsd:complexType>
406
+ </xsd:element>
407
+ <xsd:element name="linnLiveInfoResponseParam">
408
+ <xsd:complexType>
409
+ <xsd:sequence>
410
+ <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:linnLiveInfoData" />
411
+ </xsd:sequence>
412
+ </xsd:complexType>
413
+ </xsd:element>
414
+
415
+ <xsd:element name="linnLiveGetStoreCodeRequestParam">
416
+ <xsd:complexType>
417
+ <xsd:sequence>
418
+ <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
419
+ <xsd:element minOccurs="1" maxOccurs="1" name="version" type="xsd:int" />
420
+ </xsd:sequence>
421
+ </xsd:complexType>
422
+ </xsd:element>
423
+ <xsd:element name="linnLiveGetStoreCodeResponseParam">
424
+ <xsd:complexType>
425
+ <xsd:sequence>
426
+ <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:string" />
427
+ </xsd:sequence>
428
+ </xsd:complexType>
429
+ </xsd:element>
430
+
431
+
432
+ <xsd:element name="linnLiveProductListRequestParam">
433
+ <xsd:complexType>
434
+ <xsd:sequence>
435
+ <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
436
+ <xsd:element minOccurs="1" maxOccurs="1" name="version" type="xsd:int" />
437
+ <xsd:element minOccurs="1" maxOccurs="1" name="page" type="xsd:int" />
438
+ <xsd:element minOccurs="1" maxOccurs="1" name="perPage" type="xsd:int" />
439
+ <xsd:element minOccurs="1" maxOccurs="1" name="filters" type="typens:downloadFilters" />
440
+ <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
441
+ </xsd:sequence>
442
+ </xsd:complexType>
443
+ </xsd:element>
444
+ <xsd:element name="linnLiveProductListResponseParam">
445
+ <xsd:complexType>
446
+ <xsd:sequence>
447
+ <xsd:element minOccurs="1" maxOccurs="1" name="result" type="typens:linnLiveProductsList" />
448
+ </xsd:sequence>
449
+ </xsd:complexType>
450
+ </xsd:element>
451
+
452
+ <xsd:element name="linnLiveAssignImagesRequestParam">
453
+ <xsd:complexType>
454
+ <xsd:sequence>
455
+ <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
456
+ <xsd:element minOccurs="1" maxOccurs="1" name="version" type="xsd:int" />
457
+ <xsd:element minOccurs="1" maxOccurs="1" name="productImages" type="typens:linnLiveAssignImagesProductEntitiesArray" />
458
+ </xsd:sequence>
459
+ </xsd:complexType>
460
+ </xsd:element>
461
+ <xsd:element name="linnLiveAssignImagesResponseParam">
462
+ <xsd:complexType>
463
+ <xsd:sequence>
464
+ <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:boolean" />
465
+ </xsd:sequence>
466
+ </xsd:complexType>
467
+ </xsd:element>
468
+
469
+ <xsd:element name="linnLiveDeleteAssignedRequestParam">
470
+ <xsd:complexType>
471
+ <xsd:sequence>
472
+ <xsd:element minOccurs="1" maxOccurs="1" name="sessionId" type="xsd:string" />
473
+ <xsd:element minOccurs="1" maxOccurs="1" name="version" type="xsd:int" />
474
+ <xsd:element minOccurs="1" maxOccurs="1" name="productId" type="xsd:string" />
475
+ <xsd:element minOccurs="0" maxOccurs="1" name="store" type="xsd:string" />
476
+ <xsd:element minOccurs="0" maxOccurs="1" name="identifierType" type="xsd:string" />
477
+ </xsd:sequence>
478
+ </xsd:complexType>
479
+ </xsd:element>
480
+ <xsd:element name="linnLiveDeleteAssignedResponseParam">
481
+ <xsd:complexType>
482
+ <xsd:sequence>
483
+ <xsd:element minOccurs="1" maxOccurs="1" name="result" type="xsd:boolean" />
484
+ </xsd:sequence>
485
+ </xsd:complexType>
486
+ </xsd:element>
487
+
488
+
489
+ </xsd:schema>
490
+ </wsdl:types>
491
+
492
+ <!-- Attribute options enchancement -->
493
+ <wsdl:message name="linnLiveProductAttributeOptionsResponse">
494
+ <wsdl:part name="parameters" element="typens:linnLiveAttributeOptionsResponseParam" />
495
+ </wsdl:message>
496
+ <wsdl:message name="linnLiveProductAttributeOptionsRequest">
497
+ <wsdl:part name="parameters" element="typens:linnLiveAttributesOptionsRequestParam" />
498
+ </wsdl:message>
499
+ <!-- Attribute options enchancement end -->
500
+ <wsdl:message name="linnLiveConfigurableProductRequest">
501
+ <wsdl:part name="parameters" element="typens:linnLiveConfigurableProductRequestParam" />
502
+ </wsdl:message>
503
+ <wsdl:message name="linnLiveConfigurableProductResponse">
504
+ <wsdl:part name="parameters" element="typens:linnLiveConfigurableProductResponseParam" />
505
+ </wsdl:message>
506
+ <wsdl:message name="linnLiveUpdateConfigurableProductRequest">
507
+ <wsdl:part name="parameters" element="typens:linnLiveUpdateConfigurableProductRequestParam" />
508
+ </wsdl:message>
509
+ <wsdl:message name="linnLiveUpdateConfigurableProductResponse">
510
+ <wsdl:part name="parameters" element="typens:linnLiveUpdateConfigurableProductResponseParam" />
511
+ </wsdl:message>
512
+ <wsdl:message name="linnLiveCreateProductRequest">
513
+ <wsdl:part name="parameters" element="typens:linnLiveCreateProductRequestParam" />
514
+ </wsdl:message>
515
+ <wsdl:message name="linnLiveCreateProductResponse">
516
+ <wsdl:part name="parameters" element="typens:linnLiveCreateProductResponseParam" />
517
+ </wsdl:message>
518
+ <wsdl:message name="linnLiveUpdateProductRequest">
519
+ <wsdl:part name="parameters" element="typens:linnLiveUpdateProductRequestParam" />
520
+ </wsdl:message>
521
+ <wsdl:message name="linnLiveUpdateProductResponse">
522
+ <wsdl:part name="parameters" element="typens:linnLiveUpdateProductResponseParam" />
523
+ </wsdl:message>
524
+ <wsdl:message name="linnLiveStoresListRequest">
525
+ <wsdl:part name="parameters" element="typens:linnLiveStoresListRequestParam" />
526
+ </wsdl:message>
527
+ <wsdl:message name="linnLiveStoresListResponse">
528
+ <wsdl:part name="parameters" element="typens:linnLiveStoresListResponseParam" />
529
+ </wsdl:message>
530
+ <wsdl:message name="linnLiveGetStoreCodeRequest">
531
+ <wsdl:part name="parameters" element="typens:linnLiveGetStoreCodeRequestParam" />
532
+ </wsdl:message>
533
+ <wsdl:message name="linnLiveGetStoreCodeResponse">
534
+ <wsdl:part name="parameters" element="typens:linnLiveGetStoreCodeResponseParam" />
535
+ </wsdl:message>
536
+ <wsdl:message name="linnLiveProductListRequest">
537
+ <wsdl:part name="parameters" element="typens:linnLiveProductListRequestParam" />
538
+ </wsdl:message>
539
+ <wsdl:message name="linnLiveProductListResponse">
540
+ <wsdl:part name="parameters" element="typens:linnLiveProductListResponseParam" />
541
+ </wsdl:message>
542
+ <wsdl:message name="linnLiveInfoRequest">
543
+ <wsdl:part name="parameters" element="typens:linnLiveInfoRequestParam" />
544
+ </wsdl:message>
545
+ <wsdl:message name="linnLiveInfoResponse">
546
+ <wsdl:part name="parameters" element="typens:linnLiveInfoResponseParam" />
547
+ </wsdl:message>
548
+
549
+ <wsdl:message name="linnLiveAssignImagesRequest">
550
+ <wsdl:part name="parameters" element="typens:linnLiveAssignImagesRequestParam" />
551
+ </wsdl:message>
552
+ <wsdl:message name="linnLiveAssignImagesResponse">
553
+ <wsdl:part name="parameters" element="typens:linnLiveAssignImagesResponseParam" />
554
+ </wsdl:message>
555
+
556
+ <wsdl:message name="linnLiveDeleteAssignedRequest">
557
+ <wsdl:part name="parameters" element="typens:linnLiveDeleteAssignedRequestParam" />
558
+ </wsdl:message>
559
+ <wsdl:message name="linnLiveDeleteAssignedResponse">
560
+ <wsdl:part name="parameters" element="typens:linnLiveDeleteAssignedResponseParam" />
561
+ </wsdl:message>
562
+
563
+ <!-- Stub parameters for catalogProductAttributeRemove -->
564
+ <wsdl:message name="catalogProductAttributeRemoveRequest">
565
+ <wsdl:part name="parameters" element="typens:linnLiveAttributeRemoveRequestParam" />
566
+ </wsdl:message>
567
+ <wsdl:message name="catalogProductAttributeRemoveResponse">
568
+ <wsdl:part name="parameters" element="typens:linnLiveAttributeRemoveResponseParam" />
569
+ </wsdl:message>
570
+ <!-- Stub parameters for catalogProductAttributeRemove end -->
571
+
572
+ <wsdl:portType name="{{var wsdl.handler}}PortType">
573
+ <!-- Attribute options enchancement -->
574
+ <wsdl:operation name="linnLiveProductAttributeOptions">
575
+ <wsdl:documentation>Retrieve attribute options by ID</wsdl:documentation>
576
+ <wsdl:input message="typens:linnLiveProductAttributeOptionsRequest" />
577
+ <wsdl:output message="typens:linnLiveProductAttributeOptionsResponse" />
578
+ </wsdl:operation>
579
+ <!-- Attribute options enchancement end-->
580
+ <wsdl:operation name="linnLiveConfigurableProduct">
581
+ <wsdl:documentation>Create configurable product from products list</wsdl:documentation>
582
+ <wsdl:input message="typens:linnLiveConfigurableProductRequest" />
583
+ <wsdl:output message="typens:linnLiveConfigurableProductResponse" />
584
+ </wsdl:operation>
585
+ <wsdl:operation name="linnLiveUpdateConfigurableProduct">
586
+ <wsdl:documentation>Update configurable product</wsdl:documentation>
587
+ <wsdl:input message="typens:linnLiveUpdateConfigurableProductRequest" />
588
+ <wsdl:output message="typens:linnLiveUpdateConfigurableProductResponse" />
589
+ </wsdl:operation>
590
+ <wsdl:operation name="linnLiveCreateProduct">
591
+ <wsdl:documentation>Create new product and return product id</wsdl:documentation>
592
+ <wsdl:input message="typens:linnLiveCreateProductRequest" />
593
+ <wsdl:output message="typens:linnLiveCreateProductResponse" />
594
+ </wsdl:operation>
595
+ <wsdl:operation name="linnLiveUpdateProduct">
596
+ <wsdl:documentation>Update product</wsdl:documentation>
597
+ <wsdl:input message="typens:linnLiveUpdateProductRequest" />
598
+ <wsdl:output message="typens:linnLiveUpdateProductResponse" />
599
+ </wsdl:operation>
600
+ <wsdl:operation name="linnLiveStoresList">
601
+ <wsdl:documentation>Retreive installed stores list</wsdl:documentation>
602
+ <wsdl:input message="typens:linnLiveStoresListRequest" />
603
+ <wsdl:output message="typens:linnLiveStoresListResponse" />
604
+ </wsdl:operation>
605
+ <wsdl:operation name="linnLiveGetStoreCode">
606
+ <wsdl:documentation>Get current store code</wsdl:documentation>
607
+ <wsdl:input message="typens:linnLiveGetStoreCodeRequest" />
608
+ <wsdl:output message="typens:linnLiveGetStoreCodeResponse" />
609
+ </wsdl:operation>
610
+ <wsdl:operation name="linnLiveProductList">
611
+ <wsdl:documentation>Retrieve products list by filters</wsdl:documentation>
612
+ <wsdl:input message="typens:linnLiveProductListRequest"></wsdl:input>
613
+ <wsdl:output message="typens:linnLiveProductListResponse"></wsdl:output>
614
+ </wsdl:operation>
615
+
616
+ <wsdl:operation name="catalogProductAttributeRemove">
617
+ <wsdl:documentation>Stub operation for catalogProductAttributeRemove</wsdl:documentation>
618
+ <wsdl:input message="typens:catalogProductAttributeRemoveRequest" />
619
+ <wsdl:output message="typens:catalogProductAttributeRemoveResponse" />
620
+ </wsdl:operation>
621
+
622
+ <wsdl:operation name="linnLiveInfo">
623
+ <wsdl:documentation>Get information about current magento settings and installation</wsdl:documentation>
624
+ <wsdl:input message="typens:linnLiveInfoRequest" />
625
+ <wsdl:output message="typens:linnLiveInfoResponse" />
626
+ </wsdl:operation>
627
+ <wsdl:operation name="linnLiveAssignImages">
628
+ <wsdl:documentation>Assigns configurable product images to childrens products</wsdl:documentation>
629
+ <wsdl:input message="typens:linnLiveAssignImagesRequest" />
630
+ <wsdl:output message="typens:linnLiveAssignImagesResponse" />
631
+ </wsdl:operation>linnLiveDeleteAssigned
632
+ <wsdl:operation name="linnLiveDeleteAssigned">
633
+ <wsdl:documentation>Remove assigned item from inventory</wsdl:documentation>
634
+ <wsdl:input message="typens:linnLiveDeleteAssignedRequest" />
635
+ <wsdl:output message="typens:linnLiveDeleteAssignedResponse" />
636
+ </wsdl:operation>
637
+ </wsdl:portType>
638
+
639
+ <wsdl:binding name="{{var wsdl.handler}}Binding" type="typens:{{var wsdl.handler}}PortType">
640
+ <soap:binding style="document" transport="http://schemas.xmlsoap.org/soap/http" />
641
+ <!-- Attribute options enchancement -->
642
+ <wsdl:operation name="linnLiveProductAttributeOptions">
643
+ <soap:operation soapAction="" />
644
+ <wsdl:input>
645
+ <soap:body use="literal" />
646
+ </wsdl:input>
647
+ <wsdl:output>
648
+ <soap:body use="literal" />
649
+ </wsdl:output>
650
+ </wsdl:operation>
651
+ <!-- Attribute options enchancement end-->
652
+ <wsdl:operation name="linnLiveConfigurableProduct">
653
+ <soap:operation soapAction="" />
654
+ <wsdl:input>
655
+ <soap:body use="literal" />
656
+ </wsdl:input>
657
+ <wsdl:output>
658
+ <soap:body use="literal" />
659
+ </wsdl:output>
660
+ </wsdl:operation>
661
+ <wsdl:operation name="linnLiveUpdateConfigurableProduct">
662
+ <soap:operation soapAction="" />
663
+ <wsdl:input>
664
+ <soap:body use="literal" />
665
+ </wsdl:input>
666
+ <wsdl:output>
667
+ <soap:body use="literal" />
668
+ </wsdl:output>
669
+ </wsdl:operation>
670
+ <wsdl:operation name="linnLiveCreateProduct">
671
+ <soap:operation soapAction="" />
672
+ <wsdl:input>
673
+ <soap:body use="literal" />
674
+ </wsdl:input>
675
+ <wsdl:output>
676
+ <soap:body use="literal" />
677
+ </wsdl:output>
678
+ </wsdl:operation>
679
+ <wsdl:operation name="linnLiveUpdateProduct">
680
+ <soap:operation soapAction="" />
681
+ <wsdl:input>
682
+ <soap:body use="literal" />
683
+ </wsdl:input>
684
+ <wsdl:output>
685
+ <soap:body use="literal" />
686
+ </wsdl:output>
687
+ </wsdl:operation>
688
+ <wsdl:operation name="linnLiveStoresList">
689
+ <soap:operation soapAction="" />
690
+ <wsdl:input>
691
+ <soap:body use="literal" />
692
+ </wsdl:input>
693
+ <wsdl:output>
694
+ <soap:body use="literal" />
695
+ </wsdl:output>
696
+ </wsdl:operation>
697
+ <wsdl:operation name="catalogProductAttributeRemove">
698
+ <soap:operation soapAction="" />
699
+ <wsdl:input>
700
+ <soap:body use="literal" />
701
+ </wsdl:input>
702
+ <wsdl:output>
703
+ <soap:body use="literal" />
704
+ </wsdl:output>
705
+ </wsdl:operation>
706
+ <wsdl:operation name="linnLiveGetStoreCode">
707
+ <soap:operation soapAction="" />
708
+ <wsdl:input>
709
+ <soap:body use="literal" />
710
+ </wsdl:input>
711
+ <wsdl:output>
712
+ <soap:body use="literal" />
713
+ </wsdl:output>
714
+ </wsdl:operation>
715
+ <wsdl:operation name="linnLiveProductList">
716
+ <soap:operation soapAction="" />
717
+ <wsdl:input>
718
+ <soap:body use="literal" />
719
+ </wsdl:input>
720
+ <wsdl:output>
721
+ <soap:body use="literal" />
722
+ </wsdl:output>
723
+ </wsdl:operation>
724
+ <wsdl:operation name="linnLiveInfo">
725
+ <soap:operation soapAction="" />
726
+ <wsdl:input>
727
+ <soap:body use="literal" />
728
+ </wsdl:input>
729
+ <wsdl:output>
730
+ <soap:body use="literal" />
731
+ </wsdl:output>
732
+ </wsdl:operation>
733
+ <wsdl:operation name="linnLiveAssignImages">
734
+ <soap:operation soapAction="" />
735
+ <wsdl:input>
736
+ <soap:body use="literal" />
737
+ </wsdl:input>
738
+ <wsdl:output>
739
+ <soap:body use="literal" />
740
+ </wsdl:output>
741
+ </wsdl:operation>
742
+ <wsdl:operation name="linnLiveDeleteAssigned">
743
+ <soap:operation soapAction="" />
744
+ <wsdl:input>
745
+ <soap:body use="literal" />
746
+ </wsdl:input>
747
+ <wsdl:output>
748
+ <soap:body use="literal" />
749
+ </wsdl:output>
750
+ </wsdl:operation>
751
+ </wsdl:binding>
752
+
753
+ <wsdl:service name="{{var wsdl.name}}Service">
754
+ <wsdl:port name="{{var wsdl.handler}}Port" binding="typens:{{var wsdl.handler}}Binding">
755
+ <soap:address location="{{var wsdl.url}}" />
756
+ </wsdl:port>
757
+ </wsdl:service>
758
+
759
+ </wsdl:definitions>
app/etc/modules/LinnSystems_LinnLiveConnect.xml ADDED
@@ -0,0 +1,9 @@
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <config>
3
+ <modules>
4
+ <LinnSystems_LinnLiveConnect>
5
+ <active>true</active>
6
+ <codePool>local</codePool>
7
+ </LinnSystems_LinnLiveConnect>
8
+ </modules>
9
+ </config>
package.xml ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>LinnLiveConnect</name>
4
+ <version>1.1.37</version>
5
+ <stability>stable</stability>
6
+ <license>GPL v2</license>
7
+ <channel>community</channel>
8
+ <extends/>
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>Bug fixes:&#xD;
13
+ * Version fix.&#xD;
14
+ </notes>
15
+ <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></authors>
16
+ <date>2014-03-17</date>
17
+ <time>08:38:36</time>
18
+ <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="e428df7fd289d247d239a8ce0360c8c2"/></dir></dir><dir name="etc"><file name="api.xml" hash="2d53cb9b318de468f6d2e3d388bb8732"/><file name="config.xml" hash="2d1d6338d93e36b730efde622893b4e6"/><file name="wsdl.xml" hash="fc21f2963c1253f5f40e5e8414312174"/><file name="wsi.xml" hash="ef000d5115f5988664f58df8b9139e5e"/></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="LinnSystems_LinnLiveConnect.xml" hash="19c48712cd0516815d6784592ada0881"/></dir></target></contents>
19
+ <compatible/>
20
+ <dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies>
21
+ </package>