Simtech_Searchanise - Version 3.0.0

Version Notes

[+] Category search support added.

[*] Switch to API v. 1.3.

[*] Datafeeds are now submitted in JSON instead of XML.

[*] Faster indexation: Only active products are submitted on initial indexation.

[*] Faster indexation: Child products are not submitted separately from their parents.

[!] Usergroup-based prices could be submitted incorrectly. Fixed.

[!] Minor improvements and fixes in the advanced search.

Download this release

Release Info

Developer Simbirsk Technologies, Ltd.
Extension Simtech_Searchanise
Version 3.0.0
Comparing to
See all releases


Code changes from version 2.0.2 to 3.0.0

app/code/community/Simtech/Searchanise/Helper/ApiCategories.php ADDED
@@ -0,0 +1,219 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+ /***************************************************************************
3
+ * *
4
+ * (c) 2004 Vladimir V. Kalynyak, Alexey V. Vinokurov, Ilya M. Shalnev *
5
+ * *
6
+ * This is commercial software, only users who have purchased a valid *
7
+ * license and accept to the terms of the License Agreement can install *
8
+ * and use this program. *
9
+ * *
10
+ ****************************************************************************
11
+ * PLEASE READ THE FULL TEXT OF THE SOFTWARE LICENSE AGREEMENT IN THE *
12
+ * "copyright.txt" FILE PROVIDED WITH THIS DISTRIBUTION PACKAGE. *
13
+ ****************************************************************************/
14
+
15
+ class Simtech_Searchanise_Helper_ApiCategories extends Mage_Core_Helper_Data
16
+ {
17
+ public static function generateCategoryFeed($category, $store = null, $checkData = true)
18
+ {
19
+ $item = array();
20
+
21
+ if ($checkData) {
22
+ if (!$category ||
23
+ !$category->getId() ||
24
+ !$category->getName() ||
25
+ !$category->getIsActive()
26
+ ) {
27
+ return $item;
28
+ }
29
+ }
30
+ // Need for generate correct url.
31
+ if ($store) {
32
+ Mage::app()->setCurrentStore($store->getId());
33
+ } else {
34
+ Mage::app()->setCurrentStore(0);
35
+ }
36
+
37
+ $item['id'] = $category->getId();
38
+
39
+ $item['parent_id'] = $category->getId();
40
+ $parentCategory = $category->getParentCategory();
41
+ $item['parent_id'] = $parentCategory ? $parentCategory->getId() : 0;
42
+ $item['title'] = $category->getName();
43
+ $item['link'] = $category->getUrl();
44
+
45
+ // Fixme in the future
46
+ // if need to add ico for image.
47
+ // Show images without white field
48
+ // Example: image 360 x 535 => 47 х 70
49
+ // $flagKeepFrame = false;
50
+ // $image = Mage::helper('searchanise/ApiProducts')->getProductImageLink($category, $flagKeepFrame);
51
+ // if ($image) {
52
+ // $imageLink = '' . $image;
53
+
54
+ // if ($imageLink != '') {
55
+ // $item['image_link'] = '' . $imageLink;
56
+ // }
57
+ // }
58
+ // end fixme
59
+ $item['image_link'] = $category->getImageUrl();
60
+ $item['summary'] = $category->getDescription();
61
+
62
+ return $item;
63
+ }
64
+
65
+ public static function getCategories($categoryIds = Simtech_Searchanise_Model_Queue::NOT_DATA, $store = null)
66
+ {
67
+ static $arrCategories = array();
68
+
69
+ $keyCategories = '';
70
+ if ($categoryIds) {
71
+ if (is_array($categoryIds)) {
72
+ $keyCategories .= implode('_', $categoryIds);
73
+ } else {
74
+ $keyCategories .= $categoryIds;
75
+ }
76
+ }
77
+ $storeId = $store ? $store->getId() : 0;
78
+ $keyCategories .= ':' . $storeId;
79
+
80
+ if (isset($arrCategories[$keyCategories])) {
81
+ // Nothing
82
+ } else {
83
+ $collection = Mage::getModel('catalog/category')->getCollection();
84
+
85
+ /* @var $collection Mage_Catalog_Model_Resource_Eav_Mysql4_Category_Collection */
86
+ $collection
87
+ ->addAttributeToSelect('*')
88
+ ->setStoreId($storeId);
89
+
90
+ if ($categoryIds !== Simtech_Searchanise_Model_Queue::NOT_DATA) {
91
+ // Already exist automatic definition 'one value' or 'array'.
92
+ $collection->addIdFilter($categoryIds);
93
+ }
94
+
95
+ $collection->load();
96
+
97
+ $arrCategories[$keyCategories] = $collection;
98
+ }
99
+
100
+ return $arrCategories[$keyCategories];
101
+ }
102
+
103
+ public static function generateCategoriesFeed($categoryIds = Simtech_Searchanise_Model_Queue::NOT_DATA, $store = null, $checkData = true)
104
+ {
105
+ $items = array();
106
+
107
+ $categories = self::getCategories($categoryIds, $store);
108
+
109
+ if ($categories) {
110
+ foreach ($categories as $category) {
111
+ if ($item = self::generateCategoryFeed($category, $store, $checkData)) {
112
+ $items[] = $item;
113
+ }
114
+ }
115
+ }
116
+
117
+ return $items;
118
+ }
119
+
120
+ public static function getMinMaxCategoryId($store = null)
121
+ {
122
+ $startId = 0;
123
+ $endId = 0;
124
+
125
+ $categoryStartCollection = Mage::getModel('catalog/category')
126
+ ->getCollection()
127
+ ->addAttributeToSort('entity_id', Varien_Data_Collection::SORT_ORDER_ASC)
128
+ ->setPageSize(1);
129
+ if ($store) {
130
+ $categoryStartCollection = $categoryStartCollection->setStoreId($store->getId());;
131
+ }
132
+ $categoryStartCollection = $categoryStartCollection->load();
133
+
134
+ $categoryEndCollection = Mage::getModel('catalog/category')
135
+ ->getCollection()
136
+ ->addAttributeToSort('entity_id', Varien_Data_Collection::SORT_ORDER_DESC)
137
+ ->setPageSize(1);
138
+ if ($store) {
139
+ $categoryEndCollection = $categoryEndCollection->setStoreId($store->getId());;
140
+ }
141
+
142
+ $categoryEndCollection = $categoryEndCollection->load();
143
+
144
+ if ($categoryStartCollection) {
145
+ $categoryArr = $categoryStartCollection->toArray(array('entity_id'));
146
+ if (!empty($categoryArr)) {
147
+ $firstItem = reset($categoryArr);
148
+ $startId = $firstItem['entity_id'];
149
+ }
150
+ }
151
+
152
+ if ($categoryEndCollection) {
153
+ $categoryArr = $categoryEndCollection->toArray(array('entity_id'));
154
+ if (!empty($categoryArr)) {
155
+ $firstItem = reset($categoryArr);
156
+ $endId = $firstItem['entity_id'];
157
+ }
158
+ }
159
+
160
+ return array($startId, $endId);
161
+ }
162
+
163
+ public static function getCategoryIdsFormRange($start, $end, $step, $store = null)
164
+ {
165
+ $arrCategories = array();
166
+
167
+ $categories = Mage::getModel('catalog/category')
168
+ ->getCollection()
169
+ ->addFieldToFilter('entity_id', array("from" => $start, "to" => $end))
170
+ ->setPageSize($step);
171
+
172
+ if ($store) {
173
+ $categories = $categories->setStoreId($store->getId());;
174
+ }
175
+
176
+ $categories = $categories->load();
177
+ if ($categories) {
178
+ // Not used because 'arrCategories' comprising 'stock_item' field and is 'array(array())'
179
+ // $arrCategories = $categories->toArray(array('entity_id'));
180
+ foreach ($categories as $category) {
181
+ $arrCategories[] = $category->getId();
182
+ }
183
+ }
184
+ // It is necessary for save memory.
185
+ unset($categories);
186
+
187
+ return $arrCategories;
188
+ }
189
+
190
+ /**
191
+ *
192
+ *
193
+ * @param array $arr_cat
194
+ * @param Mage_Catalog_Model_Category $category
195
+ * @return array
196
+ */
197
+ public static function getAllChildrenCategories(&$arr_cat, $category, $fl_include_cur_cat = true)
198
+ {
199
+ if (empty($arr_cat)) {
200
+ $arr_cat = array();
201
+ }
202
+
203
+ if (!empty($category)) {
204
+ if ($fl_include_cur_cat == true) {
205
+ $arr_cat[] = $category->getId();
206
+ }
207
+
208
+ $children_cat = $category->getChildrenCategories();
209
+
210
+ if (!empty($children_cat)) {
211
+ foreach ($children_cat as $cat) {
212
+ self::getAllChildrenCategories($arr_cat, $cat, $fl_include_cur_cat);
213
+ }
214
+ }
215
+ }
216
+
217
+ return $arr_cat;
218
+ }
219
+ }
app/code/community/Simtech/Searchanise/Helper/{ApiXML.php → ApiProducts.php} RENAMED
@@ -12,14 +12,14 @@
12
  * "copyright.txt" FILE PROVIDED WITH THIS DISTRIBUTION PACKAGE. *
13
  ****************************************************************************/
14
 
15
- class Simtech_Searchanise_Helper_ApiXML extends Mage_Core_Helper_Data
16
  {
17
- const XML_END_LINE = "\n";
18
-
19
- const WEIGHT_SHORT_DESCRIPTION = 0; // not need because use in summary
20
- const WEIGHT_DESCRIPTION = 40;
21
 
22
  const WEIGHT_TAGS = 60;
 
23
 
24
  // <if_isSearchable>
25
  const WEIGHT_META_TITLE = 80;
@@ -94,7 +94,7 @@ class Simtech_Searchanise_Helper_ApiXML extends Mage_Core_Helper_Data
94
  }
95
 
96
  /**
97
- * generateProductImage
98
  *
99
  * @param Mage_Catalog_Model_Product $product
100
  * @param bool $flagKeepFrame
@@ -102,15 +102,15 @@ class Simtech_Searchanise_Helper_ApiXML extends Mage_Core_Helper_Data
102
  * @param int $height
103
  * @return Mage_Catalog_Model_Product_Image $image
104
  */
105
- private static function generateProductImage($product, $imageType = 'small_image', $flagKeepFrame = true, $width = 70, $height = 70)
106
  {
107
- $image = '';
108
- $productImage = $product->getData($imageType);
109
 
110
- if (!empty($productImage) && $productImage != 'no_selection') {
111
  try {
112
  $image = Mage::helper('catalog/image')
113
- ->init($product, $imageType)
114
  ->constrainOnly(true) // Guarantee, that image picture will not be bigger, than it was.
115
  ->keepAspectRatio(true) // Guarantee, that image picture width/height will not be distorted.
116
  ->keepFrame($flagKeepFrame); // Guarantee, that image will have dimensions, set in $width/$height
@@ -120,7 +120,7 @@ class Simtech_Searchanise_Helper_ApiXML extends Mage_Core_Helper_Data
120
  }
121
  } catch (Exception $e) {
122
  // image not exists
123
- $image = '';
124
  }
125
  }
126
 
@@ -136,19 +136,18 @@ class Simtech_Searchanise_Helper_ApiXML extends Mage_Core_Helper_Data
136
  * @param int $height
137
  * @return Mage_Catalog_Model_Product_Image $image
138
  */
139
- private static function getProductImageLink($product, $flagKeepFrame = true, $width = 70, $height = 70)
140
  {
141
- $image = '';
142
 
143
  if ($product) {
 
 
144
  if (empty($image)) {
145
- $image = self::generateProductImage($product, 'small_image', $flagKeepFrame, $width, $height);
146
- }
147
- if (empty($image)) {
148
- $image = self::generateProductImage($product, 'image', $flagKeepFrame, $width, $height);
149
  }
150
  if (empty($image)) {
151
- $image = self::generateProductImage($product, 'thumbnail', $flagKeepFrame, $width, $height);
152
  }
153
  }
154
 
@@ -231,7 +230,7 @@ class Simtech_Searchanise_Helper_ApiXML extends Mage_Core_Helper_Data
231
  * @param float $groupPrice
232
  * @return float
233
  */
234
- private static function getProductMinimalPrice($product, $store, $childrenProducts = null, $customerGroupId = null, $groupPrice = null)
235
  {
236
  $minimalPrice = false;
237
 
@@ -260,7 +259,7 @@ class Simtech_Searchanise_Helper_ApiXML extends Mage_Core_Helper_Data
260
 
261
  foreach ($childrenProducts as $childrenProductsKey => $childrenProduct) {
262
  if ($childrenProduct) {
263
- $minimalPriceChildren = self::getProductMinimalPrice($childrenProduct, $store, null, $customerGroupId);
264
 
265
  if (($minimalPriceChildren < $minimalPrice) ||
266
  ($minimalPrice == '')) {
@@ -304,7 +303,7 @@ class Simtech_Searchanise_Helper_ApiXML extends Mage_Core_Helper_Data
304
 
305
  if ($isCorrectProduct) {
306
  try {
307
- // $minimalPrice = $product->getFinalPrice();
308
  } catch (Exception $e) {
309
  $minimalPrice = false;
310
  Mage::helper('searchanise/ApiSe')->log($e->getMessage(), "Error: Script couldn't get final price for product ID = " . $product->getId());
@@ -321,39 +320,42 @@ class Simtech_Searchanise_Helper_ApiXML extends Mage_Core_Helper_Data
321
 
322
  return $minimalPrice;
323
  }
324
-
325
- private static function _generateProductPricesXML($product, $childrenProducts = null, $store = null)
326
  {
327
- $result = '';
328
-
329
  static $customerGroups;
330
 
331
  if (!isset($customerGroups)) {
332
  $customerGroups = Mage::getModel('customer/group')->getCollection()->load();
333
  }
334
 
335
- if ($customerGroups) {
 
 
 
 
 
 
336
  foreach ($customerGroups as $keyCustomerGroup => $customerGroup) {
337
  // It is needed because the 'setCustomerGroupId' function works only once.
338
  $productCurrentGroup = clone $product;
339
  $customerGroupId = $customerGroup->getId();
340
 
341
- $price = self::getProductMinimalPrice($productCurrentGroup, $store, $childrenProducts, $customerGroupId);
342
  if ($price != '') {
343
  $price = round($price, Mage::helper('searchanise/ApiSe')->getFloatPrecision());
344
  }
345
 
346
  if ($customerGroupId == Mage_Customer_Model_Group::NOT_LOGGED_IN_ID) {
347
- $result .= '<cs:price>' . $price . '</cs:price>'. self::XML_END_LINE;
348
  $defaultPrice = $price; // default price get for not logged user
349
  }
350
  $label_ = Mage::helper('searchanise/ApiSe')->getLabelForPricesUsergroup() . $customerGroup->getId();
351
- $result .= '<cs:attribute name="' . $label_ . '" type="float">' . $price . '</cs:attribute>' . self::XML_END_LINE;
352
  unset($productCurrentGroup);
353
  }
354
  }
355
 
356
- return $result;
357
  }
358
 
359
  /**
@@ -389,129 +391,154 @@ class Simtech_Searchanise_Helper_ApiXML extends Mage_Core_Helper_Data
389
  return $childrenProducts;
390
  }
391
 
392
- private static function getIdAttributeValuesXML($value)
393
  {
394
- $strIdValues = '';
395
 
396
  $arrValues = explode(',', $value);
397
  if (!empty($arrValues)) {
398
  foreach ($arrValues as $v) {
399
  if ($v != '') {
400
  // Example values: '0', '1', 'AF'.
401
- $strIdValues .= '<value><![CDATA[' . $v . ']]></value>';
402
  }
403
  }
404
  }
405
 
406
- return $strIdValues;
407
  }
408
 
409
- private static function getIdAttributesValuesXML($values)
410
  {
411
- $strIdValues = '';
412
-
413
- foreach ($values as $v) {
414
- $strIdValues .= self::getIdAttributeValuesXML($v);
415
  }
416
 
417
- return $strIdValues;
418
- }
 
 
419
 
420
- private static function addArrTextAttributeValues($product, $attributeCode, $inputType, &$arrTextValues)
421
- {
422
- $textValues = $product->getResource()->getAttribute($attributeCode)->getFrontend()->getValue($product);
423
-
424
- if ($textValues != '') {
425
- if ($inputType == 'multiselect') {
426
- $arrValues = explode(',', $textValues);
427
- if (!empty($arrValues)) {
428
- foreach ($arrValues as $v) {
429
- if ($v != '') {
430
- $trimValue = trim($v);
431
- if ($trimValue != '' && !in_array($trimValue, $arrTextValues)) {
432
- $arrTextValues[] .= $trimValue;
433
- }
434
- }
435
- }
436
  }
437
- } else {
438
- $trimValue = trim($textValues);
439
- $arrTextValues[] .= $trimValue;
440
  }
 
 
441
  }
442
 
443
- return true;
444
  }
445
 
446
- private static function getTextAttributesValuesXML($products, $attributeCode, $inputType)
447
  {
448
- $strTextValues = '';
449
  $arrTextValues = array();
450
 
451
  foreach ($products as $p) {
452
- self::addArrTextAttributeValues($p, $attributeCode, $inputType, $arrTextValues);
 
 
 
 
 
 
 
453
  }
454
- if ($arrTextValues) {
455
- foreach ($arrTextValues as $textValue) {
456
- $strTextValues .= '<value><![CDATA[' . $textValue . ']]></value>';
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
457
  }
458
  }
459
 
460
- return $strTextValues;
461
  }
462
 
463
- private static function _generateProductAttributesXML($product, $childrenProducts = null, $unitedProducts = null, $store = null)
464
  {
465
- $result = '';
 
 
 
 
 
 
 
 
 
466
 
467
- static $attributes;
 
468
 
469
- if (!isset($attributes)) {
470
- $attributes = Mage::getResourceModel('catalog/product_attribute_collection');
471
- $attributes
472
- ->setItemObjectClass('catalog/resource_eav_attribute')
473
- // ->setOrder('position', 'ASC') // not need, because It will slow with "order"
474
- ->load();
 
 
 
 
 
 
 
 
 
 
 
475
  }
476
 
 
 
 
 
 
 
 
 
 
477
  if ($attributes) {
 
478
  $useFullFeed = Mage::helper('searchanise/ApiSe')->getUseFullFeed();
 
479
  foreach ($attributes as $attribute) {
480
  $attributeCode = $attribute->getAttributeCode();
481
  $value = $product->getData($attributeCode);
482
 
483
  // unitedValues - main value + childrens values
484
- $unitedValues = array();
485
- {
486
- if ($value == '') {
487
- // nothing
488
- } elseif (is_array($value) && empty($value)) {
489
- // nothing
490
- } else {
491
- $unitedValues[] = $value;
492
- }
493
- if ($childrenProducts) {
494
- foreach ($childrenProducts as $childrenProductsKey => $childrenProduct) {
495
- $childValue = $childrenProduct->getData($attributeCode);
496
- if ($childValue == '') {
497
- // Nothing.
498
- } elseif (is_array($childValue) && empty($childValue)) {
499
- // Nothing.
500
- } else {
501
- if (!in_array($childValue, $unitedValues)) {
502
- $unitedValues[] = $childValue;
503
- }
504
- }
505
- }
506
- }
507
- }
508
  $inputType = $attribute->getData('frontend_input');
509
  $isSearchable = $attribute->getIsSearchable();
510
  $isVisibleInAdvancedSearch = $attribute->getIsVisibleInAdvancedSearch();
511
  $usedForSortBy = $attribute->getUsedForSortBy();
512
  $attributeName = 'attribute_' . $attribute->getId();
513
- $attributeWeight = 0;
514
- $isRequireAttribute = $useFullFeed || $isSearchable || $isVisibleInAdvancedSearch || $usedForSortBy;
 
 
 
 
515
 
516
  if (empty($unitedValues)) {
517
  // nothing
@@ -521,28 +548,15 @@ class Simtech_Searchanise_Helper_ApiXML extends Mage_Core_Helper_Data
521
  // already defined in the '<cs:price>' field
522
 
523
  } elseif ($attributeCode == 'status' || $attributeCode == 'visibility') {
524
- $result .= '<cs:attribute name="' . $attributeCode . '" type="text" text_search="N">';
525
- $result .= $value;
526
- $result .= '</cs:attribute>' . self::XML_END_LINE;
527
 
528
  } elseif ($attributeCode == 'weight') {
529
- $strTextValues = self::getTextAttributesValuesXML($unitedProducts, $attributeCode, $inputType);
530
- if ($strTextValues != '') {
531
- $result .= '<cs:attribute name="' . $attributeCode . '" type="float" text_search="N">';
532
- // fixme in the future
533
- // need for fixed bug of Server
534
- $result .= ' ';
535
- // end fixme
536
- $result .= $strTextValues;
537
- $result .= '</cs:attribute>' . self::XML_END_LINE;
538
- }
539
 
540
  // <dates>
541
  } elseif ($attributeCode == 'created_at' || $attributeCode == 'updated_at') {
542
  $dateTimestamp = Mage::getModel('core/date')->timestamp(strtotime($value));
543
- $result .= '<cs:attribute name="' . $attributeCode .'" type="int" text_search="N">';
544
- $result .= $dateTimestamp;
545
- $result .= '</cs:attribute>' . self::XML_END_LINE;
546
  // </dates>
547
 
548
  } elseif ($attributeCode == 'has_options') {
@@ -559,133 +573,43 @@ class Simtech_Searchanise_Helper_ApiXML extends Mage_Core_Helper_Data
559
  // nothing
560
  // fixme in the future if need
561
 
 
 
 
 
 
 
562
  } elseif (
563
  $attributeCode == 'short_description' ||
564
- $attributeCode == 'description' ||
565
  $attributeCode == 'meta_title' ||
566
  $attributeCode == 'meta_description' ||
567
  $attributeCode == 'meta_keyword') {
568
 
569
- if ($isRequireAttribute) {
570
- if ($isSearchable) {
571
- if ($attributeCode == 'short_description') {
572
- $attributeWeight = self::WEIGHT_SHORT_DESCRIPTION;
573
- } elseif ($attributeCode == 'description') {
574
- $attributeWeight = self::WEIGHT_DESCRIPTION;
575
- } elseif ($attributeCode == 'meta_title') {
576
- $attributeWeight = self::WEIGHT_META_TITLE;
577
- } elseif ($attributeCode == 'meta_description') {
578
- $attributeWeight = self::WEIGHT_META_DESCRIPTION;
579
- } elseif ($attributeCode == 'meta_keyword') {
580
- $attributeWeight = self::WEIGHT_META_KEYWORDS;
581
- } else {
582
- // Nothing.
583
- }
584
- }
585
-
586
- $strTextValues = self::getTextAttributesValuesXML($unitedProducts, $attributeCode, $inputType);
587
- if ($strTextValues != '') {
588
- if ($attributeCode == 'description') {
589
- if ($value != '') {
590
- $result .= '<cs:attribute name="' . $attributeCode .'" type="text" text_search="Y" weight="' . $attributeWeight . '">';
591
- $result .= '<![CDATA[' . $value . ']]>';
592
- $result .= '</cs:attribute>' . self::XML_END_LINE;
593
- }
594
-
595
- $result .= '<cs:attribute name="se_grouped_' . $attributeCode .'" type="text" text_search="Y" weight="' . $attributeWeight . '">';
596
- } else {
597
- $result .= '<cs:attribute name="' . $attributeCode .'" type="text" text_search="Y" weight="' . $attributeWeight . '">';
598
- }
599
- // fixme in the future
600
- // need for fixed bug of Server
601
- $result .= ' ';
602
- // end fixme
603
- $result .= $strTextValues;
604
- $result .= '</cs:attribute>' . self::XML_END_LINE;
605
- }
606
- }
607
 
608
  } elseif ($inputType == 'price') {
609
  // Other attributes with type 'price'.
610
- $result .= '<cs:attribute name="' . $attributeName .'" type="float">';
611
- $result .= $value;
612
- $result .= '</cs:attribute>' . self::XML_END_LINE;
613
 
614
  } elseif ($inputType == 'select' || $inputType == 'multiselect') {
615
  // <id_values>
616
- if ($strIdValues = self::getIdAttributesValuesXML($unitedValues)) {
617
- $result .= '<cs:attribute name="' . $attributeName .'" type="text">';
618
- // fixme in the future
619
- // need for fixed bug of Server
620
- $result .= ' ';
621
- // end fixme
622
-
623
- $result .= $strIdValues;
624
- $result .= '</cs:attribute>' . self::XML_END_LINE;
625
- }
626
- // </id_values>
627
 
628
  // <text_values>
629
- if ($isRequireAttribute) {
630
- $strTextValues = self::getTextAttributesValuesXML($unitedProducts, $attributeCode, $inputType);
631
-
632
- if ($strTextValues != '') {
633
- if ($isSearchable) {
634
- $attributeWeight = self::WEIGHT_SELECT_ATTRIBUTES;
635
- }
636
-
637
- $result .= '<cs:attribute name="' . $attributeCode .'" type="text" text_search="Y" weight="' . $attributeWeight . '">';
638
- // fixme in the future
639
- // need for fixed bug of Server
640
- $result .= ' ';
641
- // end fixme
642
- $result .= $strTextValues;
643
- $result .= '</cs:attribute>' . self::XML_END_LINE;
644
- }
645
- }
646
- // </text_values>
647
 
648
  } elseif ($inputType == 'text' || $inputType == 'textarea') {
649
- if ($isRequireAttribute) {
650
- $strTextValues = self::getTextAttributesValuesXML($unitedProducts, $attributeCode, $inputType);
651
-
652
- if ($strTextValues != '') {
653
- if ($isSearchable) {
654
- if ($inputType == 'text') {
655
- $attributeWeight = self::WEIGHT_TEXT_ATTRIBUTES;
656
- } elseif ($inputType == 'textarea') {
657
- $attributeWeight = self::WEIGHT_TEXT_AREA_ATTRIBUTES;
658
- } else {
659
- // Nothing.
660
- }
661
- }
662
- $result .= '<cs:attribute name="' . $attributeName .'" type="text" text_search="Y" weight="' . $attributeWeight . '">';
663
- // fixme in the future
664
- // need for fixed bug of Server
665
- $result .= ' ';
666
- // end fixme
667
- $result .= $strTextValues;
668
- $result .= '</cs:attribute>' . self::XML_END_LINE;
669
- }
670
- }
671
  } elseif ($inputType == 'date') {
672
- if ($isRequireAttribute) {
673
- $dateTimestamp = Mage::getModel('core/date')->timestamp(strtotime($value));
674
- $result .= '<cs:attribute name="' . $attributeCode .'" type="int" text_search="N">';
675
- $result .= $dateTimestamp;
676
- $result .= '</cs:attribute>' . self::XML_END_LINE;
677
- }
678
  } elseif ($inputType == 'media_image') {
679
- if ($isRequireAttribute) {
680
- $image = self::generateProductImage($product, $attributeCode, true, 0, 0);
681
- if (!empty($image)) {
682
- $imageLink = '' . $image;
683
- if (!empty($imageLink)) {
684
- $result .= '<cs:attribute name="' . $attributeCode .'" type="text" text_search="N" weight="0"><![CDATA[';
685
- $result .= $imageLink;
686
- $result .= ']]></cs:attribute>' . self::XML_END_LINE;
687
- }
688
- }
689
  }
690
  } elseif ($inputType == 'gallery') {
691
  // Nothing.
@@ -695,18 +619,18 @@ class Simtech_Searchanise_Helper_ApiXML extends Mage_Core_Helper_Data
695
  }
696
  }
697
 
698
- return $result;
699
  }
700
 
701
- public static function generateProductXML($product, $store = null, $checkData = true)
702
  {
703
- $entry = '';
704
  if ($checkData) {
705
  if (!$product ||
706
  !$product->getId() ||
707
  !$product->getName()
708
  ) {
709
- return $entry;
710
  }
711
  }
712
 
@@ -718,36 +642,31 @@ class Simtech_Searchanise_Helper_ApiXML extends Mage_Core_Helper_Data
718
  }
719
  }
720
 
721
- $entry .= '<entry>' . self::XML_END_LINE;
722
- $entry .= '<id>' . $product->getId() . '</id>' . self::XML_END_LINE;
723
-
724
- $entry .= '<title><![CDATA[' . $product->getName() . ']]></title>' . self::XML_END_LINE;
725
 
726
  $summary = $product->getData('short_description');
727
 
728
  if ($summary == '') {
729
  $summary = $product->getData('description');
730
  }
731
- $entry .= '<summary><![CDATA[' . $summary. ']]></summary>' . self::XML_END_LINE;
732
 
733
  $productUrl = $product->getProductUrl(false);
734
- $productUrl = htmlspecialchars($productUrl);
735
- $entry .= '<link href="' . $productUrl . '" />' . self::XML_END_LINE;
736
- $entry .= '<cs:product_code><![CDATA[' . $product->getSku() . ']]></cs:product_code>' . self::XML_END_LINE;
737
 
738
- $entry .= self::_generateProductPricesXML($product, $childrenProducts, $store);
739
 
740
  // <quantity>
741
  {
742
  $quantity = self::getProductQty($product, $store, $unitedProducts);
743
 
744
- $entry .= '<cs:quantity>' . ceil($quantity) . '</cs:quantity>' . self::XML_END_LINE;
745
- $isInStock = $quantity > 0;
746
- if ($isInStock) {
747
- $entry .= '<cs:attribute name="is_in_stock" type="text" text_search="N">' . $isInStock . '</cs:attribute>' . self::XML_END_LINE;
748
- }
749
  $quantity = round($quantity, Mage::helper('searchanise/ApiSe')->getFloatPrecision());
750
- $entry .= '<cs:attribute name="quantity_decimals" type="float">' . $quantity . '</cs:attribute>' . self::XML_END_LINE;
751
  }
752
  // </quantity>
753
 
@@ -756,10 +675,14 @@ class Simtech_Searchanise_Helper_ApiXML extends Mage_Core_Helper_Data
756
  // Show images without white field
757
  // Example: image 360 x 535 => 47 х 70
758
  $flagKeepFrame = false;
759
- $imageLink = self::getProductImageLink($product, $flagKeepFrame);
 
 
 
760
 
761
- if ($imageLink != '') {
762
- $entry .= '<cs:image_link><![CDATA[' . $imageLink . ']]></cs:image_link>' . self::XML_END_LINE;
 
763
  }
764
  }
765
  // </image_link>
@@ -768,83 +691,59 @@ class Simtech_Searchanise_Helper_ApiXML extends Mage_Core_Helper_Data
768
  {
769
  // Fixme in the feature:
770
  // products could have different position in different categories, sort by "position" disabled.
771
- $position = $product->getData('position');
772
- if ($position) {
773
- $entry .= '<cs:attribute name="position" type="int">';
774
- $entry .= $product->getData('position');
775
-
776
- $entry .= '</cs:attribute>' . self::XML_END_LINE;
777
- }
778
  // end
779
  }
780
  // </attributes_position>
781
 
782
- $entry .= self::_generateProductAttributesXML($product, $childrenProducts, $unitedProducts, $store);
783
 
784
  // <categories>
785
  {
786
- $entry .= '<cs:attribute name="category_ids" type="text">';
787
- // fixme in the future
788
- // need for fixed bug of Server
789
- $entry .= ' ';
790
- $nameCategories = ' ';
791
- // end fixme
792
  $categoryIds = $product->getCategoryIds();
793
  if (!empty($categoryIds)) {
 
 
794
  foreach ($categoryIds as $catKey => $categoryId) {
795
- $entry .= '<value><![CDATA[' . $categoryId . ']]></value>';
 
796
  $category = Mage::getModel('catalog/category')->load($categoryId);
797
  if ($category) {
798
- $nameCategories .= '<value><![CDATA[' . $category->getName() . ']]></value>';
799
  }
800
  }
801
- }
802
- $entry .= '</cs:attribute>' . self::XML_END_LINE;
803
 
804
- if ($nameCategories != ' ') {
805
- $attributeWeight = 0;
806
- $entry .= '<cs:attribute name="categories" type="text" text_search="N" weight="' . $attributeWeight . '">';
807
- $entry .= $nameCategories;
808
- $entry .= '</cs:attribute>' . self::XML_END_LINE;
809
  }
810
  }
811
  // </categories>
812
 
813
  // <tags>
814
  {
815
- $strTagIds = '';
816
- $strTagNames = '';
817
 
818
  $tags = self::getTagCollection($product, $store);
819
 
820
  if ($tags && count($tags) > 0) {
821
  foreach ($tags as $tag) {
822
  if ($tag) {
823
- $strTagIds .= '<value><![CDATA[' . $tag->getId() . ']]></value>';
824
- $strTagNames .= '<value><![CDATA[' . $tag->getName() . ']]></value>';
825
  }
826
  }
827
  }
828
 
829
- if ($strTagIds != '') {
830
- $entry .= '<cs:attribute name="tag_ids" type="text" text_search="N">';
831
- // fixme in the future
832
- // need for fixed bug of Server
833
- $entry .= ' ';
834
- // end fixme
835
- $entry .= $strTagIds;
836
- $entry .= '</cs:attribute>' . self::XML_END_LINE;
837
-
838
- $entry .= '<cs:attribute name="tags" type="text" text_search="Y" weight="' . self::WEIGHT_TAGS .'">';
839
- $entry .= $strTagNames;
840
- $entry .= '</cs:attribute>' . self::XML_END_LINE;
841
  }
842
  }
843
  // </tags>
844
 
845
- $entry .= '</entry>' . self::XML_END_LINE;
846
-
847
- return $entry;
848
  }
849
 
850
  public static function getOptionCollection($filter, $store = null)
@@ -862,9 +761,9 @@ class Simtech_Searchanise_Helper_ApiXML extends Mage_Core_Helper_Data
862
  ->load();
863
  }
864
 
865
- public static function getPriceNavigationStep($store = null)
866
  {
867
- if (empty($store)) {
868
  $store = Mage::app()->getStore(0);
869
  }
870
 
@@ -877,7 +776,7 @@ class Simtech_Searchanise_Helper_ApiXML extends Mage_Core_Helper_Data
877
  return null;
878
  }
879
 
880
- public static function checkFacet($attribute)
881
  {
882
  $isFilterable = $attribute->getIsFilterable();
883
  $isFilterableInSearch = $attribute->getIsFilterableInSearch();
@@ -885,65 +784,59 @@ class Simtech_Searchanise_Helper_ApiXML extends Mage_Core_Helper_Data
885
  return $isFilterable || $isFilterableInSearch;
886
  }
887
 
888
- public static function generateFacetXMLFromFilter($filter, $store = null)
889
  {
890
- $entry = '';
891
 
892
- if (self::checkFacet($filter)) {
893
  $attributeType = '';
894
 
895
- $inputType = $filter->getData('frontend_input');
896
 
897
  // "Can be used only with catalog input type Dropdown, Multiple Select and Price".
898
  if (($inputType == 'select') || ($inputType == 'multiselect')) {
899
- $attributeType = '<cs:type>select</cs:type>' . self::XML_END_LINE;
900
 
901
  } elseif ($inputType == 'price') {
902
- $attributeType = '<cs:type>dynamic</cs:type>' . self::XML_END_LINE;
903
- $step = self::getPriceNavigationStep($store);
904
-
905
  if (!empty($step)) {
906
- $attributeType .= '<cs:min_range>' . $step . '</cs:min_range>' . self::XML_END_LINE;
907
  }
908
  } else {
909
- // attribute is not filtrable
910
- // nothing
911
  }
912
 
913
- if ($attributeType != '') {
914
- $entry = '<entry>' . self::XML_END_LINE;
915
- $entry .= '<title><![CDATA[' . $filter->getData('frontend_label') . ']]></title>' . self::XML_END_LINE;
916
- $entry .= '<cs:position>' . $filter->getPosition() . '</cs:position>' . self::XML_END_LINE;
917
 
918
- $attributeCode = $filter->getAttributeCode();
919
 
920
  if ($attributeCode == 'price') {
921
  $labelAttribute = 'price';
922
  } else {
923
- $labelAttribute = 'attribute_' . $filter->getId();
924
  }
925
 
926
- $entry .= '<cs:attribute>' . $labelAttribute . '</cs:attribute>' . self::XML_END_LINE;
927
- $entry .= $attributeType;
928
- $entry .= '</entry>' . self::XML_END_LINE;
929
  }
930
  }
931
 
932
- return $entry;
933
  }
934
 
935
- public static function generateFacetXMLFromCustom($title = '', $position = 0, $attribute = '', $type = '')
936
  {
937
- $entry = '<entry>' . self::XML_END_LINE;
938
-
939
- $entry .= '<title><![CDATA[' . $title .']]></title>' . self::XML_END_LINE;
940
- $entry .= '<cs:position>' . $position . '</cs:position>' . self::XML_END_LINE;
941
- $entry .= '<cs:attribute>' . $attribute . '</cs:attribute>' . self::XML_END_LINE;
942
- $entry .= '<cs:type>' . $type .'</cs:type>' . self::XML_END_LINE;
943
-
944
- $entry .= '</entry>' . self::XML_END_LINE;
945
 
946
- return $entry;
 
 
 
 
 
947
  }
948
 
949
  private static function validateProductIds($productIds, $store = null)
@@ -1030,20 +923,22 @@ class Simtech_Searchanise_Helper_ApiXML extends Mage_Core_Helper_Data
1030
  }
1031
 
1032
  static $arrProducts = array();
1033
- $keyProductIds = implode('_', $productIds) . ':' . ($store ? $store->getId() : '0') . ':' . $customerGroupId . ':' . (self::$isGetProductsByItems ? '1' : '0');
1034
-
1035
- if (isset($arrProducts[$keyProductIds])) {
1036
- // Nothing.
1037
- } else {
1038
- $products = null;
1039
 
1040
- // Need for generate correct url and get right data.
1041
- if ($store) {
1042
- Mage::app()->setCurrentStore($store->getId());
 
1043
  } else {
1044
- Mage::app()->setCurrentStore(0);
1045
  }
 
 
 
 
1046
 
 
 
 
1047
  $products = Mage::getModel('catalog/product')
1048
  ->getCollection()
1049
  ->addAttributeToSelect('*')
@@ -1063,134 +958,374 @@ class Simtech_Searchanise_Helper_ApiXML extends Mage_Core_Helper_Data
1063
  ->addStoreFilter($store);
1064
  }
1065
 
1066
- // if (!empty($productIds)) {
1067
  // Already exist automatic definition 'one value' or 'array'.
1068
  $products->addIdFilter($productIds);
1069
- // }
1070
 
1071
  $products->load();
1072
 
1073
- $arrProducts[$keyProductIds] = $products;
1074
- }
1075
-
1076
- $resultProducts = $arrProducts[$keyProductIds];
1077
-
1078
- if ($resultProducts && ($store || $customerGroupId != null)) {
1079
- foreach ($resultProducts as $key => &$product) {
1080
- if ($product) {
1081
- if ($store) {
1082
- $product->setWebsiteId($store->getWebsiteId());
1083
- }
1084
- if ($customerGroupId != null) {
1085
- $product->setCustomerGroupId($customerGroupId);
1086
  }
1087
  }
1088
  }
 
 
 
1089
  }
1090
 
1091
- return $resultProducts;
1092
  }
1093
 
1094
  // Main functions //
1095
- public static function generateProductsXML($productIds = null, $store = null, $checkData = true)
1096
  {
1097
- $ret = '';
1098
 
1099
  $products = self::getProducts($productIds, $store, null);
1100
 
1101
  if ($products) {
1102
  foreach ($products as $product) {
1103
- $ret .= self::generateProductXML($product, $store, $checkData);
 
 
1104
  }
1105
  }
1106
 
1107
- return $ret;
1108
  }
1109
-
1110
- public static function generateFacetXMLFilters($attributeIds = null, $store = null)
1111
  {
1112
- $ret = '';
1113
-
1114
- $filters = Mage::getResourceModel('catalog/product_attribute_collection')
1115
- ->setItemObjectClass('catalog/resource_eav_attribute');
 
 
 
 
 
 
 
 
1116
 
1117
- if ($store) {
1118
- $filters->addStoreLabel($store->getId());
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1119
  }
1120
 
1121
- if (!empty($attributeIds)) {
1122
- if (is_array($attributeIds)) {
1123
- $filters->addFieldToFilter('main_table.attribute_id', array('in' => $attributeIds));
1124
- } else {
1125
- $filters->addFieldToFilter('main_table.attribute_id', array('eq' => $attributeIds));
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1126
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1127
  }
1128
-
1129
- $filters->load();
1130
-
1131
- if (!empty($filters)) {
1132
- foreach ($filters as $filter) {
1133
- $ret .= self::generateFacetXMLFromFilter($filter, $store);
 
 
 
 
 
 
1134
  }
 
1135
  }
1136
-
1137
- return $ret;
1138
  }
1139
 
1140
- public static function generateFacetXMLCategories()
1141
  {
1142
- return self::generateFacetXMLFromCustom('Category', 0, 'category_ids', 'select');
1143
  }
1144
 
1145
- public static function generateFacetXMLPrices($store = null)
1146
  {
1147
- $entry = '';
1148
-
1149
- $filters = Mage::getResourceModel('catalog/product_attribute_collection')
1150
- ->setItemObjectClass('catalog/resource_eav_attribute')
1151
- ->addFieldToFilter('main_table.frontend_input', array('eq' => 'price'));
1152
 
1153
- if ($store) {
1154
- $filters->addStoreLabel($store->getId());
 
 
 
 
 
 
 
1155
  }
1156
 
1157
- $filters->load();
1158
-
1159
- if (!empty($filters)) {
1160
- foreach ($filters as $filter) {
1161
- $entry .= self::generateFacetXMLFromFilter($filter, $store);
1162
- }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1163
  }
 
 
1164
 
1165
- return $entry;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1166
  }
1167
-
1168
- public static function generateFacetXMLTags()
1169
  {
1170
- return self::generateFacetXMLFromCustom('Tag', 0, 'tag_ids', 'select');
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1171
  }
1172
 
1173
- public static function getXMLHeader($store = null)
1174
  {
1175
  $url = '';
1176
 
1177
- if (empty($store)) {
1178
  $url = Mage::app()->getStore()->getBaseUrl();
1179
  } else {
1180
  $url = $store->getUrl();
1181
  }
1182
-
1183
  $date = date('c');
1184
-
1185
- return '<?xml version="1.0" encoding="UTF-8"?>' .
1186
- '<feed xmlns="http://www.w3.org/2005/Atom" xmlns:cs="http://searchanise.com/ns/1.0">' .
1187
- '<title>Searchanise data feed</title>' .
1188
- "<updated>{$date}</updated>" .
1189
- "<id><![CDATA[{$url}]]></id>";
1190
- }
1191
-
1192
- public static function getXMLFooter()
1193
- {
1194
- return '</feed>';
1195
  }
1196
  }
12
  * "copyright.txt" FILE PROVIDED WITH THIS DISTRIBUTION PACKAGE. *
13
  ****************************************************************************/
14
 
15
+ class Simtech_Searchanise_Helper_ApiProducts extends Mage_Core_Helper_Data
16
  {
17
+ const WEIGHT_SHORT_DESCRIPTION = 0; // not need because use in summary
18
+ const WEIGHT_DESCRIPTION = 40;
19
+ const WEIGHT_DESCRIPTION_GROUPED = 30;
 
20
 
21
  const WEIGHT_TAGS = 60;
22
+ const WEIGHT_CATEGORIES = 60;
23
 
24
  // <if_isSearchable>
25
  const WEIGHT_META_TITLE = 80;
94
  }
95
 
96
  /**
97
+ * generateImage
98
  *
99
  * @param Mage_Catalog_Model_Product $product
100
  * @param bool $flagKeepFrame
102
  * @param int $height
103
  * @return Mage_Catalog_Model_Product_Image $image
104
  */
105
+ private static function generateImage($object, $imageType = 'small_image', $flagKeepFrame = true, $width = 70, $height = 70)
106
  {
107
+ $image = null;
108
+ $objectImage = $object->getData($imageType);
109
 
110
+ if (!empty($objectImage) && $objectImage != 'no_selection') {
111
  try {
112
  $image = Mage::helper('catalog/image')
113
+ ->init($object, $imageType)
114
  ->constrainOnly(true) // Guarantee, that image picture will not be bigger, than it was.
115
  ->keepAspectRatio(true) // Guarantee, that image picture width/height will not be distorted.
116
  ->keepFrame($flagKeepFrame); // Guarantee, that image will have dimensions, set in $width/$height
120
  }
121
  } catch (Exception $e) {
122
  // image not exists
123
+ $image = null;
124
  }
125
  }
126
 
136
  * @param int $height
137
  * @return Mage_Catalog_Model_Product_Image $image
138
  */
139
+ public static function getProductImageLink($product, $flagKeepFrame = true, $width = 70, $height = 70)
140
  {
141
+ $image = null;
142
 
143
  if ($product) {
144
+ $image = self::generateImage($product, 'small_image', $flagKeepFrame, $width, $height);
145
+
146
  if (empty($image)) {
147
+ $image = self::generateImage($product, 'image', $flagKeepFrame, $width, $height);
 
 
 
148
  }
149
  if (empty($image)) {
150
+ $image = self::generateImage($product, 'thumbnail', $flagKeepFrame, $width, $height);
151
  }
152
  }
153
 
230
  * @param float $groupPrice
231
  * @return float
232
  */
233
+ private static function _getProductMinimalPrice($product, $store, $childrenProducts = null, $customerGroupId = null, $groupPrice = null)
234
  {
235
  $minimalPrice = false;
236
 
259
 
260
  foreach ($childrenProducts as $childrenProductsKey => $childrenProduct) {
261
  if ($childrenProduct) {
262
+ $minimalPriceChildren = self::_getProductMinimalPrice($childrenProduct, $store, null, $customerGroupId);
263
 
264
  if (($minimalPriceChildren < $minimalPrice) ||
265
  ($minimalPrice == '')) {
303
 
304
  if ($isCorrectProduct) {
305
  try {
306
+ $minimalPrice = $product->getFinalPrice();
307
  } catch (Exception $e) {
308
  $minimalPrice = false;
309
  Mage::helper('searchanise/ApiSe')->log($e->getMessage(), "Error: Script couldn't get final price for product ID = " . $product->getId());
320
 
321
  return $minimalPrice;
322
  }
323
+ private static function _getCustomerGroups()
 
324
  {
 
 
325
  static $customerGroups;
326
 
327
  if (!isset($customerGroups)) {
328
  $customerGroups = Mage::getModel('customer/group')->getCollection()->load();
329
  }
330
 
331
+ return $customerGroups;
332
+ }
333
+
334
+
335
+ private static function _generateProductPrices(&$item, $product, $childrenProducts = null, $store = null)
336
+ {
337
+ if ($customerGroups = self::_getCustomerGroups()) {
338
  foreach ($customerGroups as $keyCustomerGroup => $customerGroup) {
339
  // It is needed because the 'setCustomerGroupId' function works only once.
340
  $productCurrentGroup = clone $product;
341
  $customerGroupId = $customerGroup->getId();
342
 
343
+ $price = self::_getProductMinimalPrice($productCurrentGroup, $store, $childrenProducts, $customerGroupId);
344
  if ($price != '') {
345
  $price = round($price, Mage::helper('searchanise/ApiSe')->getFloatPrecision());
346
  }
347
 
348
  if ($customerGroupId == Mage_Customer_Model_Group::NOT_LOGGED_IN_ID) {
349
+ $item['price'] = $price;
350
  $defaultPrice = $price; // default price get for not logged user
351
  }
352
  $label_ = Mage::helper('searchanise/ApiSe')->getLabelForPricesUsergroup() . $customerGroup->getId();
353
+ $item[$label_] = $price;
354
  unset($productCurrentGroup);
355
  }
356
  }
357
 
358
+ return true;
359
  }
360
 
361
  /**
391
  return $childrenProducts;
392
  }
393
 
394
+ private static function _getIdAttributeValues($value)
395
  {
396
+ $values = '';
397
 
398
  $arrValues = explode(',', $value);
399
  if (!empty($arrValues)) {
400
  foreach ($arrValues as $v) {
401
  if ($v != '') {
402
  // Example values: '0', '1', 'AF'.
403
+ $values[] = $v;
404
  }
405
  }
406
  }
407
 
408
+ return $values;
409
  }
410
 
411
+ private static function _getTextAttributeValues($product, $attributeCode, $inputType, $store = null)
412
  {
413
+ static $arrTextValues = array();
414
+ $key = $attributeCode;
415
+ if ($store) {
416
+ $key .= '__' . $store->getId();
417
  }
418
 
419
+ if (!isset($arrTextValues[$key])) {
420
+ $values = array();
421
+ // Dependency of store already exists
422
+ $textValues = $product->getResource()->getAttribute($attributeCode)->getFrontend()->getValue($product);
423
 
424
+ if ($textValues != '') {
425
+ if ($inputType == 'multiselect') {
426
+ $values = explode(',', $textValues);
427
+ } else {
428
+ $values[] = $textValues;
 
 
 
 
 
 
 
 
 
 
 
429
  }
 
 
 
430
  }
431
+
432
+ $arrTextValues[$key] = $values;
433
  }
434
 
435
+ return $arrTextValues[$key];
436
  }
437
 
438
+ private static function _getProductAttributeTextValues($products, $attributeCode, $inputType, $store = null)
439
  {
 
440
  $arrTextValues = array();
441
 
442
  foreach ($products as $p) {
443
+ if ($values = self::_getTextAttributeValues($p, $attributeCode, $inputType, $store)) {
444
+ foreach ($values as $key => $value) {
445
+ $trimValue = trim($value);
446
+ if ($trimValue != '' && !in_array($trimValue, $arrTextValues)) {
447
+ $arrTextValues[] = $value;
448
+ }
449
+ }
450
+ }
451
  }
452
+
453
+ return $arrTextValues;
454
+ }
455
+
456
+ private static function _getIdAttributesValues($products, $attributeCode)
457
+ {
458
+ $values = array();
459
+
460
+ foreach ($products as $productKey => $product) {
461
+ $value = $product->getData($attributeCode);
462
+ if ($value == '') {
463
+ // Nothing.
464
+ } elseif (is_array($value) && empty($value)) {
465
+ // Nothing.
466
+ } else {
467
+ if (!in_array($value, $values)) {
468
+ $values[] = $value;
469
+ }
470
  }
471
  }
472
 
473
+ return $values;
474
  }
475
 
476
+ public static function getProductAttributes($attributeIds = Simtech_Searchanise_Model_Queue::NOT_DATA, $store = null, $isPrice = false)
477
  {
478
+ if ($attributeIds === Simtech_Searchanise_Model_Queue::NOT_DATA) {
479
+ static $allAttributes;
480
+
481
+ if (!isset($allAttributes)) {
482
+ $allAttributes = Mage::getResourceModel('catalog/product_attribute_collection');
483
+ $allAttributes
484
+ ->setItemObjectClass('catalog/resource_eav_attribute')
485
+ // ->setOrder('position', 'ASC') // not need, because It will slow with "order"
486
+ ->load();
487
+ }
488
 
489
+ return $allAttributes;
490
+ }
491
 
492
+ $attributes = Mage::getResourceModel('catalog/product_attribute_collection')
493
+ ->setItemObjectClass('catalog/resource_eav_attribute');
494
+
495
+ // fixme in the future
496
+ // need delete
497
+ // if ($store) {
498
+ // $filters->addStoreLabel($store->getId());
499
+ // }
500
+ // end fixme
501
+
502
+ if (is_array($attributeIds)) {
503
+ $attributes->addFieldToFilter('main_table.attribute_id', array('in' => $attributeIds));
504
+ } else {
505
+ $attributes->addFieldToFilter('main_table.attribute_id', array('eq' => $attributeIds));
506
+ }
507
+ if ($isPrice) {
508
+ $attributes->addFieldToFilter('main_table.frontend_input', array('eq' => 'price'));
509
  }
510
 
511
+ $attributes->load();
512
+
513
+ return $attributes;
514
+ }
515
+
516
+ private static function _generateProductAttributes(&$item, $product, $childrenProducts = null, $unitedProducts = null, $store = null)
517
+ {
518
+ $attributes = self::getProductAttributes(Simtech_Searchanise_Model_Queue::NOT_DATA, $store);
519
+
520
  if ($attributes) {
521
+ $requiredAttributes = self::_getRequiredAttributes();
522
  $useFullFeed = Mage::helper('searchanise/ApiSe')->getUseFullFeed();
523
+
524
  foreach ($attributes as $attribute) {
525
  $attributeCode = $attribute->getAttributeCode();
526
  $value = $product->getData($attributeCode);
527
 
528
  // unitedValues - main value + childrens values
529
+ $unitedValues = self::_getIdAttributesValues($unitedProducts, $attributeCode);
530
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
531
  $inputType = $attribute->getData('frontend_input');
532
  $isSearchable = $attribute->getIsSearchable();
533
  $isVisibleInAdvancedSearch = $attribute->getIsVisibleInAdvancedSearch();
534
  $usedForSortBy = $attribute->getUsedForSortBy();
535
  $attributeName = 'attribute_' . $attribute->getId();
536
+
537
+ $isNecessaryAttribute = $useFullFeed || $isSearchable || $isVisibleInAdvancedSearch || $usedForSortBy || in_array($attributeCode, $requiredAttributes);
538
+
539
+ if (!$isNecessaryAttribute) {
540
+ continue;
541
+ }
542
 
543
  if (empty($unitedValues)) {
544
  // nothing
548
  // already defined in the '<cs:price>' field
549
 
550
  } elseif ($attributeCode == 'status' || $attributeCode == 'visibility') {
551
+ $item[$attributeCode] = $value;
 
 
552
 
553
  } elseif ($attributeCode == 'weight') {
554
+ $item[$attributeCode] = $unitedValues;
 
 
 
 
 
 
 
 
 
555
 
556
  // <dates>
557
  } elseif ($attributeCode == 'created_at' || $attributeCode == 'updated_at') {
558
  $dateTimestamp = Mage::getModel('core/date')->timestamp(strtotime($value));
559
+ $item[$attributeCode] = $dateTimestamp;
 
 
560
  // </dates>
561
 
562
  } elseif ($attributeCode == 'has_options') {
573
  // nothing
574
  // fixme in the future if need
575
 
576
+ } elseif ($attributeCode == 'description') {
577
+ if ($value != '') {
578
+ $item[$attributeCode] = $value;
579
+ }
580
+ $item['se_grouped_' . $attributeCode] = $unitedValues;
581
+
582
  } elseif (
583
  $attributeCode == 'short_description' ||
 
584
  $attributeCode == 'meta_title' ||
585
  $attributeCode == 'meta_description' ||
586
  $attributeCode == 'meta_keyword') {
587
 
588
+ $item[$attributeCode] = $unitedValues;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
589
 
590
  } elseif ($inputType == 'price') {
591
  // Other attributes with type 'price'.
592
+ $item[$attributeCode] = $unitedValues;
 
 
593
 
594
  } elseif ($inputType == 'select' || $inputType == 'multiselect') {
595
  // <id_values>
596
+ $item[$attributeName] = $unitedValues;
 
 
 
 
 
 
 
 
 
 
597
 
598
  // <text_values>
599
+ $unitedTextValues = self::_getProductAttributeTextValues($unitedProducts, $attributeCode, $inputType, $store);
600
+ $item[$attributeCode] = $unitedTextValues;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
601
 
602
  } elseif ($inputType == 'text' || $inputType == 'textarea') {
603
+ $item[$attributeCode] = $unitedValues;
604
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
605
  } elseif ($inputType == 'date') {
606
+ $dateTimestamp = Mage::getModel('core/date')->timestamp(strtotime($value));
607
+ $item[$attributeCode] = $dateTimestamp;
 
 
 
 
608
  } elseif ($inputType == 'media_image') {
609
+ $image = self::generateImage($product, $attributeCode, true, 0, 0);
610
+ if (!empty($image)) {
611
+ $imageLink = '' . $image;
612
+ $item[$attributeCode] = $imageLink;
 
 
 
 
 
 
613
  }
614
  } elseif ($inputType == 'gallery') {
615
  // Nothing.
619
  }
620
  }
621
 
622
+ return $item;
623
  }
624
 
625
+ public static function generateProductFeed($product, $store = null, $checkData = true)
626
  {
627
+ $item = array();
628
  if ($checkData) {
629
  if (!$product ||
630
  !$product->getId() ||
631
  !$product->getName()
632
  ) {
633
+ return $item;
634
  }
635
  }
636
 
642
  }
643
  }
644
 
645
+ $item['id'] = $product->getId();
646
+ $item['title'] = $product->getName();
 
 
647
 
648
  $summary = $product->getData('short_description');
649
 
650
  if ($summary == '') {
651
  $summary = $product->getData('description');
652
  }
653
+ $item['summary'] = $summary;
654
 
655
  $productUrl = $product->getProductUrl(false);
656
+ $item['link'] = $productUrl;
657
+ $item['product_code'] = $product->getSku();
 
658
 
659
+ self::_generateProductPrices($item, $product, $childrenProducts, $store);
660
 
661
  // <quantity>
662
  {
663
  $quantity = self::getProductQty($product, $store, $unitedProducts);
664
 
665
+ $item['quantity'] = ceil($quantity);
666
+
667
+ $item['is_in_stock'] = $quantity > 0;
 
 
668
  $quantity = round($quantity, Mage::helper('searchanise/ApiSe')->getFloatPrecision());
669
+ $item['quantity_decimals'] = $quantity;
670
  }
671
  // </quantity>
672
 
675
  // Show images without white field
676
  // Example: image 360 x 535 => 47 х 70
677
  $flagKeepFrame = false;
678
+ $image = self::getProductImageLink($product, $flagKeepFrame);
679
+
680
+ if ($image) {
681
+ $imageLink = '' . $image;
682
 
683
+ if ($imageLink != '') {
684
+ $item['image_link'] = '' . $imageLink;
685
+ }
686
  }
687
  }
688
  // </image_link>
691
  {
692
  // Fixme in the feature:
693
  // products could have different position in different categories, sort by "position" disabled.
694
+ $item['position'] = $product->getData('position');
 
 
 
 
 
 
695
  // end
696
  }
697
  // </attributes_position>
698
 
699
+ self::_generateProductAttributes($item, $product, $childrenProducts, $unitedProducts, $store);
700
 
701
  // <categories>
702
  {
703
+
 
 
 
 
 
704
  $categoryIds = $product->getCategoryIds();
705
  if (!empty($categoryIds)) {
706
+ $categoryNames = array();
707
+
708
  foreach ($categoryIds as $catKey => $categoryId) {
709
+ // fixme int the future
710
+ // check value for other language
711
  $category = Mage::getModel('catalog/category')->load($categoryId);
712
  if ($category) {
713
+ $categoryNames[] = $category->getName();
714
  }
715
  }
 
 
716
 
717
+ $item['category_ids'] = $categoryIds;
718
+ $item['categories'] = $categoryNames;
 
 
 
719
  }
720
  }
721
  // </categories>
722
 
723
  // <tags>
724
  {
725
+ $tagIds = array();
726
+ $tagNames = array();
727
 
728
  $tags = self::getTagCollection($product, $store);
729
 
730
  if ($tags && count($tags) > 0) {
731
  foreach ($tags as $tag) {
732
  if ($tag) {
733
+ $tagIds[] = $tag->getId();
734
+ $tagNames[] = $tag->getName();
735
  }
736
  }
737
  }
738
 
739
+ if (!empty($tagIds)) {
740
+ $item['tag_ids'] = $tagIds;
741
+ $item['tags'] = $tagNames;
 
 
 
 
 
 
 
 
 
742
  }
743
  }
744
  // </tags>
745
 
746
+ return $item;
 
 
747
  }
748
 
749
  public static function getOptionCollection($filter, $store = null)
761
  ->load();
762
  }
763
 
764
+ private static function _getPriceNavigationStep($store = null)
765
  {
766
+ if (!$store) {
767
  $store = Mage::app()->getStore(0);
768
  }
769
 
776
  return null;
777
  }
778
 
779
+ public static function isFacet($attribute)
780
  {
781
  $isFilterable = $attribute->getIsFilterable();
782
  $isFilterableInSearch = $attribute->getIsFilterableInSearch();
784
  return $isFilterable || $isFilterableInSearch;
785
  }
786
 
787
+ private static function _generateFacetFromFilter($attribute, $store = null)
788
  {
789
+ $item = array();
790
 
791
+ if (self::isFacet($attribute)) {
792
  $attributeType = '';
793
 
794
+ $inputType = $attribute->getData('frontend_input');
795
 
796
  // "Can be used only with catalog input type Dropdown, Multiple Select and Price".
797
  if (($inputType == 'select') || ($inputType == 'multiselect')) {
798
+ $item['type'] = 'select';
799
 
800
  } elseif ($inputType == 'price') {
801
+ $item['type'] = 'dynamic';
802
+ $step = self::_getPriceNavigationStep($store);
803
+
804
  if (!empty($step)) {
805
+ $item['min_range'] = $step;
806
  }
807
  } else {
808
+ // Nothing.
 
809
  }
810
 
811
+ if (isset($item['type'])) {
812
+ $item['title'] = $attribute->getData('frontend_label');
813
+ $item['position'] = $attribute->getPosition();
 
814
 
815
+ $attributeCode = $attribute->getAttributeCode();
816
 
817
  if ($attributeCode == 'price') {
818
  $labelAttribute = 'price';
819
  } else {
820
+ $labelAttribute = 'attribute_' . $attribute->getId();
821
  }
822
 
823
+ $item['attribute'] = $labelAttribute;
 
 
824
  }
825
  }
826
 
827
+ return $item;
828
  }
829
 
830
+ private static function _generateFacetFromCustom($title = '', $position = 0, $attribute = '', $type = '')
831
  {
832
+ $facet = array();
 
 
 
 
 
 
 
833
 
834
+ $facet['title'] = $title;
835
+ $facet['position'] = $position;
836
+ $facet['attribute'] = $attribute;
837
+ $facet['type'] = $type;
838
+
839
+ return $facet;
840
  }
841
 
842
  private static function validateProductIds($productIds, $store = null)
923
  }
924
 
925
  static $arrProducts = array();
 
 
 
 
 
 
926
 
927
+ $keyProducts = '';
928
+ if ($productIds) {
929
+ if (is_array($productIds)) {
930
+ $keyProducts .= implode('_', $productIds);
931
  } else {
932
+ $keyProducts .= $productIds;
933
  }
934
+ }
935
+ $keyProducts .= ':' . ($store ? $store->getId() : '0');
936
+ $keyProducts .= ':' . $customerGroupId;
937
+ $keyProducts .= ':' . (self::$isGetProductsByItems ? '1' : '0');
938
 
939
+ if (isset($arrProducts[$keyProducts])) {
940
+ // Nothing
941
+ } else {
942
  $products = Mage::getModel('catalog/product')
943
  ->getCollection()
944
  ->addAttributeToSelect('*')
958
  ->addStoreFilter($store);
959
  }
960
 
961
+ if ($productIds !== Simtech_Searchanise_Model_Queue::NOT_DATA) {
962
  // Already exist automatic definition 'one value' or 'array'.
963
  $products->addIdFilter($productIds);
964
+ }
965
 
966
  $products->load();
967
 
968
+ // Fixme in the future
969
+ // Maybe create cache without customerGroupId and setCustomerGroupId after using cache.
970
+ if ($products && ($store || $customerGroupId != null)) {
971
+ foreach ($products as $key => &$product) {
972
+ if ($product) {
973
+ if ($store) {
974
+ $product->setWebsiteId($store->getWebsiteId());
975
+ }
976
+ if ($customerGroupId != null) {
977
+ $product->setCustomerGroupId($customerGroupId);
978
+ }
 
 
979
  }
980
  }
981
  }
982
+ // end fixme
983
+
984
+ $arrProducts[$keyProducts] = $products;
985
  }
986
 
987
+ return $arrProducts[$keyProducts];
988
  }
989
 
990
  // Main functions //
991
+ public static function generateProductsFeed($productIds = null, $store = null, $checkData = true)
992
  {
993
+ $items = array();
994
 
995
  $products = self::getProducts($productIds, $store, null);
996
 
997
  if ($products) {
998
  foreach ($products as $product) {
999
+ if ($item = self::generateProductFeed($product, $store, $checkData)) {
1000
+ $items[] = $item;
1001
+ }
1002
  }
1003
  }
1004
 
1005
+ return $items;
1006
  }
1007
+
1008
+ private static function _getRequiredAttributes()
1009
  {
1010
+ static $requiredAttributes;
1011
+
1012
+ if (!isset($requiredAttributes)) {
1013
+ $requiredAttributes = array(
1014
+ 'status',
1015
+ 'visibility',
1016
+ 'price',
1017
+ 'weight',
1018
+ 'created_at',
1019
+ 'updated_at',
1020
+ );
1021
+ }
1022
 
1023
+ return $requiredAttributes;
1024
+ }
1025
+
1026
+ public static function getSchemaAttribute($attribute)
1027
+ {
1028
+ $items = array();
1029
+
1030
+ $requiredAttributes = self::_getRequiredAttributes();
1031
+ $useFullFeed = Mage::helper('searchanise/ApiSe')->getUseFullFeed();
1032
+
1033
+ $attributeCode = $attribute->getAttributeCode();
1034
+ $inputType = $attribute->getData('frontend_input');
1035
+ $isSearchable = $attribute->getIsSearchable();
1036
+ $isVisibleInAdvancedSearch = $attribute->getIsVisibleInAdvancedSearch();
1037
+ $usedForSortBy = $attribute->getUsedForSortBy();
1038
+ $attributeName = 'attribute_' . $attribute->getId();
1039
+
1040
+ $isNecessaryAttribute = $useFullFeed || $isSearchable || $isVisibleInAdvancedSearch || $usedForSortBy || in_array($attributeCode, $requiredAttributes);
1041
+
1042
+ if (!$isNecessaryAttribute) {
1043
+ return $items;
1044
  }
1045
 
1046
+ $name = $attribute->getAttributeCode();
1047
+ $title = $attribute->getData('frontend_label');
1048
+ $type = '';
1049
+ $textSearch = $isSearchable ? 'Y' : 'N';
1050
+ $attributeWeight = 0;
1051
+
1052
+ // <system_attributes>
1053
+ if ($attributeCode == 'price') {
1054
+ $type = 'float';
1055
+ $textSearch = 'N';
1056
+
1057
+ } elseif ($attributeCode == 'status' || $attributeCode == 'visibility') {
1058
+ $type = 'text';
1059
+ $textSearch = 'N';
1060
+ } elseif ($attributeCode == 'weight') {
1061
+ $type = 'float';
1062
+ $textSearch = 'N';
1063
+ // <dates>
1064
+ } elseif ($attributeCode == 'created_at' || $attributeCode == 'updated_at') {
1065
+ $type = 'int';
1066
+ $textSearch = 'N';
1067
+ if ($attributeCode == 'created_at'){
1068
+ $title = Mage::helper('searchanise')->__('Date Created');
1069
+ } elseif ($attributeCode == 'updated_at') {
1070
+ $title = Mage::helper('searchanise')->__('Date Updated');
1071
  }
1072
+ // </dates>
1073
+ } elseif ($attributeCode == 'has_options') {
1074
+ } elseif ($attributeCode == 'required_options') {
1075
+ } elseif ($attributeCode == 'custom_layout_update') {
1076
+ } elseif ($attributeCode == 'tier_price') { // quantity discount
1077
+ } elseif ($attributeCode == 'image_label') {
1078
+ } elseif ($attributeCode == 'small_image_label') {
1079
+ } elseif ($attributeCode == 'thumbnail_label') {
1080
+ } elseif ($attributeCode == 'url_key') { // seo name
1081
+ // <system_attributes>
1082
+
1083
+ } elseif ($attributeCode == 'group_price') {
1084
+ // nothing
1085
+ // fixme in the future if need
1086
+ } elseif (
1087
+ $attributeCode == 'short_description' ||
1088
+ $attributeCode == 'description' ||
1089
+ $attributeCode == 'meta_title' ||
1090
+ $attributeCode == 'meta_description' ||
1091
+ $attributeCode == 'meta_keyword') {
1092
+
1093
+ if ($isSearchable) {
1094
+ if ($attributeCode == 'short_description') {
1095
+ $attributeWeight = self::WEIGHT_SHORT_DESCRIPTION;
1096
+ } elseif ($attributeCode == 'description') {
1097
+ $attributeWeight = self::WEIGHT_DESCRIPTION;
1098
+ } elseif ($attributeCode == 'meta_title') {
1099
+ $attributeWeight = self::WEIGHT_META_TITLE;
1100
+ } elseif ($attributeCode == 'meta_description') {
1101
+ $attributeWeight = self::WEIGHT_META_DESCRIPTION;
1102
+ } elseif ($attributeCode == 'meta_keyword') {
1103
+ $attributeWeight = self::WEIGHT_META_KEYWORDS;
1104
+ } else {
1105
+ // Nothing.
1106
+ }
1107
+ }
1108
+ $type = 'text';
1109
+ if ($attributeCode == 'description') {
1110
+ $items[] = array(
1111
+ 'name' => 'se_grouped_' . $attributeCode,
1112
+ 'title' => $attribute->getData('frontend_label') . ' - Grouped',
1113
+ 'type' => $type,
1114
+ 'weight' => $isSearchable ? self:: WEIGHT_DESCRIPTION_GROUPED : 0,
1115
+ 'text_search' => $textSearch,
1116
+ );
1117
+ }
1118
+
1119
+ } elseif ($inputType == 'price') {
1120
+ $type = 'float';
1121
+
1122
+ } elseif ($inputType == 'select' || $inputType == 'multiselect') {
1123
+ $type = 'text';
1124
+ $items[] = array(
1125
+ 'name' => $name,
1126
+ 'title' => $title,
1127
+ 'type' => $type,
1128
+ 'weight' => $isSearchable ? self::WEIGHT_SELECT_ATTRIBUTES : 0,
1129
+ 'text_search' => $textSearch,
1130
+ );
1131
+ $name = $attributeName;
1132
+ $title = $title . ' - IDs';
1133
+ $textSearch = 'N';
1134
+
1135
+ } elseif ($inputType == 'text' || $inputType == 'textarea') {
1136
+ if ($isSearchable) {
1137
+ if ($inputType == 'text') {
1138
+ $attributeWeight = self::WEIGHT_TEXT_ATTRIBUTES;
1139
+ } elseif ($inputType == 'textarea') {
1140
+ $attributeWeight = self::WEIGHT_TEXT_AREA_ATTRIBUTES;
1141
+ }
1142
+ }
1143
+ $type = 'text';
1144
+
1145
+ } elseif ($inputType == 'date') {
1146
+ $type = 'int';
1147
+
1148
+ } elseif ($inputType == 'media_image') {
1149
+ $type = 'text';
1150
+
1151
+ } elseif ($inputType == 'gallery') {
1152
+ // Nothing.
1153
+ } else {
1154
+ // Attribute not will use.
1155
  }
1156
+
1157
+ if ($type) {
1158
+ $item = array(
1159
+ 'name' => $name,
1160
+ 'title' => $title,
1161
+ 'type' => $type,
1162
+ 'weight' => $attributeWeight,
1163
+ 'text_search' => $textSearch,
1164
+ );
1165
+
1166
+ if ($facet = self::_generateFacetFromFilter($attribute)) {
1167
+ $item['facet'] = $facet;
1168
  }
1169
+ $items[] = $item;
1170
  }
1171
+
1172
+ return $items;
1173
  }
1174
 
1175
+ public static function getSchemaPrices($store = null)
1176
  {
1177
+ return self::getSchema(null, $store, true);
1178
  }
1179
 
1180
+ public static function getSchemaCustomerGroupsPrices()
1181
  {
1182
+ $items = array();
 
 
 
 
1183
 
1184
+ if ($customerGroups = self::_getCustomerGroups()) {
1185
+ foreach ($customerGroups as $keyCustomerGroup => $customerGroup) {
1186
+ $label = Mage::helper('searchanise/ApiSe')->getLabelForPricesUsergroup() . $customerGroup->getId();
1187
+ $items[] = array(
1188
+ 'name' => $label,
1189
+ 'title' => 'Price for ' . $customerGroup->getData('customer_group_code'),
1190
+ 'type' => 'float',
1191
+ );
1192
+ }
1193
  }
1194
 
1195
+ return $items;
1196
+ }
1197
+
1198
+ public static function getSchemaCategories()
1199
+ {
1200
+ static $items;
1201
+
1202
+ if (!isset($items)) {
1203
+ $items[] = array(
1204
+ 'name' => 'categories',
1205
+ 'title' => 'Categories',
1206
+ 'type' => 'text',
1207
+ 'weight' => self::WEIGHT_CATEGORIES,
1208
+ 'text_search' => 'Y',
1209
+ );
1210
+
1211
+ $items[] = array(
1212
+ 'name' => 'category_ids',
1213
+ 'title' => 'Categories - IDs',
1214
+ 'type' => 'text',
1215
+ 'weight' => 0,
1216
+ 'text_search' => 'N',
1217
+ 'facet' => self::_generateFacetFromCustom('Category', 0, 'category_ids', 'select'),
1218
+ );
1219
  }
1220
+ return $items;
1221
+ }
1222
 
1223
+ public static function getSchemaTags()
1224
+ {
1225
+ static $items;
1226
+
1227
+ if (!isset($items)) {
1228
+ $items[] = array(
1229
+ 'name' => 'tags',
1230
+ 'title' => 'Tags',
1231
+ 'type' => 'text',
1232
+ 'weight' => self::WEIGHT_TAGS,
1233
+ 'text_search' => 'Y',
1234
+ );
1235
+
1236
+ $items[] = array(
1237
+ 'name' => 'tag_ids',
1238
+ 'title' => 'Tags - IDs',
1239
+ 'type' => 'text',
1240
+ 'weight' => 0,
1241
+ 'text_search' => 'N',
1242
+ 'facet' => self::_generateFacetFromCustom('Tag', 0, 'tag_ids', 'select'),
1243
+ );
1244
+ }
1245
+ return $items;
1246
  }
1247
+
1248
+ public static function getSchema($attributeIds = Simtech_Searchanise_Model_Queue::NOT_DATA, $store = null, $isPrice = false)
1249
  {
1250
+ static $schema;
1251
+
1252
+ if (isset($schema)) {
1253
+ return $schema;
1254
+ }
1255
+
1256
+ $schema = array();
1257
+
1258
+ if ($attributeIds === Simtech_Searchanise_Model_Queue::NOT_DATA) {
1259
+ $schema = self::getSchemaCustomerGroupsPrices();
1260
+
1261
+ if ($items = self::getSchemaCategories()) {
1262
+ foreach ($items as $keyItem => $item) {
1263
+ $schema[] = $item;
1264
+ }
1265
+ }
1266
+
1267
+ if ($items = self::getSchemaTags()) {
1268
+ foreach ($items as $keyItem => $item) {
1269
+ $schema[] = $item;
1270
+ }
1271
+ }
1272
+ $schema[] = array(
1273
+ 'name' => 'is_in_stock',
1274
+ 'title' => 'Stock Availability',
1275
+ 'type' => 'text',
1276
+ 'weight' => 0,
1277
+ 'text_search' => 'N',
1278
+ );
1279
+ $schema[] = array(
1280
+ 'name' => 'quantity_decimals',
1281
+ 'title' => 'Quantity - decimals',
1282
+ 'type' => 'text',
1283
+ 'weight' => 0,
1284
+ 'text_search' => 'N',
1285
+ );
1286
+ $schema[] = array(
1287
+ 'name' => 'created_at',
1288
+ 'title' => 'Created Date',
1289
+ 'type' => 'text',
1290
+ 'weight' => 0,
1291
+ 'text_search' => 'N',
1292
+ );
1293
+ $schema[] = array(
1294
+ 'name' => 'position',
1295
+ 'title' => 'Position',
1296
+ 'type' => 'text',
1297
+ 'weight' => 0,
1298
+ 'text_search' => 'N',
1299
+ );
1300
+ }
1301
+
1302
+ if ($attributes = self::getProductAttributes($attributeIds, $store, $isPrice)) {
1303
+ foreach ($attributes as $attribute) {
1304
+ if ($items = self::getSchemaAttribute($attribute)) {
1305
+ foreach ($items as $keyItem => $item) {
1306
+ $schema[] = $item;
1307
+ }
1308
+ }
1309
+ }
1310
+ }
1311
+
1312
+ return $schema;
1313
  }
1314
 
1315
+ public static function getHeader($store = null)
1316
  {
1317
  $url = '';
1318
 
1319
+ if ($store) {
1320
  $url = Mage::app()->getStore()->getBaseUrl();
1321
  } else {
1322
  $url = $store->getUrl();
1323
  }
 
1324
  $date = date('c');
1325
+
1326
+ return array(
1327
+ 'id' => $url,
1328
+ 'updated' => $date,
1329
+ );
 
 
 
 
 
 
1330
  }
1331
  }
app/code/community/Simtech/Searchanise/Helper/ApiSe.php CHANGED
@@ -142,7 +142,7 @@ class Simtech_Searchanise_Helper_ApiSe
142
  public static function getServiceUrl($onlyHttp = true)
143
  {
144
  $ret = self::getSetting('service_url');
145
-
146
  if (!$onlyHttp) {
147
  if (Mage::app()->getStore()->isCurrentlySecure()) {
148
  $ret = str_replace('http://', 'https://', $ret);
@@ -540,6 +540,11 @@ class Simtech_Searchanise_Helper_ApiSe
540
  {
541
  return self::getSetting('products_per_pass');
542
  }
 
 
 
 
 
543
 
544
  public static function getMaxErrorCount()
545
  {
@@ -666,6 +671,19 @@ class Simtech_Searchanise_Helper_ApiSe
666
 
667
  public static function httpRequest($method = Zend_Http_Client::POST, $url = '', $data = array(), $cookies = array(), $basicAuth = array(), $timeout = 0, $maxredirects = 5)
668
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
669
  $client = new Zend_Http_Client();
670
 
671
  $client->setUri($url);
@@ -684,48 +702,21 @@ class Simtech_Searchanise_Helper_ApiSe
684
 
685
  try {
686
  $response = $client->request($method);
 
687
  } catch (Exception $e) {
688
  self::log($e->getMessage());
689
-
690
- return null;
 
691
  }
692
-
693
- $responseBody = $response->getBody();
694
-
695
  // fixme in the future
696
  // add getHeader()
697
  //~ return array($response->getHeader(), $response->getBody());
698
- return array('', $response->getBody());
699
- }
700
-
701
- /**
702
- *
703
- *
704
- * @param array $arr_cat
705
- * @param Mage_Catalog_Model_Category $category
706
- * @return array
707
- */
708
- public static function getAllChildrenCategories(&$arr_cat, $category, $fl_include_cur_cat = true)
709
- {
710
- if (empty($arr_cat)) {
711
- $arr_cat = array();
712
- }
713
-
714
- if (!empty($category)) {
715
- if ($fl_include_cur_cat == true) {
716
- $arr_cat[] = $category->getId();
717
- }
718
-
719
- $children_cat = $category->getChildrenCategories();
720
-
721
- if (!empty($children_cat)) {
722
- foreach ($children_cat as $cat) {
723
- self::getAllChildrenCategories($arr_cat, $cat, $fl_include_cur_cat);
724
- }
725
- }
726
  }
727
-
728
- return $arr_cat;
729
  }
730
 
731
  public static function escapingCharacters($str)
@@ -1205,9 +1196,15 @@ class Simtech_Searchanise_Helper_ApiSe
1205
  return array($startId, $endId);
1206
  }
1207
 
1208
- public static function getProductIdsFormRange($start, $end, $step, $store = null)
1209
  {
1210
  $arrProducts = array();
 
 
 
 
 
 
1211
 
1212
  $products = Mage::getModel('catalog/product')
1213
  ->getCollection()
@@ -1215,10 +1212,22 @@ class Simtech_Searchanise_Helper_ApiSe
1215
  ->setPageSize($step);
1216
 
1217
  if ($store) {
1218
- $products = $products->addStoreFilter($store);
 
 
 
 
 
 
 
 
 
 
 
 
1219
  }
1220
 
1221
- $products = $products->load();
1222
  if ($products) {
1223
  // Not used because 'arrProducts' comprising 'stock_item' field and is 'array(array())'
1224
  // $arrProducts = $products->toArray(array('entity_id'));
@@ -1349,6 +1358,55 @@ class Simtech_Searchanise_Helper_ApiSe
1349
 
1350
  return $ret;
1351
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1352
 
1353
  public static function async($flIgnoreProcessing = false)
1354
  {
@@ -1371,14 +1429,13 @@ class Simtech_Searchanise_Helper_ApiSe
1371
  if (Mage::helper('searchanise')->checkDebug()) {
1372
  Mage::helper('searchanise/ApiSe')->printR($q);
1373
  }
1374
- $xml = '';
1375
  $status = true;
1376
- $data = array();
1377
  $store = Mage::app()->getStore($q['store_id']);
1378
- $xmlHeader = Mage::helper('searchanise/ApiXML')->getXMLHeader($store);
1379
- $xmlFooter = Mage::helper('searchanise/ApiXML')->getXMLFooter($store);
1380
- if ((!empty($q['data'])) && ($q['data'] != Simtech_Searchanise_Model_Queue::NOT_DATA)) {
1381
- $data = unserialize($q['data']);
1382
  }
1383
 
1384
  $privateKey = self::getPrivateKey($store);
@@ -1413,7 +1470,7 @@ class Simtech_Searchanise_Helper_ApiSe
1413
  if ($q['action'] == Simtech_Searchanise_Model_Queue::ACT_PREPARE_FULL_IMPORT) {
1414
  Mage::getModel('searchanise/queue')
1415
  ->getCollection()
1416
- ->addFieldToFilter('action', array("neq" => Simtech_Searchanise_Model_Queue::ACT_PREPARE_FULL_IMPORT))
1417
  ->addFilter('store_id', $store->getId())
1418
  ->load()
1419
  ->delete();
@@ -1426,174 +1483,147 @@ class Simtech_Searchanise_Helper_ApiSe
1426
 
1427
  Mage::getModel('searchanise/queue')->setData($queueData)->save();
1428
 
1429
- $i = 0;
1430
- $step = self::getProductsPerPass() * 50;
1431
-
1432
- list($start, $max) = self::getMinMaxProductId($store);
1433
-
1434
- do {
1435
- $end = $start + $step;
1436
-
1437
- $_productIds = self::getProductIdsFormRange($start, $end, $step, $store);
1438
-
1439
- $start = $end + 1;
1440
-
1441
- if (empty($_productIds)) {
1442
- continue;
1443
- }
1444
- $_productIds = array_chunk($_productIds, self::getProductsPerPass());
1445
-
1446
- foreach ($_productIds as $productIds) {
1447
- $_data = serialize($productIds);
1448
- $queueData = array(
1449
- 'data' => $_data,
1450
- 'action' => Simtech_Searchanise_Model_Queue::ACT_UPDATE,
1451
- 'store_id' => $store->getId(),
1452
- );
1453
- $_result = Mage::getModel('searchanise/queue')->setData($queueData)->save();
1454
- // It is necessary for save memory.
1455
- unset($_result);
1456
- unset($_data);
1457
- unset($queueData);
1458
- }
1459
-
1460
- } while ($end <= $max);
1461
-
1462
- self::echoConnectProgress('.');
1463
-
1464
- //
1465
- // reSend all active filters
1466
- //
1467
-
1468
- $queueData = array(
1469
- 'data' => Simtech_Searchanise_Model_Queue::NOT_DATA,
1470
- 'action' => Simtech_Searchanise_Model_Queue::ACT_FACET_DELETE_ALL,
1471
- 'store_id' => $store->getId(),
1472
- );
1473
- Mage::getModel('searchanise/queue')->setData($queueData)->save();
1474
-
1475
- $filterIds = self::getFiltersIds($store);
1476
-
1477
- if (!empty($filterIds)) {
1478
- $queueData = array(
1479
- 'data' => serialize($filterIds),
1480
- 'action' => Simtech_Searchanise_Model_Queue::ACT_FACET_UPDATE,
1481
- 'store_id' => $store->getId(),
1482
- );
1483
-
1484
- Mage::getModel('searchanise/queue')->setData($queueData)->save();
1485
- }
1486
-
1487
- // add facet-categories
1488
  {
1489
  $queueData = array(
1490
- 'data' => serialize(Simtech_Searchanise_Model_Queue::DATA_FACET_CATEGORIES),
1491
- 'action' => Simtech_Searchanise_Model_Queue::ACT_FACET_UPDATE,
1492
  'store_id' => $store->getId(),
1493
  );
1494
-
1495
  Mage::getModel('searchanise/queue')->setData($queueData)->save();
1496
- }
1497
-
1498
- // add facet-tags
1499
- {
1500
  $queueData = array(
1501
- 'data' => serialize(Simtech_Searchanise_Model_Queue::DATA_FACET_TAGS),
1502
- 'action' => Simtech_Searchanise_Model_Queue::ACT_FACET_UPDATE,
1503
  'store_id' => $store->getId(),
1504
  );
1505
 
1506
  Mage::getModel('searchanise/queue')->setData($queueData)->save();
1507
  }
1508
-
 
 
 
 
 
 
1509
  $queueData = array(
1510
  'data' => Simtech_Searchanise_Model_Queue::NOT_DATA,
1511
  'action' => Simtech_Searchanise_Model_Queue::ACT_END_FULL_IMPORT,
1512
  'store_id' => $store->getId(),
1513
  );
1514
-
1515
  Mage::getModel('searchanise/queue')->setData($queueData)->save();
1516
 
1517
  $status = true;
1518
-
1519
  } elseif ($q['action'] == Simtech_Searchanise_Model_Queue::ACT_START_FULL_IMPORT) {
1520
- $status = self::sendRequest('/api/state/update', $privateKey, array('full_import' => self::EXPORT_STATUS_START), true);
1521
 
1522
  if ($status == true) {
1523
  self::setExportStatus(self::EXPORT_STATUS_PROCESSING, $store);
1524
  }
1525
 
1526
  } elseif ($q['action'] == Simtech_Searchanise_Model_Queue::ACT_END_FULL_IMPORT) {
1527
- $status = self::sendRequest('/api/state/update', $privateKey, array('full_import' => self::EXPORT_STATUS_DONE), true);
1528
 
1529
  if ($status == true) {
1530
  self::setExportStatus(self::EXPORT_STATUS_SENT, $store);
1531
  self::setLastResync(self::getTime());
1532
  }
1533
-
1534
- } elseif ($q['action'] == Simtech_Searchanise_Model_Queue::ACT_FACET_DELETE_ALL) {
1535
- $status = self::sendRequest('/api/facets/delete', $privateKey, array('all' => true), true);
1536
-
1537
- } elseif ($q['action'] == Simtech_Searchanise_Model_Queue::ACT_FACET_UPDATE) {
1538
- if ($data == Simtech_Searchanise_Model_Queue::DATA_FACET_CATEGORIES) {
1539
- $xml .= Mage::helper('searchanise/ApiXML')->generateFacetXMLCategories();
1540
-
1541
- } elseif ($data == Simtech_Searchanise_Model_Queue::DATA_FACET_PRICES) {
1542
- $xml .= Mage::helper('searchanise/ApiXML')->generateFacetXMLPrices();
1543
 
1544
- } elseif ($data == Simtech_Searchanise_Model_Queue::DATA_FACET_TAGS) {
1545
- $xml .= Mage::helper('searchanise/ApiXML')->generateFacetXMLTags();
1546
-
1547
- } else {
1548
- $xml .= Mage::helper('searchanise/ApiXML')->generateFacetXMLFilters($data, $store);
1549
- }
1550
-
1551
- if (!empty($xml)) {
1552
- $status = self::sendRequest('/api/facets/update', $privateKey, array('data' => $xmlHeader . $xml . $xmlFooter), true);
1553
  }
1554
-
1555
- } elseif ($q['action'] == Simtech_Searchanise_Model_Queue::ACT_FACET_DELETE) {
1556
- if (!empty($data)) {
1557
- foreach ($data as $facetAttribute) {
1558
- $status = self::sendRequest('/api/facets/delete', $privateKey, array('attribute' => $facetAttribute), true);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1559
 
1560
- self::echoConnectProgress('.');
 
 
 
 
1561
 
1562
- if ($status == false) {
1563
- break;
1564
- }
 
 
 
 
 
 
1565
  }
1566
  }
1567
-
1568
- } elseif ($q['action'] == Simtech_Searchanise_Model_Queue::ACT_UPDATE) {
1569
- $xml .= Mage::helper('searchanise/ApiXML')->generateProductsXML($data, $store);
1570
-
1571
- if (!empty($xml)) {
1572
  if (function_exists('gzcompress')) {
1573
- $data = gzcompress($xmlHeader . $xml . $xmlFooter, self::COMPRESS_RATE);
1574
- } else {
1575
- $data = $xmlHeader . $xml . $xmlFooter;
1576
  }
1577
- $status = self::sendRequest('/api/items/update', $privateKey, array('data' => $data), true);
1578
  }
1579
 
1580
- } elseif ($q['action'] == Simtech_Searchanise_Model_Queue::ACT_DELETE) {
1581
- foreach ($data as $product_id) {
1582
- $status = self::sendRequest('/api/items/delete', $privateKey, array('id' => $product_id), true);
1583
-
1584
- self::echoConnectProgress('.');
1585
-
1586
- if ($status == false) {
1587
- break;
 
 
 
 
 
 
 
 
 
1588
  }
1589
  }
1590
-
1591
- } elseif ($q['action'] == Simtech_Searchanise_Model_Queue::ACT_DELETE_ALL) {
1592
- $status = self::sendRequest('/api/items/delete', $privateKey, array('all' => true), true);
1593
-
1594
  } elseif ($q['action'] == Simtech_Searchanise_Model_Queue::ACT_PHRASE) {
1595
  foreach ($data as $phrase) {
1596
- $status = self::sendRequest('/api/phrases/update', $privateKey, array('phrase' => $phrase), true);
1597
 
1598
  self::echoConnectProgress('.');
1599
 
@@ -1643,77 +1673,86 @@ class Simtech_Searchanise_Helper_ApiSe
1643
  if (!empty($stores)) {
1644
  foreach ($stores as $store) {
1645
  $privateKey = self::getPrivateKey($store);
1646
- self::sendRequest('/api/state/update', $privateKey, array('addon_status' => $status), true);
1647
  }
1648
  }
1649
  }
1650
 
1651
  public static function sendRequest($urlPart, $privateKey, $data, $onlyHttp = true)
1652
  {
1653
- $ret = null;
1654
 
1655
  if (!empty($privateKey)) {
1656
  $params = array('private_key' => $privateKey) + $data;
1657
 
1658
- list($h, $result) = self::httpRequest(Zend_Http_Client::POST, self::getServiceUrl($onlyHttp) . $urlPart, $params, array(), array(), self::getRequestTimeout());
1659
-
1660
- $ret = self::parseResponse($result, false);
 
 
1661
 
1662
  self::setLastRequest(self::getTime());
1663
  }
1664
 
1665
- return $ret;
1666
  }
1667
 
1668
  /**
1669
  * Parse response from service
1670
  *
1671
- * @param string $res xml service response
1672
- * @return mixed false if errors returned, true if response is ok, xml object if data was passed in the response
1673
  */
1674
- public static function parseResponse($res, $showNotification = false)
1675
  {
1676
- $xml = simplexml_load_string($res, null, LIBXML_NOERROR);
1677
-
1678
- if (empty($res) || $xml === false) {
1679
- return false;
 
 
 
 
 
 
 
 
 
 
 
1680
  }
1681
-
1682
- if (!empty($xml->error)) {
1683
- foreach ($xml->error as $e) {
 
 
1684
  if ($showNotification == true) {
1685
- self::setNotification('E', Mage::helper('searchanise')->__('Error'), 'Searchanise: ' . (string)$e);
1686
  }
 
1687
  }
1688
 
1689
- return false;
1690
- } elseif (strtolower($xml->getName()) == 'ok') {
1691
- return true;
1692
  } else {
1693
- return $xml;
1694
  }
 
 
1695
  }
1696
 
1697
- public static function parseStateResponse($xml, $element = false)
1698
  {
1699
- $res = array();
1700
- if (!is_object($xml)) {
1701
- return false;
1702
- }
1703
 
1704
- if ($xml->getName() == 'variable') {
1705
- foreach ($xml as $v) {
1706
- $res[$v->getName()] = (string)$v;
1707
  }
1708
- } else {
1709
- return false;
1710
- }
1711
-
1712
- if (!empty($element)) {
1713
- $res = isset($res[$element])? $res[$element] : false;
1714
  }
1715
 
1716
- return $res;
1717
  }
1718
 
1719
  public static function deleteKeys($stores = null)
@@ -1746,18 +1785,17 @@ class Simtech_Searchanise_Helper_ApiSe
1746
 
1747
  foreach ($stores as $store) {
1748
  if (self::getExportStatus($store) == self::EXPORT_STATUS_SENT && ((self::getTime() - self::getLastRequest()) > self::getRequestTimeout() || $skipTimeCheck == true)) {
1749
- $xml = self::sendRequest('/api/state/get', self::getPrivateKey($store), array('status' => '', 'full_import' => ''), true);
1750
-
1751
- $variables = self::parseStateResponse($xml);
1752
 
1753
- if ((!empty($variables)) && (isset($variables['status']))) {
1754
- if (($variables['status'] == self::STATUS_NORMAL) &&
1755
- (isset($variables['full_import'])) &&
1756
- ($variables['full_import'] == self::EXPORT_STATUS_DONE)) {
1757
  $skipTimeCheck = true;
1758
  self::setExportStatus(self::EXPORT_STATUS_DONE, $store);
1759
 
1760
- } elseif ($variables['status'] == self::STATUS_DISABLED) {
1761
  self::setExportStatus(self::EXPORT_STATUS_NONE, $store);
1762
  }
1763
  }
@@ -1773,24 +1811,7 @@ class Simtech_Searchanise_Helper_ApiSe
1773
 
1774
  return $result;
1775
  }
1776
-
1777
- public static function getPriceFilters($store = null)
1778
- {
1779
- $filters = Mage::getResourceModel('catalog/product_attribute_collection')
1780
- ->setItemObjectClass('catalog/resource_eav_attribute')
1781
- ->addIsFilterableFilter()
1782
- ->addFieldToFilter('frontend_input', array('eq' => 'price'));
1783
-
1784
-
1785
- if (!empty($store)) {
1786
- $filters->addStoreLabel($store->getId());
1787
- }
1788
-
1789
- $filters->load();
1790
-
1791
- return $filters;
1792
- }
1793
-
1794
  public static function getStoreByWebsiteIds($websiteIds = array())
1795
  {
1796
  $ret = array();
@@ -1867,6 +1888,9 @@ class Simtech_Searchanise_Helper_ApiSe
1867
  public static function log($message = '', $type = 'Error')
1868
  {
1869
  Mage::log("Searchanise # {$type}: {$message}");
 
 
 
1870
 
1871
  return true;
1872
  }
142
  public static function getServiceUrl($onlyHttp = true)
143
  {
144
  $ret = self::getSetting('service_url');
145
+
146
  if (!$onlyHttp) {
147
  if (Mage::app()->getStore()->isCurrentlySecure()) {
148
  $ret = str_replace('http://', 'https://', $ret);
540
  {
541
  return self::getSetting('products_per_pass');
542
  }
543
+
544
+ public static function getCategoriesPerPass()
545
+ {
546
+ return self::getSetting('categories_per_pass');
547
+ }
548
 
549
  public static function getMaxErrorCount()
550
  {
671
 
672
  public static function httpRequest($method = Zend_Http_Client::POST, $url = '', $data = array(), $cookies = array(), $basicAuth = array(), $timeout = 0, $maxredirects = 5)
673
  {
674
+ if (Mage::helper('searchanise')->checkDebug(true)) {
675
+ Mage::helper('searchanise/ApiSe')->printR('httpRequest',
676
+ 'method', $method,
677
+ 'url', $url,
678
+ 'data', $data,
679
+ 'cookies', $cookies,
680
+ 'basicAuth', $basicAuth,
681
+ 'timeout', $timeout,
682
+ 'maxredirects', $maxredirects
683
+ );
684
+ }
685
+ $responseHeader = '';
686
+ $responseBody = '';
687
  $client = new Zend_Http_Client();
688
 
689
  $client->setUri($url);
702
 
703
  try {
704
  $response = $client->request($method);
705
+ $responseBody = $response->getBody();
706
  } catch (Exception $e) {
707
  self::log($e->getMessage());
708
+ if (Mage::helper('searchanise')->checkDebug(true)) {
709
+ Mage::helper('searchanise/ApiSe')->printR('response', $response);
710
+ }
711
  }
712
+
 
 
713
  // fixme in the future
714
  // add getHeader()
715
  //~ return array($response->getHeader(), $response->getBody());
716
+ if (Mage::helper('searchanise')->checkDebug(true)) {
717
+ Mage::helper('searchanise/ApiSe')->printR('responseBody', $responseBody);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
718
  }
719
+ return array($responseHeader, $responseBody);
 
720
  }
721
 
722
  public static function escapingCharacters($str)
1196
  return array($startId, $endId);
1197
  }
1198
 
1199
+ public static function getProductIdsFormRange($start, $end, $step, $store = null, $isOnlyActive = false)
1200
  {
1201
  $arrProducts = array();
1202
+ // Need for get correct products.
1203
+ if ($store) {
1204
+ Mage::app()->setCurrentStore($store->getId());
1205
+ } else {
1206
+ Mage::app()->setCurrentStore(0);
1207
+ }
1208
 
1209
  $products = Mage::getModel('catalog/product')
1210
  ->getCollection()
1212
  ->setPageSize($step);
1213
 
1214
  if ($store) {
1215
+ $products->addStoreFilter($store);
1216
+ }
1217
+
1218
+ if ($isOnlyActive) {
1219
+ Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($products);
1220
+ // Fixme in the future
1221
+ // It may require to disable "product visibility" filter if "is full feed".
1222
+ if (self::getUseFullFeed() || self::getUseNavigation()) {
1223
+ Mage::getSingleton('catalog/product_visibility')->addVisibleInSiteFilterToCollection($products);
1224
+ } else {
1225
+ Mage::getSingleton('catalog/product_visibility')->addVisibleInSearchFilterToCollection($products);
1226
+ }
1227
+ // end fixme
1228
  }
1229
 
1230
+ $products->load();
1231
  if ($products) {
1232
  // Not used because 'arrProducts' comprising 'stock_item' field and is 'array(array())'
1233
  // $arrProducts = $products->toArray(array('entity_id'));
1358
 
1359
  return $ret;
1360
  }
1361
+ private static function _addTaskByChunk($store, $action = Simtech_Searchanise_Model_Queue::ACT_UPDATE_PRODUCTS, $isOnlyActive = false)
1362
+ {
1363
+ $i = 0;
1364
+ $step = 50;
1365
+ $start = 0;
1366
+ $max = 0;
1367
+
1368
+ if ($action == Simtech_Searchanise_Model_Queue::ACT_UPDATE_PRODUCTS) {
1369
+ $step = self::getProductsPerPass() * 50;
1370
+ list($start, $max) = self::getMinMaxProductId($store);
1371
+ } elseif ($action == Simtech_Searchanise_Model_Queue::ACT_UPDATE_CATEGORIES) {
1372
+ $step = self::getCategoriesPerPass() * 50;
1373
+ list($start, $max) = Mage::helper('searchanise/ApiCategories')->getMinMaxCategoryId($store);
1374
+ }
1375
+
1376
+ do {
1377
+ $end = $start + $step;
1378
+ $chunkItemIds = null;
1379
+
1380
+ if ($action == Simtech_Searchanise_Model_Queue::ACT_UPDATE_PRODUCTS) {
1381
+ $chunkItemIds = self::getProductIdsFormRange($start, $end, $step, $store, $isOnlyActive);
1382
+ } elseif ($action == Simtech_Searchanise_Model_Queue::ACT_UPDATE_CATEGORIES) {
1383
+ $chunkItemIds = Mage::helper('searchanise/ApiCategories')->getCategoryIdsFormRange($start, $end, $step, $store);
1384
+ }
1385
+
1386
+ $start = $end + 1;
1387
+
1388
+ if (empty($chunkItemIds)) {
1389
+ continue;
1390
+ }
1391
+ $chunkItemIds = array_chunk($chunkItemIds, self::getProductsPerPass());
1392
+
1393
+ foreach ($chunkItemIds as $itemIds) {
1394
+ $queueData = array(
1395
+ 'data' => serialize($itemIds),
1396
+ 'action' => $action,
1397
+ 'store_id' => $store->getId(),
1398
+ );
1399
+ $_result = Mage::getModel('searchanise/queue')->setData($queueData)->save();
1400
+ // It is necessary for save memory.
1401
+ unset($_result);
1402
+ unset($_data);
1403
+ unset($queueData);
1404
+ }
1405
+
1406
+ } while ($end <= $max);
1407
+
1408
+ return true;
1409
+ }
1410
 
1411
  public static function async($flIgnoreProcessing = false)
1412
  {
1429
  if (Mage::helper('searchanise')->checkDebug()) {
1430
  Mage::helper('searchanise/ApiSe')->printR($q);
1431
  }
1432
+ $dataForSend = array();
1433
  $status = true;
 
1434
  $store = Mage::app()->getStore($q['store_id']);
1435
+ $header = Mage::helper('searchanise/ApiProducts')->getHeader($store);
1436
+ $data = $q['data'];
1437
+ if (!empty($data) && $data !== Simtech_Searchanise_Model_Queue::NOT_DATA) {
1438
+ $data = unserialize($data);
1439
  }
1440
 
1441
  $privateKey = self::getPrivateKey($store);
1470
  if ($q['action'] == Simtech_Searchanise_Model_Queue::ACT_PREPARE_FULL_IMPORT) {
1471
  Mage::getModel('searchanise/queue')
1472
  ->getCollection()
1473
+ ->addFieldToFilter('action', array('neq' => Simtech_Searchanise_Model_Queue::ACT_PREPARE_FULL_IMPORT))
1474
  ->addFilter('store_id', $store->getId())
1475
  ->load()
1476
  ->delete();
1483
 
1484
  Mage::getModel('searchanise/queue')->setData($queueData)->save();
1485
 
1486
+ // <schemas>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1487
  {
1488
  $queueData = array(
1489
+ 'data' => Simtech_Searchanise_Model_Queue::NOT_DATA,
1490
+ 'action' => Simtech_Searchanise_Model_Queue::ACT_DELETE_FACETS_ALL,
1491
  'store_id' => $store->getId(),
1492
  );
 
1493
  Mage::getModel('searchanise/queue')->setData($queueData)->save();
1494
+
 
 
 
1495
  $queueData = array(
1496
+ 'data' => Simtech_Searchanise_Model_Queue::NOT_DATA,
1497
+ 'action' => Simtech_Searchanise_Model_Queue::ACT_UPDATE_ATTRIBUTES,
1498
  'store_id' => $store->getId(),
1499
  );
1500
 
1501
  Mage::getModel('searchanise/queue')->setData($queueData)->save();
1502
  }
1503
+ // </schemas>
1504
+
1505
+ self::_addTaskByChunk($store, $action = Simtech_Searchanise_Model_Queue::ACT_UPDATE_PRODUCTS, true);
1506
+ self::_addTaskByChunk($store, $action = Simtech_Searchanise_Model_Queue::ACT_UPDATE_CATEGORIES, true);
1507
+
1508
+ self::echoConnectProgress('.');
1509
+
1510
  $queueData = array(
1511
  'data' => Simtech_Searchanise_Model_Queue::NOT_DATA,
1512
  'action' => Simtech_Searchanise_Model_Queue::ACT_END_FULL_IMPORT,
1513
  'store_id' => $store->getId(),
1514
  );
1515
+
1516
  Mage::getModel('searchanise/queue')->setData($queueData)->save();
1517
 
1518
  $status = true;
1519
+
1520
  } elseif ($q['action'] == Simtech_Searchanise_Model_Queue::ACT_START_FULL_IMPORT) {
1521
+ $status = self::sendRequest('/api/state/update/json', $privateKey, array('full_import' => self::EXPORT_STATUS_START), true);
1522
 
1523
  if ($status == true) {
1524
  self::setExportStatus(self::EXPORT_STATUS_PROCESSING, $store);
1525
  }
1526
 
1527
  } elseif ($q['action'] == Simtech_Searchanise_Model_Queue::ACT_END_FULL_IMPORT) {
1528
+ $status = self::sendRequest('/api/state/update/json', $privateKey, array('full_import' => self::EXPORT_STATUS_DONE), true);
1529
 
1530
  if ($status == true) {
1531
  self::setExportStatus(self::EXPORT_STATUS_SENT, $store);
1532
  self::setLastResync(self::getTime());
1533
  }
 
 
 
 
 
 
 
 
 
 
1534
 
1535
+ } elseif (Simtech_Searchanise_Model_Queue::isDeleteAllAction($q['action'])) {
1536
+ $type = Simtech_Searchanise_Model_Queue::getAPITypeByAction($q['action']);
1537
+ if ($type) {
1538
+ $status = self::sendRequest("/api/{$type}/delete/json", $privateKey, array('all' => true), true);
 
 
 
 
 
1539
  }
1540
+
1541
+ } elseif (Simtech_Searchanise_Model_Queue::isUpdateAction($q['action'])) {
1542
+ $dataForSend = array();
1543
+
1544
+ if ($q['action'] == Simtech_Searchanise_Model_Queue::ACT_UPDATE_PRODUCTS) {
1545
+ $items = Mage::helper('searchanise/ApiProducts')->generateProductsFeed($data, $store);
1546
+ if (!empty($items)) {
1547
+ $dataForSend = array(
1548
+ 'header' => $header,
1549
+ 'items' => $items,
1550
+ );
1551
+ }
1552
+ } elseif ($q['action'] == Simtech_Searchanise_Model_Queue::ACT_UPDATE_CATEGORIES) {
1553
+ $categories = Mage::helper('searchanise/ApiCategories')->generateCategoriesFeed($data, $store, true);
1554
+ if (!empty($categories)) {
1555
+ $dataForSend = array(
1556
+ 'header' => $header,
1557
+ 'categories' => $categories,
1558
+ );
1559
+ }
1560
+
1561
+ } elseif ($q['action'] == Simtech_Searchanise_Model_Queue::ACT_UPDATE_PAGES) {
1562
+ // Fixme in the future
1563
+ // $pages = Mage::helper('searchanise/ApiPages')->generatePagesFeed($data, $store);
1564
+ // if (!empty($pages)) {
1565
+ // $dataForSend = array(
1566
+ // 'header' => $header,
1567
+ // 'pages' => $pages,
1568
+ // );
1569
+ // }
1570
+ // end fixme
1571
+ } elseif ($q['action'] == Simtech_Searchanise_Model_Queue::ACT_UPDATE_ATTRIBUTES) {
1572
+ $schema = null;
1573
+
1574
+ if ($data == Simtech_Searchanise_Model_Queue::DATA_CATEGORIES) {
1575
+ $schema = Mage::helper('searchanise/ApiProducts')->getSchemaCategories();
1576
 
1577
+ } elseif ($data == Simtech_Searchanise_Model_Queue::DATA_FACET_PRICES) {
1578
+ $schema = Mage::helper('searchanise/ApiProducts')->getSchemaPrices();
1579
+
1580
+ } elseif ($data == Simtech_Searchanise_Model_Queue::DATA_FACET_TAGS) {
1581
+ $schema = Mage::helper('searchanise/ApiProducts')->getSchemaTags();
1582
 
1583
+ } else {
1584
+ $schema = Mage::helper('searchanise/ApiProducts')->getSchema($data, $store);
1585
+ }
1586
+
1587
+ if (!empty($schema)) {
1588
+ $dataForSend = array(
1589
+ 'header' => $header,
1590
+ 'schema' => $schema,
1591
+ );
1592
  }
1593
  }
1594
+
1595
+ if (!empty($dataForSend)) {
1596
+ $dataForSend = Mage::helper('core')->jsonEncode($dataForSend, Zend_Json::TYPE_ARRAY);
1597
+
 
1598
  if (function_exists('gzcompress')) {
1599
+ $dataForSend = gzcompress($dataForSend, self::COMPRESS_RATE);
 
 
1600
  }
1601
+ $status = self::sendRequest('/api/items/update/json', $privateKey, array('data' => $dataForSend), true);
1602
  }
1603
 
1604
+ } elseif (Simtech_Searchanise_Model_Queue::isDeleteAction($q['action'])) {
1605
+ $type = Simtech_Searchanise_Model_Queue::getAPITypeByAction($q['action']);
1606
+ if ($type) {
1607
+ foreach ($data as $itemId) {
1608
+ $dataForSend = array();
1609
+ if ($q['action'] == Simtech_Searchanise_Model_Queue::ACT_DELETE_FACETS) {
1610
+ $dataForSend['attribute'] = $itemId;
1611
+ } else {
1612
+ $dataForSend['id'] = $itemId;
1613
+ }
1614
+ $status = self::sendRequest("/api/{$type}/delete/json", $privateKey, $dataForSend, true);
1615
+
1616
+ self::echoConnectProgress('.');
1617
+
1618
+ if ($status == false) {
1619
+ break;
1620
+ }
1621
  }
1622
  }
1623
+
 
 
 
1624
  } elseif ($q['action'] == Simtech_Searchanise_Model_Queue::ACT_PHRASE) {
1625
  foreach ($data as $phrase) {
1626
+ $status = self::sendRequest('/api/phrases/update/json', $privateKey, array('phrase' => $phrase), true);
1627
 
1628
  self::echoConnectProgress('.');
1629
 
1673
  if (!empty($stores)) {
1674
  foreach ($stores as $store) {
1675
  $privateKey = self::getPrivateKey($store);
1676
+ self::sendRequest('/api/state/update/json', $privateKey, array('addon_status' => $status), true);
1677
  }
1678
  }
1679
  }
1680
 
1681
  public static function sendRequest($urlPart, $privateKey, $data, $onlyHttp = true)
1682
  {
1683
+ $result = false;
1684
 
1685
  if (!empty($privateKey)) {
1686
  $params = array('private_key' => $privateKey) + $data;
1687
 
1688
+ list($h, $body) = self::httpRequest(Zend_Http_Client::POST, self::getServiceUrl($onlyHttp) . $urlPart, $params, array(), array(), self::getRequestTimeout());
1689
+
1690
+ if ($body) {
1691
+ $result = self::parseResponse($body, false);
1692
+ }
1693
 
1694
  self::setLastRequest(self::getTime());
1695
  }
1696
 
1697
+ return $result;
1698
  }
1699
 
1700
  /**
1701
  * Parse response from service
1702
  *
1703
+ * @param string $jsonData json service response
1704
+ * @return mixed false if errors returned, true if response is ok, object if data was passed in the response
1705
  */
1706
+ public static function parseResponse($jsonData, $showNotification = false, $objectDecodeType = Zend_Json::TYPE_ARRAY)
1707
  {
1708
+ $result = false;
1709
+ $data = false;
1710
+
1711
+ try {
1712
+ if (trim($jsonData) === 'CLOSED;' || trim($jsonData) === 'CLOSED') {
1713
+ $data = false;
1714
+ } else {
1715
+ $data = Mage::helper('core')->jsonDecode($jsonData, $objectDecodeType);
1716
+ }
1717
+ } catch (Exception $e) {
1718
+ if ($objectDecodeType == Zend_Json::TYPE_ARRAY) {
1719
+ return self::parseResponse($jsonData, $showNotification, Zend_Json::TYPE_OBJECT);
1720
+ }
1721
+ self::log('parseResponse : jsonDecode: ' . $e->getMessage());
1722
+ $data = false;
1723
  }
1724
+
1725
+ if (empty($data)) {
1726
+ $result = false;
1727
+ } elseif (is_array($data) && !empty($data['errors'])) {
1728
+ foreach ($data['errors'] as $e) {
1729
  if ($showNotification == true) {
1730
+ self::setNotification('E', Mage::helper('searchanise')->__('Error'), 'Searchanise: parseResponse: ' . $e->getMessage());
1731
  }
1732
+ self::log('parseResponse : ' . $e->getMessage());
1733
  }
1734
 
1735
+ $result = false;
1736
+ } elseif ($data === 'ok') {
1737
+ $result = true;
1738
  } else {
1739
+ $result = $data;
1740
  }
1741
+
1742
+ return $result;
1743
  }
1744
 
1745
+ public static function parseStateResponse($response)
1746
  {
1747
+ $result = array();
 
 
 
1748
 
1749
+ if (!empty($response['variable'])) {
1750
+ foreach ($response['variable'] as $name => $v) {
1751
+ $result[$name] = (string) $v;
1752
  }
 
 
 
 
 
 
1753
  }
1754
 
1755
+ return $result;
1756
  }
1757
 
1758
  public static function deleteKeys($stores = null)
1785
 
1786
  foreach ($stores as $store) {
1787
  if (self::getExportStatus($store) == self::EXPORT_STATUS_SENT && ((self::getTime() - self::getLastRequest()) > self::getRequestTimeout() || $skipTimeCheck == true)) {
1788
+ $response = self::sendRequest('/api/state/get/json', self::getPrivateKey($store), array('status' => '', 'full_import' => ''), true);
1789
+ $variable = self::parseStateResponse($response);
 
1790
 
1791
+ if ((!empty($variable)) && (isset($variable['status']))) {
1792
+ if (($variable['status'] == self::STATUS_NORMAL) &&
1793
+ (isset($variable['full_import'])) &&
1794
+ ($variable['full_import'] == self::EXPORT_STATUS_DONE)) {
1795
  $skipTimeCheck = true;
1796
  self::setExportStatus(self::EXPORT_STATUS_DONE, $store);
1797
 
1798
+ } elseif ($variable['status'] == self::STATUS_DISABLED) {
1799
  self::setExportStatus(self::EXPORT_STATUS_NONE, $store);
1800
  }
1801
  }
1811
 
1812
  return $result;
1813
  }
1814
+
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1815
  public static function getStoreByWebsiteIds($websiteIds = array())
1816
  {
1817
  $ret = array();
1888
  public static function log($message = '', $type = 'Error')
1889
  {
1890
  Mage::log("Searchanise # {$type}: {$message}");
1891
+ if (Mage::helper('searchanise')->checkDebug(true)) {
1892
+ Mage::helper('searchanise/ApiSe')->printR("Searchanise # {$type}: {$message}");
1893
+ }
1894
 
1895
  return true;
1896
  }
app/code/community/Simtech/Searchanise/Helper/Data.php CHANGED
@@ -14,6 +14,8 @@
14
 
15
  class Simtech_Searchanise_Helper_Data extends Mage_Core_Helper_Abstract
16
  {
 
 
17
  const DISABLE_VAR_NAME = 'disabled_module_searchanise';
18
  const DISABLE_KEY = 'Y';
19
 
@@ -25,8 +27,8 @@ class Simtech_Searchanise_Helper_Data extends Mage_Core_Helper_Abstract
25
  const VIEW_CATEGORY = 'VIEW_CATEGORY';
26
  const VIEW_TAG = 'VIEW_TAG';
27
 
28
- protected $_disableText = null;
29
- protected $_debugText = null;
30
 
31
  protected static $_searchaniseTypes = array(
32
  self::TEXT_FIND,
@@ -78,7 +80,7 @@ class Simtech_Searchanise_Helper_Data extends Mage_Core_Helper_Abstract
78
 
79
  public function getDisableText()
80
  {
81
- if (is_null($this->_disableText)) {
82
  $this->_disableText = $this->_getRequest()->getParam(self::DISABLE_VAR_NAME);
83
  }
84
 
@@ -92,16 +94,40 @@ class Simtech_Searchanise_Helper_Data extends Mage_Core_Helper_Abstract
92
 
93
  public function getDebugText()
94
  {
95
- if (is_null($this->_debugText)) {
96
  $this->_debugText = $this->_getRequest()->getParam(self::DEBUG_VAR_NAME);
97
  }
98
 
99
  return $this->_debugText;
100
  }
101
 
102
- public function checkDebug()
103
  {
104
- return ($this->getDebugText() == self::DEBUG_KEY) ? true : false;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
105
  }
106
 
107
  protected function setDefaultSort(&$params, $type)
@@ -116,15 +142,15 @@ class Simtech_Searchanise_Helper_Data extends Mage_Core_Helper_Abstract
116
  $params['sortOrder'] = 'desc';
117
 
118
  } elseif ($type == self::TEXT_ADVANCED_FIND) {
119
- $params['sortBy'] = 'title';
120
  $params['sortOrder'] = 'asc';
121
 
122
  } elseif ($type == self::VIEW_CATEGORY) {
123
- $params['sortBy'] = 'title';
124
  $params['sortOrder'] = 'asc';
125
 
126
  } elseif ($type == self::VIEW_TAG) {
127
- $params['sortBy'] = 'title';
128
  $params['sortOrder'] = 'asc';
129
  }
130
 
@@ -308,11 +334,7 @@ class Simtech_Searchanise_Helper_Data extends Mage_Core_Helper_Abstract
308
  }
309
 
310
  if ($sortBy) {
311
- if ($sortBy == 'name') {
312
- $params['sortBy'] = 'title';
313
- } else {
314
- $params['sortBy'] = $sortBy;
315
- }
316
  }
317
 
318
  if ($sortOrder) {
14
 
15
  class Simtech_Searchanise_Helper_Data extends Mage_Core_Helper_Abstract
16
  {
17
+ const PARENT_PRIVATE_KEY = 'parent_private_key';
18
+
19
  const DISABLE_VAR_NAME = 'disabled_module_searchanise';
20
  const DISABLE_KEY = 'Y';
21
 
27
  const VIEW_CATEGORY = 'VIEW_CATEGORY';
28
  const VIEW_TAG = 'VIEW_TAG';
29
 
30
+ protected $_disableText;
31
+ protected $_debugText;
32
 
33
  protected static $_searchaniseTypes = array(
34
  self::TEXT_FIND,
80
 
81
  public function getDisableText()
82
  {
83
+ if (!isset($this->_disableText)) {
84
  $this->_disableText = $this->_getRequest()->getParam(self::DISABLE_VAR_NAME);
85
  }
86
 
94
 
95
  public function getDebugText()
96
  {
97
+ if (!isset($this->_debugText)) {
98
  $this->_debugText = $this->_getRequest()->getParam(self::DEBUG_VAR_NAME);
99
  }
100
 
101
  return $this->_debugText;
102
  }
103
 
104
+ public function checkDebug($checkPrivateKey = false)
105
  {
106
+ $checkDebug = ($this->getDebugText() == self::DEBUG_KEY) ? true : false;
107
+
108
+ if ($checkDebug && $checkPrivateKey) {
109
+ $checkDebug = $checkDebug && $this->checkPrivateKey();
110
+ }
111
+
112
+ return $checkDebug;
113
+ }
114
+
115
+ public function checkPrivateKey()
116
+ {
117
+ static $check;
118
+
119
+ if (!isset($check)) {
120
+ $parentPrivateKey = $this->_getRequest()->getParam(self::PARENT_PRIVATE_KEY);
121
+
122
+ if ((empty($parentPrivateKey)) ||
123
+ (Mage::helper('searchanise/ApiSe')->getParentPrivateKey() !== $parentPrivateKey)) {
124
+ $check = false;
125
+ } else {
126
+ $check = true;
127
+ }
128
+ }
129
+
130
+ return $check;
131
  }
132
 
133
  protected function setDefaultSort(&$params, $type)
142
  $params['sortOrder'] = 'desc';
143
 
144
  } elseif ($type == self::TEXT_ADVANCED_FIND) {
145
+ $params['sortBy'] = 'name';
146
  $params['sortOrder'] = 'asc';
147
 
148
  } elseif ($type == self::VIEW_CATEGORY) {
149
+ $params['sortBy'] = 'name';
150
  $params['sortOrder'] = 'asc';
151
 
152
  } elseif ($type == self::VIEW_TAG) {
153
+ $params['sortBy'] = 'name';
154
  $params['sortOrder'] = 'asc';
155
  }
156
 
334
  }
335
 
336
  if ($sortBy) {
337
+ $params['sortBy'] = $sortBy;
 
 
 
 
338
  }
339
 
340
  if ($sortOrder) {
app/code/community/Simtech/Searchanise/Model/Advanced.php CHANGED
@@ -14,6 +14,27 @@
14
 
15
  class Simtech_Searchanise_Model_Advanced extends Mage_CatalogSearch_Model_Advanced
16
  {
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
17
  /**
18
  * Prepare product collection
19
  *
@@ -30,7 +51,7 @@ class Simtech_Searchanise_Model_Advanced extends Mage_CatalogSearch_Model_Advanc
30
  $collection->setSearchaniseRequest(Mage::helper('searchanise')->getSearchaniseRequest());
31
  }
32
 
33
- if ((!method_exists($collection, 'checkSearchaniseResult')) || (!$collection->checkSearchaniseResult())) {
34
  return parent::prepareProductCollection($collection);
35
  }
36
 
14
 
15
  class Simtech_Searchanise_Model_Advanced extends Mage_CatalogSearch_Model_Advanced
16
  {
17
+ /**
18
+ * Add advanced search filters to product collection
19
+ *
20
+ * @param array $values
21
+ * @return Mage_CatalogSearch_Model_Advanced
22
+ */
23
+ public function addFilters($values)
24
+ {
25
+ if (!Mage::helper('searchanise/ApiSe')->checkSearchaniseResult(true)) {
26
+ return parent::addFilters($values);
27
+ }
28
+ $collection = $this->getProductCollection();
29
+
30
+ if (!$collection && !method_exists($collection, 'checkSearchaniseResult') || !$collection->checkSearchaniseResult()) {
31
+ return parent::addFilters($values);
32
+ }
33
+ // Nothing,
34
+
35
+ return $this;
36
+ }
37
+
38
  /**
39
  * Prepare product collection
40
  *
51
  $collection->setSearchaniseRequest(Mage::helper('searchanise')->getSearchaniseRequest());
52
  }
53
 
54
+ if (!$collection && !method_exists($collection, 'checkSearchaniseResult') || !$collection->checkSearchaniseResult()) {
55
  return parent::prepareProductCollection($collection);
56
  }
57
 
app/code/community/Simtech/Searchanise/Model/Observer.php CHANGED
@@ -14,8 +14,8 @@
14
 
15
  class Simtech_Searchanise_Model_Observer
16
  {
17
- protected static $newAttributes = array();
18
  protected static $productIdsInCategory = array();
 
19
 
20
  public function __construct()
21
  {
@@ -122,7 +122,7 @@ class Simtech_Searchanise_Model_Observer
122
 
123
  if (!empty($storeIds)) {
124
  foreach ($storeIds as $k => $storeId) {
125
- Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_UPDATE, $product->getId(), null, $storeId);
126
  }
127
  }
128
  }
@@ -149,7 +149,7 @@ class Simtech_Searchanise_Model_Observer
149
  foreach ($productIds as $k => $productId) {
150
  if ($action == 'add') {
151
  foreach ($storeIds as $k => $storeId) {
152
- Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_UPDATE, $productId, null, $storeId);
153
  }
154
 
155
  } elseif ($action == 'remove') {
@@ -162,7 +162,7 @@ class Simtech_Searchanise_Model_Observer
162
  if (!empty($storeIdsOld)) {
163
  foreach ($storeIds as $k => $storeId) {
164
  if (in_array($storeId, $storeIdsOld)) {
165
- Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_DELETE, $productId, null, $storeId);
166
  }
167
  }
168
  }
@@ -175,6 +175,27 @@ class Simtech_Searchanise_Model_Observer
175
  }
176
 
177
  // FOR CATEGORIES //
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
178
  /**
179
  * Save category before
180
  *
@@ -184,14 +205,20 @@ class Simtech_Searchanise_Model_Observer
184
  public function catalogCategorySaveBefore(Varien_Event_Observer $observer)
185
  {
186
  $category = $observer->getEvent()->getCategory();
187
-
188
  if ($category && $category->getId()) {
 
 
 
 
 
 
189
  $products = $category->getProductCollection();
190
  Mage::getModel('searchanise/queue')->addActionProducts($products);
191
 
192
  // save current products ids
193
  // need for find new products in catalogCategorySaveAfter
194
- if (!empty($products)) {
195
  self::$productIdsInCategory = array();
196
 
197
  foreach ($products as $product) {
@@ -214,8 +241,14 @@ class Simtech_Searchanise_Model_Observer
214
  public function catalogCategorySaveAfter(Varien_Event_Observer $observer)
215
  {
216
  $category = $observer->getEvent()->getCategory();
217
-
218
  if ($category && $category->getId()) {
 
 
 
 
 
 
219
  $products = $category->getProductCollection();
220
 
221
  if (!empty($products)) {
@@ -234,6 +267,8 @@ class Simtech_Searchanise_Model_Observer
234
  }
235
  }
236
  }
 
 
237
 
238
  return $this;
239
  }
@@ -250,21 +285,8 @@ class Simtech_Searchanise_Model_Observer
250
 
251
  if ($category && $category->getId()) {
252
  $products = $category->getProductCollection();
253
-
254
- if (!empty($products)) {
255
- if (empty(self::$productIdsInCategory)) {
256
- Mage::getModel('searchanise/queue')->addActionProducts($products);
257
- } else {
258
- $productIds = array();
259
- foreach ($products as $product) {
260
- $id = $product->getId();
261
- if ((!empty($id)) && (!in_array($id, self::$productIdsInCategory))) {
262
- $productIds[] = $id;
263
- }
264
- }
265
-
266
- Mage::getModel('searchanise/queue')->addActionProductIds($productIds);
267
- }
268
  }
269
  }
270
 
@@ -310,7 +332,7 @@ class Simtech_Searchanise_Model_Observer
310
  }
311
 
312
  if (!empty($productIds)) {
313
- Mage::getModel('searchanise/queue')->addActionProductIds($productIds , Simtech_Searchanise_Model_Queue::ACT_UPDATE);
314
  }
315
  }
316
 
@@ -328,7 +350,7 @@ class Simtech_Searchanise_Model_Observer
328
  $idToDelete = $observer->getData('idToDelete');
329
 
330
  if (!empty($idToDelete)) {
331
- Mage::getModel('searchanise/queue')->addActionProductIds($idToDelete, Simtech_Searchanise_Model_Queue::ACT_DELETE);
332
  }
333
 
334
  return $this;
@@ -504,12 +526,10 @@ class Simtech_Searchanise_Model_Observer
504
 
505
  if (!empty($stores)) {
506
  if ($section == 'catalog') {
507
- foreach ($stores as $k => $store) {
508
- $filters = Mage::helper('searchanise/ApiSe')->getPriceFilters($store);
509
-
510
- if (!empty($filters)) {
511
- foreach ($filters as $filter) {
512
- Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_FACET_UPDATE, $filter->getId(), $store);
513
  }
514
  }
515
 
@@ -517,7 +537,7 @@ class Simtech_Searchanise_Model_Observer
517
  {
518
  $queueData = array(
519
  'data' => serialize(Simtech_Searchanise_Model_Queue::DATA_FACET_PRICES),
520
- 'action' => Simtech_Searchanise_Model_Queue::ACT_FACET_UPDATE,
521
  'store_id' => $store->getId(),
522
  );
523
 
@@ -546,36 +566,27 @@ class Simtech_Searchanise_Model_Observer
546
  $attribute = $observer->getEvent()->getAttribute();
547
 
548
  if ($attribute && $attribute->getId()) {
549
- $flFacet = Mage::helper('searchanise/ApiXML')->checkFacet($attribute);
550
 
551
- $flFacetOld = null;
552
 
553
- $attributeOld = Mage::getModel('catalog/entity_attribute')
554
  ->load($attribute->getId());
555
 
556
- if (!empty($attributeOld)) {
557
- $flFacetOld = Mage::helper('searchanise/ApiXML')->checkFacet($attributeOld);
558
  }
559
 
560
- if ($flFacet != $flFacetOld) {
561
- if ($flFacet) {
562
- Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_FACET_UPDATE, $attribute->getId());
563
- } else {
564
- Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_FACET_DELETE, $attribute->getId());
565
  }
566
  }
567
  }
568
 
569
- if (($attribute) && (!$attribute->getId())) {
570
- self::$newAttributes[$attribute->getData('attribute_code')] = true;
571
- } else {
572
- // uncomment if need this checking
573
- // self::$newAttributes[$attribute->getData('attribute_code')] = false;
574
- }
575
-
576
  return $this;
577
  }
578
-
579
  /**
580
  * Save attribute
581
  *
@@ -587,18 +598,7 @@ class Simtech_Searchanise_Model_Observer
587
  $attribute = $observer->getEvent()->getAttribute();
588
 
589
  if ($attribute && $attribute->getId()) {
590
- $attributeCode = $attribute->getData('attribute_code');
591
-
592
- if ((!empty(self::$newAttributes)) &&
593
- (array_key_exists($attributeCode, self::$newAttributes)) &&
594
- (self::$newAttributes[$attributeCode])) {
595
- $flFacet = Mage::helper('searchanise/ApiXML')->checkFacet($attribute);
596
-
597
-
598
- if ($flFacet) {
599
- Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_FACET_UPDATE, $attribute->getId());
600
- }
601
- }
602
  }
603
 
604
  return $this;
@@ -615,10 +615,8 @@ class Simtech_Searchanise_Model_Observer
615
  $attribute = $observer->getEvent()->getAttribute();
616
 
617
  if ($attribute && $attribute->getId()) {
618
- $flFacet = Mage::helper('searchanise/ApiXML')->checkFacet($attribute);
619
-
620
- if ($flFacet) {
621
- Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_FACET_DELETE, $attribute->getId());
622
  }
623
  }
624
 
@@ -639,7 +637,7 @@ class Simtech_Searchanise_Model_Observer
639
  if (!empty($tag)) {
640
  $productIds = $tag->getRelatedProductIds();
641
 
642
- Mage::getModel('searchanise/queue')->addActionProductIds($productIds, Simtech_Searchanise_Model_Queue::ACT_UPDATE);
643
  }
644
 
645
  return $this;
@@ -658,7 +656,7 @@ class Simtech_Searchanise_Model_Observer
658
  if (!empty($tag)) {
659
  $productIds = $tag->getRelatedProductIds();
660
 
661
- Mage::getModel('searchanise/queue')->addActionProductIds($productIds, Simtech_Searchanise_Model_Queue::ACT_UPDATE);
662
  }
663
 
664
  return $this;
@@ -684,7 +682,7 @@ class Simtech_Searchanise_Model_Observer
684
  if (!empty($tag)) {
685
  $productIds = $tag->getRelatedProductIds();
686
 
687
- Mage::getModel('searchanise/queue')->addActionProductIds($productIds, Simtech_Searchanise_Model_Queue::ACT_UPDATE);
688
  }
689
  }
690
 
14
 
15
  class Simtech_Searchanise_Model_Observer
16
  {
 
17
  protected static $productIdsInCategory = array();
18
+ protected static $isExistsCategory = false;
19
 
20
  public function __construct()
21
  {
122
 
123
  if (!empty($storeIds)) {
124
  foreach ($storeIds as $k => $storeId) {
125
+ Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_UPDATE_PRODUCTS, $product->getId(), null, $storeId);
126
  }
127
  }
128
  }
149
  foreach ($productIds as $k => $productId) {
150
  if ($action == 'add') {
151
  foreach ($storeIds as $k => $storeId) {
152
+ Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_UPDATE_PRODUCTS, $productId, null, $storeId);
153
  }
154
 
155
  } elseif ($action == 'remove') {
162
  if (!empty($storeIdsOld)) {
163
  foreach ($storeIds as $k => $storeId) {
164
  if (in_array($storeId, $storeIdsOld)) {
165
+ Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_DELETE_PRODUCTS, $productId, null, $storeId);
166
  }
167
  }
168
  }
175
  }
176
 
177
  // FOR CATEGORIES //
178
+ /**
179
+ * Delete category before
180
+ *
181
+ * @param Varien_Event_Observer $observer
182
+ * @return Mage_CatalogIndex_Model_Observer
183
+ */
184
+ public function catalogCategoryDeleteBefore(Varien_Event_Observer $observer)
185
+ {
186
+ $category = $observer->getEvent()->getCategory();
187
+
188
+ if ($category && $category->getId()) {
189
+ // For category
190
+ Mage::getModel('searchanise/queue')->addActionCategory($category, Simtech_Searchanise_Model_Queue::ACT_DELETE_CATEGORIES);
191
+
192
+ // For products from category
193
+ $products = $category->getProductCollection();
194
+ }
195
+
196
+ return $this;
197
+ }
198
+
199
  /**
200
  * Save category before
201
  *
205
  public function catalogCategorySaveBefore(Varien_Event_Observer $observer)
206
  {
207
  $category = $observer->getEvent()->getCategory();
208
+
209
  if ($category && $category->getId()) {
210
+ self::$isExistsCategory = true; // New category doesn't run the catalogCategorySaveBefore function.
211
+ // For category
212
+ Mage::getModel('searchanise/queue')->addActionCategory($category);
213
+
214
+ // For products from category
215
+ // It save before because products could remove from $category.
216
  $products = $category->getProductCollection();
217
  Mage::getModel('searchanise/queue')->addActionProducts($products);
218
 
219
  // save current products ids
220
  // need for find new products in catalogCategorySaveAfter
221
+ if ($products) {
222
  self::$productIdsInCategory = array();
223
 
224
  foreach ($products as $product) {
241
  public function catalogCategorySaveAfter(Varien_Event_Observer $observer)
242
  {
243
  $category = $observer->getEvent()->getCategory();
244
+
245
  if ($category && $category->getId()) {
246
+ // For category
247
+ if (!self::$isExistsCategory) { // if category was created now
248
+ Mage::getModel('searchanise/queue')->addActionCategory($category);
249
+ }
250
+
251
+ // For products from category
252
  $products = $category->getProductCollection();
253
 
254
  if (!empty($products)) {
267
  }
268
  }
269
  }
270
+ self::$isExistsCategory = false;
271
+ self::$productIdsInCategory = array();
272
 
273
  return $this;
274
  }
285
 
286
  if ($category && $category->getId()) {
287
  $products = $category->getProductCollection();
288
+ if ($products) {
289
+ Mage::getModel('searchanise/queue')->addActionProducts($products);
 
 
 
 
 
 
 
 
 
 
 
 
 
290
  }
291
  }
292
 
332
  }
333
 
334
  if (!empty($productIds)) {
335
+ Mage::getModel('searchanise/queue')->addActionProductIds($productIds , Simtech_Searchanise_Model_Queue::ACT_UPDATE_PRODUCTS);
336
  }
337
  }
338
 
350
  $idToDelete = $observer->getData('idToDelete');
351
 
352
  if (!empty($idToDelete)) {
353
+ Mage::getModel('searchanise/queue')->addActionProductIds($idToDelete, Simtech_Searchanise_Model_Queue::ACT_DELETE_PRODUCTS);
354
  }
355
 
356
  return $this;
526
 
527
  if (!empty($stores)) {
528
  if ($section == 'catalog') {
529
+ foreach ($stores as $k => $store) {
530
+ if ($attributes = Mage::helper('searchanise/ApiProducts')->getProductAttributes(null, $store, true)) {
531
+ foreach ($attributes as $attribute) {
532
+ Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_UPDATE_ATTRIBUTES, $attribute->getId(), $store);
 
 
533
  }
534
  }
535
 
537
  {
538
  $queueData = array(
539
  'data' => serialize(Simtech_Searchanise_Model_Queue::DATA_FACET_PRICES),
540
+ 'action' => Simtech_Searchanise_Model_Queue::ACT_UPDATE_ATTRIBUTES,
541
  'store_id' => $store->getId(),
542
  );
543
 
566
  $attribute = $observer->getEvent()->getAttribute();
567
 
568
  if ($attribute && $attribute->getId()) {
569
+ $isFacet = Mage::helper('searchanise/ApiProducts')->isFacet($attribute);
570
 
571
+ $isFacetPrev = null;
572
 
573
+ $prevAttribute = Mage::getModel('catalog/entity_attribute')
574
  ->load($attribute->getId());
575
 
576
+ if ($prevAttribute) {
577
+ $isFacetPrev = Mage::helper('searchanise/ApiProducts')->isFacet($prevAttribute);
578
  }
579
 
580
+ if ($isFacet != $isFacetPrev) {
581
+ if (!$isFacet) {
582
+ Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_DELETE_FACETS, $attribute->getId());
 
 
583
  }
584
  }
585
  }
586
 
 
 
 
 
 
 
 
587
  return $this;
588
  }
589
+
590
  /**
591
  * Save attribute
592
  *
598
  $attribute = $observer->getEvent()->getAttribute();
599
 
600
  if ($attribute && $attribute->getId()) {
601
+ Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_UPDATE_ATTRIBUTES, $attribute->getId());
 
 
 
 
 
 
 
 
 
 
 
602
  }
603
 
604
  return $this;
615
  $attribute = $observer->getEvent()->getAttribute();
616
 
617
  if ($attribute && $attribute->getId()) {
618
+ if (Mage::helper('searchanise/ApiProducts')->isFacet($attribute)) {
619
+ Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_DELETE_FACETS, $attribute->getId());
 
 
620
  }
621
  }
622
 
637
  if (!empty($tag)) {
638
  $productIds = $tag->getRelatedProductIds();
639
 
640
+ Mage::getModel('searchanise/queue')->addActionProductIds($productIds, Simtech_Searchanise_Model_Queue::ACT_UPDATE_PRODUCTS);
641
  }
642
 
643
  return $this;
656
  if (!empty($tag)) {
657
  $productIds = $tag->getRelatedProductIds();
658
 
659
+ Mage::getModel('searchanise/queue')->addActionProductIds($productIds, Simtech_Searchanise_Model_Queue::ACT_UPDATE_PRODUCTS);
660
  }
661
 
662
  return $this;
682
  if (!empty($tag)) {
683
  $productIds = $tag->getRelatedProductIds();
684
 
685
+ Mage::getModel('searchanise/queue')->addActionProductIds($productIds, Simtech_Searchanise_Model_Queue::ACT_UPDATE_PRODUCTS);
686
  }
687
  }
688
 
app/code/community/Simtech/Searchanise/Model/Queue.php CHANGED
@@ -17,24 +17,36 @@ class Simtech_Searchanise_Model_Queue extends Mage_Core_Model_Abstract
17
  const NOT_DATA = 'N';
18
  const DATA_FACET_TAGS = 'facet_tags';
19
  const DATA_FACET_PRICES = 'facet_prices';
20
- const DATA_FACET_CATEGORIES = 'facet_categories';
 
21
 
22
  public static $dataTypes = array(
23
  self::DATA_FACET_TAGS,
24
  self::DATA_FACET_PRICES,
25
- self::DATA_FACET_CATEGORIES,
26
  );
27
 
28
- const ACT_PHRASE = 'phrase';
29
- const ACT_UPDATE = 'update';
30
- const ACT_DELETE = 'delete';
31
- const ACT_DELETE_ALL = 'delete';
32
- const ACT_FACET_UPDATE = 'facet_update';
33
- const ACT_FACET_DELETE = 'facet_delete';
34
- const ACT_FACET_DELETE_ALL = 'facet_delete_all';
35
- const ACT_PREPARE_FULL_IMPORT = 'prepare_full_import';
36
- const ACT_START_FULL_IMPORT = 'start_full_import';
37
- const ACT_END_FULL_IMPORT = 'end_full_import';
 
 
 
 
 
 
 
 
 
 
 
38
 
39
  public static $mainActionTypes = array(
40
  self::ACT_PREPARE_FULL_IMPORT,
@@ -44,12 +56,23 @@ class Simtech_Searchanise_Model_Queue extends Mage_Core_Model_Abstract
44
 
45
  public static $actionTypes = array(
46
  self::ACT_PHRASE,
47
- self::ACT_UPDATE,
48
- self::ACT_DELETE,
49
- self::ACT_DELETE_ALL,
50
- self::ACT_FACET_UPDATE,
51
- self::ACT_FACET_DELETE,
52
- self::ACT_FACET_DELETE_ALL,
 
 
 
 
 
 
 
 
 
 
 
53
  self::ACT_PREPARE_FULL_IMPORT,
54
  self::ACT_START_FULL_IMPORT,
55
  self::ACT_END_FULL_IMPORT,
@@ -69,10 +92,74 @@ class Simtech_Searchanise_Model_Queue extends Mage_Core_Model_Abstract
69
  {
70
  $this->_init('searchanise/queue');
71
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
72
 
73
- public function deleteKeys($cur_store = null)
74
  {
75
- $stores = Mage::helper('searchanise/ApiSe')->getStores($cur_store);
76
 
77
  foreach ($stores as $k_store => $store) {
78
  $queue = Mage::getModel('searchanise/queue')->getCollection()->addFilter('store_id', $store->getId())->toArray();
@@ -147,7 +234,7 @@ class Simtech_Searchanise_Model_Queue extends Mage_Core_Model_Abstract
147
  return $collection->load()->delete();
148
  }
149
 
150
- public function addAction($action, $data = NULL, $cur_store = null, $cur_store_id = null)
151
  {
152
  if (in_array($action, self::$actionTypes))
153
  {
@@ -158,11 +245,11 @@ class Simtech_Searchanise_Model_Queue extends Mage_Core_Model_Abstract
158
  $data = serialize((array)$data);
159
  $data = array($data);
160
 
161
- $stores = Mage::helper('searchanise/ApiSe')->getStores($cur_store, $cur_store_id);
162
 
163
- if ($action == self::ACT_PREPARE_FULL_IMPORT && !empty($cur_store)) {
164
  // Truncate queue for all
165
- Mage::getModel('searchanise/queue')->clearActions($cur_store);
166
  }
167
 
168
  foreach ($data as $d) {
@@ -200,6 +287,40 @@ class Simtech_Searchanise_Model_Queue extends Mage_Core_Model_Abstract
200
 
201
  return false;
202
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
203
 
204
  public function addActionProducts($products)
205
  {
@@ -211,20 +332,20 @@ class Simtech_Searchanise_Model_Queue extends Mage_Core_Model_Abstract
211
  $productIds[] = $product->getId();
212
  }
213
  if (count($productIds) >= Mage::helper('searchanise/ApiSe')->getProductsPerPass()) {
214
- Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_UPDATE, $productIds);
215
  $productIds = array();
216
  }
217
  }
218
 
219
  if ((!empty($productIds)) && (count($productIds) > 0)) {
220
- Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_UPDATE, $productIds);
221
  }
222
  }
223
 
224
  return $this;
225
  }
226
 
227
- public function addActionProductIdsForAllStore($productIds, $action = self::ACT_UPDATE)
228
  {
229
  if (!empty($productIds)) {
230
  if (count($productIds) <= Mage::helper('searchanise/ApiSe')->getProductsPerPass()) {
@@ -251,7 +372,7 @@ class Simtech_Searchanise_Model_Queue extends Mage_Core_Model_Abstract
251
  return $this;
252
  }
253
 
254
- public function addActionProductIds($productIds, $action = self::ACT_UPDATE)
255
  {
256
  if (!empty($productIds)) {
257
  if (!is_array($productIds)) {
@@ -265,7 +386,7 @@ class Simtech_Searchanise_Model_Queue extends Mage_Core_Model_Abstract
265
 
266
  if ($product) {
267
  $storeIds = $product->getStoreIds();
268
- Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_UPDATE, $productId, null, $storeIds);
269
  }
270
  }
271
  }
@@ -283,13 +404,13 @@ class Simtech_Searchanise_Model_Queue extends Mage_Core_Model_Abstract
283
  $productIds[] = $item->getProductId();
284
  }
285
  if (count($productIds) >= Mage::helper('searchanise/ApiSe')->getProductsPerPass()) {
286
- Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_UPDATE, $productIds, null, $item->getStoreId());
287
  $productIds = array();
288
  }
289
  }
290
 
291
  if (!empty($productIds)) {
292
- Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_UPDATE, $productIds, null, $item->getStoreId());
293
  }
294
  }
295
 
@@ -310,7 +431,7 @@ class Simtech_Searchanise_Model_Queue extends Mage_Core_Model_Abstract
310
  if (!empty($storeIdsOld)) {
311
  foreach ($storeIdsOld as $k => $storeIdOld) {
312
  if ((empty($storeIds)) || (!in_array($storeIdOld, $storeIds))) {
313
- $this->addAction(Simtech_Searchanise_Model_Queue::ACT_DELETE, $product->getId(), null, $storeIdOld);
314
  }
315
  }
316
  }
@@ -327,7 +448,7 @@ class Simtech_Searchanise_Model_Queue extends Mage_Core_Model_Abstract
327
 
328
  if (!empty($storeIds)) {
329
  foreach ($storeIds as $k => $storeId) {
330
- $this->addAction(Simtech_Searchanise_Model_Queue::ACT_DELETE, $product->getId(), null, $storeId);
331
  }
332
  }
333
  }
@@ -350,7 +471,7 @@ class Simtech_Searchanise_Model_Queue extends Mage_Core_Model_Abstract
350
 
351
  if (!empty($storeIds)) {
352
  foreach ($storeIds as $k => $storeId) {
353
- $this->addAction(Simtech_Searchanise_Model_Queue::ACT_UPDATE, $product->getId(), null, $storeId);
354
  }
355
  }
356
  }
17
  const NOT_DATA = 'N';
18
  const DATA_FACET_TAGS = 'facet_tags';
19
  const DATA_FACET_PRICES = 'facet_prices';
20
+
21
+ const DATA_CATEGORIES = 'categories';
22
 
23
  public static $dataTypes = array(
24
  self::DATA_FACET_TAGS,
25
  self::DATA_FACET_PRICES,
26
+ self::DATA_CATEGORIES,
27
  );
28
 
29
+ const ACT_PHRASE = 'phrase';
30
+
31
+ const ACT_UPDATE_PAGES = 'update_pages';
32
+ const ACT_UPDATE_PRODUCTS = 'update_products';
33
+ const ACT_UPDATE_ATTRIBUTES = 'update_attributes';
34
+ const ACT_UPDATE_CATEGORIES = 'update_categories';
35
+
36
+ const ACT_DELETE_PAGES = 'delete_pages';
37
+ const ACT_DELETE_PAGES_ALL = 'delete_pages_all';
38
+ const ACT_DELETE_PRODUCTS = 'delete_products';
39
+ const ACT_DELETE_PRODUCTS_ALL = 'delete_products_all';
40
+ const ACT_DELETE_FACETS = 'delete_facets';
41
+ const ACT_DELETE_FACETS_ALL = 'delete_facets_all';
42
+ const ACT_DELETE_ATTRIBUTES = 'delete_attributes'; // not used
43
+ const ACT_DELETE_ATTRIBUTES_ALL = 'delete_attributes_all'; // not used
44
+ const ACT_DELETE_CATEGORIES = 'delete_categories';
45
+ const ACT_DELETE_CATEGORIES_ALL = 'delete_categories_all';
46
+
47
+ const ACT_PREPARE_FULL_IMPORT = 'prepare_full_import';
48
+ const ACT_START_FULL_IMPORT = 'start_full_import';
49
+ const ACT_END_FULL_IMPORT = 'end_full_import';
50
 
51
  public static $mainActionTypes = array(
52
  self::ACT_PREPARE_FULL_IMPORT,
56
 
57
  public static $actionTypes = array(
58
  self::ACT_PHRASE,
59
+
60
+ self::ACT_UPDATE_PAGES,
61
+ self::ACT_UPDATE_PRODUCTS,
62
+ self::ACT_UPDATE_CATEGORIES,
63
+ self::ACT_UPDATE_ATTRIBUTES,
64
+
65
+ self::ACT_DELETE_PAGES,
66
+ self::ACT_DELETE_PAGES_ALL,
67
+ self::ACT_DELETE_PRODUCTS,
68
+ self::ACT_DELETE_PRODUCTS_ALL,
69
+ self::ACT_DELETE_FACETS,
70
+ self::ACT_DELETE_FACETS_ALL,
71
+ self::ACT_DELETE_ATTRIBUTES,
72
+ self::ACT_DELETE_ATTRIBUTES_ALL,
73
+ self::ACT_DELETE_CATEGORIES,
74
+ self::ACT_DELETE_CATEGORIES_ALL,
75
+
76
  self::ACT_PREPARE_FULL_IMPORT,
77
  self::ACT_START_FULL_IMPORT,
78
  self::ACT_END_FULL_IMPORT,
92
  {
93
  $this->_init('searchanise/queue');
94
  }
95
+
96
+ public static function isUpdateAction($action)
97
+ {
98
+ $isUpdate = false;
99
+
100
+ if ($action == Simtech_Searchanise_Model_Queue::ACT_UPDATE_PAGES ||
101
+ $action == Simtech_Searchanise_Model_Queue::ACT_UPDATE_PRODUCTS ||
102
+ $action == Simtech_Searchanise_Model_Queue::ACT_UPDATE_ATTRIBUTES ||
103
+ $action == Simtech_Searchanise_Model_Queue::ACT_UPDATE_CATEGORIES) {
104
+ $isUpdate = true;
105
+ }
106
+
107
+ return $isUpdate;
108
+ }
109
+
110
+ public static function isDeleteAction($action)
111
+ {
112
+ $isDelete = false;
113
+
114
+ if ($action == Simtech_Searchanise_Model_Queue::ACT_DELETE_PAGES ||
115
+ $action == Simtech_Searchanise_Model_Queue::ACT_DELETE_PRODUCTS ||
116
+ $action == Simtech_Searchanise_Model_Queue::ACT_DELETE_ATTRIBUTES ||
117
+ $action == Simtech_Searchanise_Model_Queue::ACT_DELETE_FACETS ||
118
+ $action == Simtech_Searchanise_Model_Queue::ACT_DELETE_CATEGORIES) {
119
+ $isDelete = true;
120
+ }
121
+
122
+ return $isDelete;
123
+ }
124
+ public static function isDeleteAllAction($action)
125
+ {
126
+ $isDeleteAll = false;
127
+
128
+ if ($action == Simtech_Searchanise_Model_Queue::ACT_DELETE_PAGES_ALL ||
129
+ $action == Simtech_Searchanise_Model_Queue::ACT_DELETE_PRODUCTS_ALL ||
130
+ $action == Simtech_Searchanise_Model_Queue::ACT_DELETE_ATTRIBUTES_ALL ||
131
+ $action == Simtech_Searchanise_Model_Queue::ACT_DELETE_FACETS_ALL ||
132
+ $action == Simtech_Searchanise_Model_Queue::ACT_DELETE_CATEGORIES_ALL) {
133
+ $isDeleteAll = true;
134
+ }
135
+
136
+ return $isDeleteAll;
137
+ }
138
+
139
+ public static function getAPITypeByAction($action)
140
+ {
141
+ $type = '';
142
+
143
+ if ($action == Simtech_Searchanise_Model_Queue::ACT_DELETE_PRODUCTS ||
144
+ $action == Simtech_Searchanise_Model_Queue::ACT_DELETE_PRODUCTS_ALL) {
145
+ $type = 'items';
146
+ } elseif ($action == Simtech_Searchanise_Model_Queue::ACT_DELETE_CATEGORIES ||
147
+ $action == Simtech_Searchanise_Model_Queue::ACT_DELETE_CATEGORIES_ALL) {
148
+ $type = 'categories';
149
+ } elseif ($action == Simtech_Searchanise_Model_Queue::ACT_DELETE_PAGES ||
150
+ $action == Simtech_Searchanise_Model_Queue::ACT_DELETE_PAGES_ALL) {
151
+ $type = 'pages';
152
+ } elseif ($action == Simtech_Searchanise_Model_Queue::ACT_DELETE_FACETS ||
153
+ $action == Simtech_Searchanise_Model_Queue::ACT_DELETE_FACETS_ALL) {
154
+ $type = 'facets';
155
+ }
156
+
157
+ return $type;
158
+ }
159
 
160
+ public function deleteKeys($curStore = null)
161
  {
162
+ $stores = Mage::helper('searchanise/ApiSe')->getStores($curStore);
163
 
164
  foreach ($stores as $k_store => $store) {
165
  $queue = Mage::getModel('searchanise/queue')->getCollection()->addFilter('store_id', $store->getId())->toArray();
234
  return $collection->load()->delete();
235
  }
236
 
237
+ public function addAction($action, $data = NULL, $curStore = null, $curStoreId = null)
238
  {
239
  if (in_array($action, self::$actionTypes))
240
  {
245
  $data = serialize((array)$data);
246
  $data = array($data);
247
 
248
+ $stores = Mage::helper('searchanise/ApiSe')->getStores($curStore, $curStoreId);
249
 
250
+ if ($action == self::ACT_PREPARE_FULL_IMPORT && !empty($curStore)) {
251
  // Truncate queue for all
252
+ Mage::getModel('searchanise/queue')->clearActions($curStore);
253
  }
254
 
255
  foreach ($data as $d) {
287
 
288
  return false;
289
  }
290
+
291
+ public function addActionCategory($category, $action = Simtech_Searchanise_Model_Queue::ACT_UPDATE_CATEGORIES)
292
+ {
293
+ if ($category) {
294
+ // Fixme in the future
295
+ // need get $currentIsActive for all stores because each store can have his value of IsActive for category.
296
+ $currentIsActive = $category->getIsActive();
297
+ $storeId = $category->getStoreId();
298
+
299
+ if ($currentIsActive) {
300
+ // Delete need for all stores
301
+ if ($action == Simtech_Searchanise_Model_Queue::ACT_DELETE_CATEGORIES) {
302
+ $storeId = null;
303
+ }
304
+ Mage::getModel('searchanise/queue')->addAction($action, $category->getId(), null, $storeId);
305
+
306
+ } elseif ($action == Simtech_Searchanise_Model_Queue::ACT_UPDATE_CATEGORIES) {
307
+ $prevCategory = Mage::getModel('catalog/category')
308
+ ->setStoreId($category->getStoreId())
309
+ ->load($category->getId());
310
+ if ($prevCategory) {
311
+ $prevIsActive = $prevCategory->getIsActive();
312
+ if ($prevIsActive != $currentIsActive) {
313
+ // Delete need for all stores
314
+ Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_DELETE_CATEGORIES, $category->getId());
315
+ }
316
+ }
317
+
318
+ }
319
+ // end fixme
320
+ }
321
+
322
+ return true;
323
+ }
324
 
325
  public function addActionProducts($products)
326
  {
332
  $productIds[] = $product->getId();
333
  }
334
  if (count($productIds) >= Mage::helper('searchanise/ApiSe')->getProductsPerPass()) {
335
+ Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_UPDATE_PRODUCTS, $productIds);
336
  $productIds = array();
337
  }
338
  }
339
 
340
  if ((!empty($productIds)) && (count($productIds) > 0)) {
341
+ Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_UPDATE_PRODUCTS, $productIds);
342
  }
343
  }
344
 
345
  return $this;
346
  }
347
 
348
+ public function addActionProductIdsForAllStore($productIds, $action = self::ACT_UPDATE_PRODUCTS)
349
  {
350
  if (!empty($productIds)) {
351
  if (count($productIds) <= Mage::helper('searchanise/ApiSe')->getProductsPerPass()) {
372
  return $this;
373
  }
374
 
375
+ public function addActionProductIds($productIds, $action = self::ACT_UPDATE_PRODUCTS)
376
  {
377
  if (!empty($productIds)) {
378
  if (!is_array($productIds)) {
386
 
387
  if ($product) {
388
  $storeIds = $product->getStoreIds();
389
+ Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_UPDATE_PRODUCTS, $productId, null, $storeIds);
390
  }
391
  }
392
  }
404
  $productIds[] = $item->getProductId();
405
  }
406
  if (count($productIds) >= Mage::helper('searchanise/ApiSe')->getProductsPerPass()) {
407
+ Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_UPDATE_PRODUCTS, $productIds, null, $item->getStoreId());
408
  $productIds = array();
409
  }
410
  }
411
 
412
  if (!empty($productIds)) {
413
+ Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_UPDATE_PRODUCTS, $productIds, null, $item->getStoreId());
414
  }
415
  }
416
 
431
  if (!empty($storeIdsOld)) {
432
  foreach ($storeIdsOld as $k => $storeIdOld) {
433
  if ((empty($storeIds)) || (!in_array($storeIdOld, $storeIds))) {
434
+ $this->addAction(Simtech_Searchanise_Model_Queue::ACT_DELETE_PRODUCTS, $product->getId(), null, $storeIdOld);
435
  }
436
  }
437
  }
448
 
449
  if (!empty($storeIds)) {
450
  foreach ($storeIds as $k => $storeId) {
451
+ $this->addAction(Simtech_Searchanise_Model_Queue::ACT_DELETE_PRODUCTS, $product->getId(), null, $storeId);
452
  }
453
  }
454
  }
471
 
472
  if (!empty($storeIds)) {
473
  foreach ($storeIds as $k => $storeId) {
474
+ $this->addAction(Simtech_Searchanise_Model_Queue::ACT_UPDATE_PRODUCTS, $product->getId(), null, $storeId);
475
  }
476
  }
477
  }
app/code/community/Simtech/Searchanise/Model/Request.php CHANGED
@@ -539,7 +539,7 @@ class Simtech_Searchanise_Model_Request extends Mage_Core_Model_Abstract
539
  // fixme in the future
540
  // error calc count product in category
541
  $arr_cat = null;
542
- Mage::helper('searchanise/ApiSe')->getAllChildrenCategories($arr_cat, $category);
543
 
544
  foreach ($res['facets'] as $facet) {
545
  if ($facet['attribute'] == 'category_ids') {
539
  // fixme in the future
540
  // error calc count product in category
541
  $arr_cat = null;
542
+ Mage::helper('searchanise/ApiCategories')->getAllChildrenCategories($arr_cat, $category);
543
 
544
  foreach ($res['facets'] as $facet) {
545
  if ($facet['attribute'] == 'category_ids') {
app/code/community/Simtech/Searchanise/controllers/AsyncController.php CHANGED
@@ -13,7 +13,6 @@
13
  ****************************************************************************/
14
  class Simtech_Searchanise_AsyncController extends Mage_Core_Controller_Front_Action
15
  {
16
- const PARENT_PRIVATE_KEY = 'parent_private_key';
17
  protected $_notUseHttpRequestText = null;
18
  protected $_flShowStatusAsync = null;
19
 
@@ -72,14 +71,8 @@ class Simtech_Searchanise_AsyncController extends Mage_Core_Controller_Front_Act
72
  public function indexAction()
73
  {
74
  if (Mage::helper('searchanise/ApiSe')->getStatusModule() == 'Y') {
75
- $parentPrivateKey = $this->getRequest()->getParam(self::PARENT_PRIVATE_KEY);
76
- if ((empty($parentPrivateKey)) ||
77
- (Mage::helper('searchanise/ApiSe')->getParentPrivateKey() !== $parentPrivateKey)) {
78
- $checkKey = false;
79
- } else {
80
- $checkKey = true;
81
- }
82
-
83
  // not need because it checked in the "Async.php" block
84
  // if (Mage::helper('searchanise/ApiSe')->checkStartAsync()) {
85
  if (true) {
@@ -94,11 +87,13 @@ class Simtech_Searchanise_AsyncController extends Mage_Core_Controller_Front_Act
94
  @ignore_user_abort(true);
95
  @set_time_limit(0);
96
  if ($checkKey && $this->getRequest()->getParam('display_errors') === 'Y') {
97
- @error_reporting(E_ALL);
98
  @ini_set('display_errors', 1);
 
99
  } else {
100
  @error_reporting(0);
101
  @ini_set('display_errors', 0);
 
102
  }
103
  $flIgnoreProcessing = false;
104
  if ($checkKey && $this->getRequest()->getParam('ignore_processing') === 'Y') {
13
  ****************************************************************************/
14
  class Simtech_Searchanise_AsyncController extends Mage_Core_Controller_Front_Action
15
  {
 
16
  protected $_notUseHttpRequestText = null;
17
  protected $_flShowStatusAsync = null;
18
 
71
  public function indexAction()
72
  {
73
  if (Mage::helper('searchanise/ApiSe')->getStatusModule() == 'Y') {
74
+ $checkKey = Mage::helper('searchanise')->checkPrivateKey();
75
+
 
 
 
 
 
 
76
  // not need because it checked in the "Async.php" block
77
  // if (Mage::helper('searchanise/ApiSe')->checkStartAsync()) {
78
  if (true) {
87
  @ignore_user_abort(true);
88
  @set_time_limit(0);
89
  if ($checkKey && $this->getRequest()->getParam('display_errors') === 'Y') {
90
+ @error_reporting(E_ALL | E_STRICT);
91
  @ini_set('display_errors', 1);
92
+ @ini_set('display_startup_errors', 1);
93
  } else {
94
  @error_reporting(0);
95
  @ini_set('display_errors', 0);
96
+ @ini_set('display_startup_errors', 0);
97
  }
98
  $flIgnoreProcessing = false;
99
  if ($checkKey && $this->getRequest()->getParam('ignore_processing') === 'Y') {
app/code/community/Simtech/Searchanise/controllers/InfoController.php CHANGED
@@ -22,6 +22,8 @@ class Simtech_Searchanise_InfoController extends Mage_Core_Controller_Front_Acti
22
  const DISPLAY_ERRORS = 'display_errors';
23
  const PRODUCT_ID = 'product_id';
24
  const PRODUCT_IDS = 'product_ids';
 
 
25
  const BY_ITEMS = 'by_items';
26
  const PARENT_PRIVATE_KEY = 'parent_private_key';
27
 
@@ -32,7 +34,7 @@ class Simtech_Searchanise_InfoController extends Mage_Core_Controller_Front_Acti
32
  */
33
  public function preDispatch()
34
  {
35
- // It is need if controller will used the "generateProductsXML" function
36
 
37
  // Do not start standart session
38
  $this->setFlag('', self::FLAG_NO_START_SESSION, 1);
@@ -50,11 +52,9 @@ class Simtech_Searchanise_InfoController extends Mage_Core_Controller_Front_Acti
50
 
51
  public function indexAction()
52
  {
53
- $visual = $this->getRequest()->getParam(self::OUTPUT);
54
- $parentPrivateKey = $this->getRequest()->getParam(self::PARENT_PRIVATE_KEY);
55
 
56
- if ((empty($parentPrivateKey)) ||
57
- (Mage::helper('searchanise/ApiSe')->getParentPrivateKey() !== $parentPrivateKey)) {
58
  $_options = Mage::helper('searchanise/ApiSe')->getAddonOptions();
59
  $options = array(
60
  'status' => $_options['addon_status'],
@@ -74,24 +74,26 @@ class Simtech_Searchanise_InfoController extends Mage_Core_Controller_Front_Acti
74
  $displayErrors = $this->getRequest()->getParam(self::DISPLAY_ERRORS);
75
  $productId = $this->getRequest()->getParam(self::PRODUCT_ID);
76
  $productIds = $this->getRequest()->getParam(self::PRODUCT_IDS);
 
 
77
  $byItems = $this->getRequest()->getParam(self::BY_ITEMS);
78
  if ($byItems == 'Y') {
79
- Mage::helper('searchanise/ApiXML')->setIsGetProductsByItems(true);
80
  }
 
81
 
82
  if ($displayErrors) {
83
- @error_reporting(E_ALL);
84
  @ini_set('display_errors', 1);
 
85
  } else {
86
  @error_reporting(0);
87
  @ini_set('display_errors', 0);
 
88
  }
89
 
90
- if ($productId) {
91
- $productIds = array($productId);
92
- } elseif ($productIds) {
93
- $productIds = explode(',', $productIds);
94
- }
95
 
96
  $store = null;
97
  if (!empty($storeId)) {
@@ -118,31 +120,43 @@ class Simtech_Searchanise_InfoController extends Mage_Core_Controller_Front_Acti
118
  $n = 0;
119
  $productFeeds = '';
120
  while ($n < $numberIterations) {
121
- $productFeeds = Mage::helper('searchanise/ApiXML')->generateProductsXML($productIds, $store, true);
122
  $n++;
123
  }
124
 
125
  echo $this->_profiler();
 
 
 
 
 
 
 
 
126
  if ($visual) {
127
- Mage::helper('searchanise/ApiSe')->printR($productFeeds);
128
  } else {
129
- echo Mage::helper('core')->jsonEncode($productFeeds);
130
  }
 
131
  } elseif ($resync) {
132
  Mage::helper('searchanise/ApiSe')->queueImport($store);
133
 
134
- } elseif (!empty($productIds)) {
135
- $productFeeds = Mage::helper('searchanise/ApiXML')->generateProductsXML($productIds, $store, $checkData);
136
- if ($productFeeds) {
137
- $xmlHeader = Mage::helper('searchanise/ApiXML')->getXMLHeader($store);
138
- $xmlFooter = Mage::helper('searchanise/ApiXML')->getXMLFooter($store);
139
- $productFeeds = $xmlHeader . $productFeeds . $xmlFooter;
140
  }
 
 
 
 
 
 
141
 
142
  if ($visual) {
143
- Mage::helper('searchanise/ApiSe')->printR($productFeeds);
144
  } else {
145
- echo Mage::helper('core')->jsonEncode($productFeeds);
146
  }
147
 
148
  } else {
@@ -159,6 +173,7 @@ class Simtech_Searchanise_InfoController extends Mage_Core_Controller_Front_Acti
159
  $options['ajax_async_enabled'] = Mage::helper('searchanise/ApiSe')->checkAjaxAsync();
160
  $options['object_async_enabled'] = Mage::helper('searchanise/ApiSe')->checkObjectAsync();
161
 
 
162
  $options['use_full_feed'] = Mage::helper('searchanise/ApiSe')->getUseFullFeed();
163
 
164
  $options['max_execution_time'] = ini_get('max_execution_time');
22
  const DISPLAY_ERRORS = 'display_errors';
23
  const PRODUCT_ID = 'product_id';
24
  const PRODUCT_IDS = 'product_ids';
25
+ const CATEGORY_ID = 'category_id';
26
+ const CATEGORY_IDS = 'category_ids';
27
  const BY_ITEMS = 'by_items';
28
  const PARENT_PRIVATE_KEY = 'parent_private_key';
29
 
34
  */
35
  public function preDispatch()
36
  {
37
+ // It is need if controller will used the "generateProductsFeed" function
38
 
39
  // Do not start standart session
40
  $this->setFlag('', self::FLAG_NO_START_SESSION, 1);
52
 
53
  public function indexAction()
54
  {
55
+ $visual = $this->getRequest()->getParam(self::OUTPUT);
 
56
 
57
+ if (!Mage::helper('searchanise')->checkPrivateKey()) {
 
58
  $_options = Mage::helper('searchanise/ApiSe')->getAddonOptions();
59
  $options = array(
60
  'status' => $_options['addon_status'],
74
  $displayErrors = $this->getRequest()->getParam(self::DISPLAY_ERRORS);
75
  $productId = $this->getRequest()->getParam(self::PRODUCT_ID);
76
  $productIds = $this->getRequest()->getParam(self::PRODUCT_IDS);
77
+ $categoryId = $this->getRequest()->getParam(self::CATEGORY_ID);
78
+ $categoryIds = $this->getRequest()->getParam(self::CATEGORY_IDS);
79
  $byItems = $this->getRequest()->getParam(self::BY_ITEMS);
80
  if ($byItems == 'Y') {
81
+ Mage::helper('searchanise/ApiProducts')->setIsGetProductsByItems(true);
82
  }
83
+ $checkData = $checkData != 'N';
84
 
85
  if ($displayErrors) {
86
+ @error_reporting(E_ALL | E_STRICT);
87
  @ini_set('display_errors', 1);
88
+ @ini_set('display_startup_errors', 1);
89
  } else {
90
  @error_reporting(0);
91
  @ini_set('display_errors', 0);
92
+ @ini_set('display_startup_errors', 0);
93
  }
94
 
95
+ $productIds = $productId ? $productId : ($productIds ? explode(',', $productIds) : 0);
96
+ $categoryIds = $categoryId ? $categoryId : ($categoryIds ? explode(',', $categoryIds) : 0);
 
 
 
97
 
98
  $store = null;
99
  if (!empty($storeId)) {
120
  $n = 0;
121
  $productFeeds = '';
122
  while ($n < $numberIterations) {
123
+ $productFeeds = Mage::helper('searchanise/ApiProducts')->generateProductsFeed($productIds, $store, true);
124
  $n++;
125
  }
126
 
127
  echo $this->_profiler();
128
+
129
+ $feed = array(
130
+ 'header' => Mage::helper('searchanise/ApiProducts')->getHeader($store),
131
+ 'items' => $productFeeds,
132
+ 'schema' => Mage::helper('searchanise/ApiProducts')->getSchema(Simtech_Searchanise_Model_Queue::NOT_DATA, $store),
133
+ 'categories' => Mage::helper('searchanise/ApiCategories')->generateCategoriesFeed(Simtech_Searchanise_Model_Queue::NOT_DATA, $store, true),
134
+ );
135
+
136
  if ($visual) {
137
+ Mage::helper('searchanise/ApiSe')->printR(Mage::helper('core')->jsonEncode($feed), $feed);
138
  } else {
139
+ echo Mage::helper('core')->jsonEncode($feed);
140
  }
141
+
142
  } elseif ($resync) {
143
  Mage::helper('searchanise/ApiSe')->queueImport($store);
144
 
145
+ } elseif (!empty($productIds) || !empty($categoryIds)) {
146
+ if (!$categoryIds) {
147
+ $categoryIds = Simtech_Searchanise_Model_Queue::NOT_DATA;
 
 
 
148
  }
149
+ $feed = array(
150
+ 'header' => Mage::helper('searchanise/ApiProducts')->getHeader($store),
151
+ 'items' => Mage::helper('searchanise/ApiProducts')->generateProductsFeed($productIds, $store, $checkData),
152
+ 'schema' => Mage::helper('searchanise/ApiProducts')->getSchema(Simtech_Searchanise_Model_Queue::NOT_DATA, $store),
153
+ 'categories' => Mage::helper('searchanise/ApiCategories')->generateCategoriesFeed($categoryIds, $store, $checkData),
154
+ );
155
 
156
  if ($visual) {
157
+ Mage::helper('searchanise/ApiSe')->printR(Mage::helper('core')->jsonEncode($feed), $feed);
158
  } else {
159
+ echo Mage::helper('core')->jsonEncode($feed);
160
  }
161
 
162
  } else {
173
  $options['ajax_async_enabled'] = Mage::helper('searchanise/ApiSe')->checkAjaxAsync();
174
  $options['object_async_enabled'] = Mage::helper('searchanise/ApiSe')->checkObjectAsync();
175
 
176
+ $options['use_navigation'] = Mage::helper('searchanise/ApiSe')->getUseNavigation();
177
  $options['use_full_feed'] = Mage::helper('searchanise/ApiSe')->getUseFullFeed();
178
 
179
  $options['max_execution_time'] = ini_get('max_execution_time');
app/code/community/Simtech/Searchanise/etc/config.xml CHANGED
@@ -15,7 +15,7 @@
15
  <config>
16
  <modules>
17
  <Simtech_Searchanise>
18
- <version>2.0.2</version>
19
  </Simtech_Searchanise>
20
  </modules>
21
  <frontend>
@@ -413,6 +413,14 @@
413
  </observers>
414
  </catalog_entity_attribute_delete_after>
415
  <!-- facet-categories -->
 
 
 
 
 
 
 
 
416
  <catalog_category_save_before>
417
  <observers>
418
  <rating>
@@ -563,12 +571,13 @@
563
  <default>
564
  <searchanise>
565
  <config>
566
- <server_version>1.2</server_version>
567
  <async_memory_limit>512</async_memory_limit>
568
  <search_timeout>3</search_timeout>
569
  <request_timeout>10</request_timeout>
570
  <ajax_async_timeout>1</ajax_async_timeout>
571
  <products_per_pass>100</products_per_pass>
 
572
  <max_error_count>25</max_error_count>
573
  <max_processing_thread>3</max_processing_thread>
574
  <max_processing_time>720</max_processing_time>
15
  <config>
16
  <modules>
17
  <Simtech_Searchanise>
18
+ <version>3.0.0</version>
19
  </Simtech_Searchanise>
20
  </modules>
21
  <frontend>
413
  </observers>
414
  </catalog_entity_attribute_delete_after>
415
  <!-- facet-categories -->
416
+ <catalog_category_delete_before>
417
+ <observers>
418
+ <rating>
419
+ <class>searchanise/observer</class>
420
+ <method>catalogCategoryDeleteBefore</method>
421
+ </rating>
422
+ </observers>
423
+ </catalog_category_delete_before>
424
  <catalog_category_save_before>
425
  <observers>
426
  <rating>
571
  <default>
572
  <searchanise>
573
  <config>
574
+ <server_version>1.3</server_version>
575
  <async_memory_limit>512</async_memory_limit>
576
  <search_timeout>3</search_timeout>
577
  <request_timeout>10</request_timeout>
578
  <ajax_async_timeout>1</ajax_async_timeout>
579
  <products_per_pass>100</products_per_pass>
580
+ <categories_per_pass>500</categories_per_pass>
581
  <max_error_count>25</max_error_count>
582
  <max_processing_thread>3</max_processing_thread>
583
  <max_processing_time>720</max_processing_time>
app/code/community/Simtech/Searchanise/etc/config_without_search.xml CHANGED
@@ -15,7 +15,7 @@
15
  <config>
16
  <modules>
17
  <Simtech_Searchanise>
18
- <version>2.0.2</version>
19
  </Simtech_Searchanise>
20
  </modules>
21
  <frontend>
@@ -413,6 +413,14 @@
413
  </observers>
414
  </catalog_entity_attribute_delete_after>
415
  <!-- facet-categories -->
 
 
 
 
 
 
 
 
416
  <catalog_category_save_before>
417
  <observers>
418
  <rating>
@@ -563,12 +571,13 @@
563
  <default>
564
  <searchanise>
565
  <config>
566
- <server_version>1.2</server_version>
567
  <async_memory_limit>512</async_memory_limit>
568
  <search_timeout>3</search_timeout>
569
  <request_timeout>10</request_timeout>
570
  <ajax_async_timeout>1</ajax_async_timeout>
571
  <products_per_pass>100</products_per_pass>
 
572
  <max_error_count>25</max_error_count>
573
  <max_processing_thread>3</max_processing_thread>
574
  <max_processing_time>720</max_processing_time>
15
  <config>
16
  <modules>
17
  <Simtech_Searchanise>
18
+ <version>3.0.0</version>
19
  </Simtech_Searchanise>
20
  </modules>
21
  <frontend>
413
  </observers>
414
  </catalog_entity_attribute_delete_after>
415
  <!-- facet-categories -->
416
+ <catalog_category_delete_before>
417
+ <observers>
418
+ <rating>
419
+ <class>searchanise/observer</class>
420
+ <method>catalogCategoryDeleteBefore</method>
421
+ </rating>
422
+ </observers>
423
+ </catalog_category_delete_before>
424
  <catalog_category_save_before>
425
  <observers>
426
  <rating>
571
  <default>
572
  <searchanise>
573
  <config>
574
+ <server_version>1.3</server_version>
575
  <async_memory_limit>512</async_memory_limit>
576
  <search_timeout>3</search_timeout>
577
  <request_timeout>10</request_timeout>
578
  <ajax_async_timeout>1</ajax_async_timeout>
579
  <products_per_pass>100</products_per_pass>
580
+ <categories_per_pass>500</categories_per_pass>
581
  <max_error_count>25</max_error_count>
582
  <max_processing_thread>3</max_processing_thread>
583
  <max_processing_time>720</max_processing_time>
package.xml CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Simtech_Searchanise</name>
4
- <version>2.0.2</version>
5
  <stability>stable</stability>
6
  <license uri="http://docs.searchanise.com/connector_addon/license_agreement.html">Commercial license: http://docs.searchanise.com/connector_addon/license_agreement.html</license>
7
  <channel>community</channel>
@@ -10,14 +10,17 @@
10
  <description>Searchanise is a free SaaS solution providing fast and smart search for online stores. It provides rapid search results and instant search suggestions presented in a fancy and customizable widget.&#xD;
11
  &#xD;
12
  With the help of Searchanise Connector Add-on you will be able to connect your store to the service and start using the search widget in no time. Power up your store right now!</description>
13
- <notes>[*] Full catalog import is now 2.5-3 times faster.&#xD;
14
- [*] For a group product, its child product descriptions are stored in a separate attribute (fixes the [:ATTR:] issue).&#xD;
15
- [!] The [:ATTR:] chunk could occur in the instant search widget. Fixed.&#xD;
16
- [!] Attribute weights tuned for more relevant search (e.g. description weight increased).</notes>
 
 
 
17
  <authors><author><name>Simbirsk Technologies, Ltd.</name><user>searchanise</user><email>sales@searchanise.com</email></author></authors>
18
- <date>2014-01-28</date>
19
- <time>07:42:45</time>
20
- <contents><target name="magecommunity"><dir name="Simtech"><dir name="Searchanise"><dir name="Block"><file name="Async.php" hash="bc97c98da15f5abbc1d8922ca477dc6d"/><file name="Autocomplete.php" hash="efc89ac3f897be3bc307fba6a36778f0"/><file name="Jsinit.php" hash="3cb0a3bd02858a6ce81d14dbc7b6042f"/><dir name="Product"><dir name="List"><file name="Toolbar.php" hash="759854378cb8c35c37a8a7f44076194f"/></dir><file name="Result.php" hash="4e767e273ee21a38332ac226af878291"/></dir><file name="Result.php" hash="dec7b27ab9511c956680eb60eba9b95e"/></dir><dir name="Helper"><file name="ApiSe.php" hash="5f68ea5c944463c2bb7aac69c51f75cc"/><file name="ApiXML.php" hash="718b40e3039d701196ca8da9b3a5933e"/><file name="Data.php" hash="7c600b973ddaf87cd6a3d507bc6691c5"/></dir><dir name="Model"><file name="Advanced.php" hash="2a22ebcf7ac75b54681ef8a27bad2e47"/><dir name="Config"><file name="Data.php" hash="ddc558d22208f0ebc1e4378c9d050022"/></dir><file name="Config.php" hash="00ca3c7955f3ff2283c636a2074b6f03"/><dir name="Import"><dir name="Entity"><file name="Product.php" hash="4997af528b36f0f576d1c01402e14b03"/></dir></dir><dir name="Layer"><dir name="Filter"><file name="Category.php" hash="e290ab29f2d50e1acbbbb37496150ea4"/><file name="Price.php" hash="743887b32bf012274ad8a371fff96411"/></dir></dir><file name="Layer.php" hash="3e8c975d649ae6e20fcc69d35779c97c"/><file name="LayerCatalogSearch.php" hash="42058e0552719902f3f40f91e816b460"/><dir name="Mysql4"><dir name="Advanced"><file name="Collection.php" hash="dd8c6f3cbb0621a5a7320f3104e68da6"/></dir><dir name="Config"><file name="Collection.php" hash="470218c1eb3f1cc1ca0e6d0e93e1b097"/></dir><file name="Config.php" hash="c95dc8ecd7ab4f955b6eaf4710ab960e"/><dir name="Fulltext"><file name="Collection.php" hash="5646955503a90020f87cfd861ac07e73"/></dir><dir name="Product"><file name="Collection.php" hash="28b478eb328502ce03e389404d9f54b5"/><file name="CollectionTag.php" hash="ea06ec75ee4d083f2b4232c5fe298f00"/></dir><dir name="Queue"><file name="Collection.php" hash="30ca0f8640bdc443deb94cd2e71010c8"/></dir><file name="Queue.php" hash="286351623e8f011a21519f8d9c3e3151"/><file name="Store.php" hash="0126a4291d7dad6641bf59abb0f64cc4"/></dir><file name="Observer.php" hash="5db27768e7d77ed7ddc63ae9f4c4308c"/><file name="Queue.php" hash="831f5ea7e57810f9c78d09659424e9a7"/><file name="Request.php" hash="4bcc67cae33aa9d173e9c414a0367488"/><dir name="Resource"><dir name="Advanced"><file name="Collection.php" hash="6744555254ba1c57f482504b5f16012a"/></dir><dir name="Eav"><dir name="Mysql4"><dir name="Layer"><dir name="Filter"><file name="Attribute.php" hash="05320757b9289edac4f15230cd06c0e1"/><file name="Price.php" hash="ed4e21a18c552e3a92b21ff6e8bc5d61"/></dir></dir><dir name="Product"><file name="Action.php" hash="006e3c8c775cf31a8b9c66fb934c9d2d"/></dir></dir></dir><dir name="Fulltext"><file name="Collection.php" hash="273467b2e39649fcd0a8eede59c5ab98"/></dir><dir name="Layer"><dir name="Filter"><file name="Attribute.php" hash="643a513735ac2a2ac9fba08ff1fa79a0"/><file name="Price.php" hash="15d7ab510b37655a148e077dcece13df"/></dir></dir><dir name="Product"><file name="Collection.php" hash="b7c9a1c2fc24ecf78a32fd0d9d46b120"/><file name="CollectionTag.php" hash="60f12d27d78426a8e04e01d2cbdadb48"/></dir><file name="Store.php" hash="dee8bb23b7fe48dc55e46e93f583699a"/></dir><file name="Searchanise.php" hash="0a03a35854470a310f075298c9a1abf2"/><dir name="System"><dir name="Config"><dir name="Source"><dir name="Searchanise"><file name="TypeAsync.php" hash="11d1aa481094ccbeab365b1fed33440d"/></dir></dir></dir></dir><dir name="Tag"><file name="Relation.php" hash="598f81fd8b2ac77baf24211c2ed03e55"/></dir></dir><dir name="controllers"><file name="AdvancedController.php" hash="5ea4f7fb3362d720462dc0a8e1f1497b"/><file name="AsyncController.php" hash="e1a7dd9debd00fb7df09804d99e56e9e"/><file name="CategoryController.php" hash="06eac1ad4730d42379f6bc6aae097427"/><file name="IndexController.php" hash="e3234ca51a7669741e29ff7c38789989"/><file name="InfoController.php" hash="ad7268c1ccba3323bd2c20341a14f880"/><file name="OptionsController.php" hash="46b8e49dd1026a5e07410b51d101d498"/><file name="ProductController.php" hash="4cf4e991446a36ea34b7c1d350971e1a"/><file name="ResultController.php" hash="2c1d838a2897ffcbb8bc61743254e934"/><file name="ResyncController.php" hash="0612f929d375427326821dfc12186be8"/><file name="SignupController.php" hash="80f87a63d6272f98a068dde35f1d140e"/></dir><dir name="etc"><file name="config.xml" hash="528aaa445dbe31d08b63a818063035c5"/><file name="config_without_search.xml" hash="a7b9f3676b3aeed285145c26ed34c39b"/><file name="system.xml" hash="a006341e693571d11efaa9d289ebf7fa"/></dir><dir name="sql"><dir name="searchanise_setup"><file name="mysql4-install-0.1.0.php" hash="754324c8783e9cc24de86396e1587e73"/></dir></dir></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="template"><dir name="searchanise"><file name="dashboard.phtml" hash="0ec8814b915e8594b019062c071cc485"/></dir></dir><dir name="layout"><file name="searchanise.xml" hash="68baa611d05db05f8816ea2a8260e961"/></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="searchanise.xml" hash="5e904fee02cbd42324a297d513b9f582"/></dir></dir></dir><dir name="default"><dir name="default"><dir name="template"><dir name="catalogsearch"><file name="form.mini.phtml" hash="fcf8e06e66801a36c96f20ca5d187123"/></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Simtech_Searchanise.xml" hash="04148681a6648bd370ab62140cbf2ad9"/></dir></target><target name="magelocale"><dir name="en_US"><file name="Simtech_Searchanise.csv" hash="1bdb7fddc596dac1460bc3054c425187"/></dir></target></contents>
21
  <compatible/>
22
  <dependencies><required><php><min>5.2.13</min><max>6.0.0</max></php></required></dependencies>
23
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>Simtech_Searchanise</name>
4
+ <version>3.0.0</version>
5
  <stability>stable</stability>
6
  <license uri="http://docs.searchanise.com/connector_addon/license_agreement.html">Commercial license: http://docs.searchanise.com/connector_addon/license_agreement.html</license>
7
  <channel>community</channel>
10
  <description>Searchanise is a free SaaS solution providing fast and smart search for online stores. It provides rapid search results and instant search suggestions presented in a fancy and customizable widget.&#xD;
11
  &#xD;
12
  With the help of Searchanise Connector Add-on you will be able to connect your store to the service and start using the search widget in no time. Power up your store right now!</description>
13
+ <notes>[+] Category search support added.&lt;br&gt;&#xD;
14
+ [*] Switch to API v. 1.3.&lt;br&gt;&#xD;
15
+ [*] Datafeeds are now submitted in JSON instead of XML.&lt;br&gt;&#xD;
16
+ [*] Faster indexation: Only active products are submitted on initial indexation.&lt;br&gt;&#xD;
17
+ [*] Faster indexation: Child products are not submitted separately from their parents.&lt;br&gt;&#xD;
18
+ [!] Usergroup-based prices could be submitted incorrectly. Fixed.&lt;br&gt;&#xD;
19
+ [!] Minor improvements and fixes in the advanced search.&lt;br&gt;</notes>
20
  <authors><author><name>Simbirsk Technologies, Ltd.</name><user>searchanise</user><email>sales@searchanise.com</email></author></authors>
21
+ <date>2014-02-14</date>
22
+ <time>07:57:41</time>
23
+ <contents><target name="magecommunity"><dir name="Simtech"><dir name="Searchanise"><dir name="Block"><file name="Async.php" hash="bc97c98da15f5abbc1d8922ca477dc6d"/><file name="Autocomplete.php" hash="efc89ac3f897be3bc307fba6a36778f0"/><file name="Jsinit.php" hash="3cb0a3bd02858a6ce81d14dbc7b6042f"/><dir name="Product"><dir name="List"><file name="Toolbar.php" hash="759854378cb8c35c37a8a7f44076194f"/></dir><file name="Result.php" hash="4e767e273ee21a38332ac226af878291"/></dir><file name="Result.php" hash="dec7b27ab9511c956680eb60eba9b95e"/></dir><dir name="Helper"><file name="ApiCategories.php" hash="dc10df2138ae17ea77e9ad522748ab81"/><file name="ApiProducts.php" hash="12b5b03b26dccf7c07777f3d73e90713"/><file name="ApiSe.php" hash="c9133cd2543ab9ff92ee126b43eea505"/><file name="Data.php" hash="d4925c397d8b821b47be87a4d377930a"/></dir><dir name="Model"><file name="Advanced.php" hash="deb3ae5193e0aee50b94360b1833ac82"/><dir name="Config"><file name="Data.php" hash="ddc558d22208f0ebc1e4378c9d050022"/></dir><file name="Config.php" hash="00ca3c7955f3ff2283c636a2074b6f03"/><dir name="Import"><dir name="Entity"><file name="Product.php" hash="4997af528b36f0f576d1c01402e14b03"/></dir></dir><dir name="Layer"><dir name="Filter"><file name="Category.php" hash="e290ab29f2d50e1acbbbb37496150ea4"/><file name="Price.php" hash="743887b32bf012274ad8a371fff96411"/></dir></dir><file name="Layer.php" hash="3e8c975d649ae6e20fcc69d35779c97c"/><file name="LayerCatalogSearch.php" hash="42058e0552719902f3f40f91e816b460"/><dir name="Mysql4"><dir name="Advanced"><file name="Collection.php" hash="dd8c6f3cbb0621a5a7320f3104e68da6"/></dir><dir name="Config"><file name="Collection.php" hash="470218c1eb3f1cc1ca0e6d0e93e1b097"/></dir><file name="Config.php" hash="c95dc8ecd7ab4f955b6eaf4710ab960e"/><dir name="Fulltext"><file name="Collection.php" hash="5646955503a90020f87cfd861ac07e73"/></dir><dir name="Product"><file name="Collection.php" hash="28b478eb328502ce03e389404d9f54b5"/><file name="CollectionTag.php" hash="ea06ec75ee4d083f2b4232c5fe298f00"/></dir><dir name="Queue"><file name="Collection.php" hash="30ca0f8640bdc443deb94cd2e71010c8"/></dir><file name="Queue.php" hash="286351623e8f011a21519f8d9c3e3151"/><file name="Store.php" hash="0126a4291d7dad6641bf59abb0f64cc4"/></dir><file name="Observer.php" hash="f7571c2aea1673f05d61eda706b26c15"/><file name="Queue.php" hash="71cc48374a82faed0f3a312aa2462ef8"/><file name="Request.php" hash="897d53117d7d0e11932e77daaf8b639e"/><dir name="Resource"><dir name="Advanced"><file name="Collection.php" hash="6744555254ba1c57f482504b5f16012a"/></dir><dir name="Eav"><dir name="Mysql4"><dir name="Layer"><dir name="Filter"><file name="Attribute.php" hash="05320757b9289edac4f15230cd06c0e1"/><file name="Price.php" hash="ed4e21a18c552e3a92b21ff6e8bc5d61"/></dir></dir><dir name="Product"><file name="Action.php" hash="006e3c8c775cf31a8b9c66fb934c9d2d"/></dir></dir></dir><dir name="Fulltext"><file name="Collection.php" hash="273467b2e39649fcd0a8eede59c5ab98"/></dir><dir name="Layer"><dir name="Filter"><file name="Attribute.php" hash="643a513735ac2a2ac9fba08ff1fa79a0"/><file name="Price.php" hash="15d7ab510b37655a148e077dcece13df"/></dir></dir><dir name="Product"><file name="Collection.php" hash="b7c9a1c2fc24ecf78a32fd0d9d46b120"/><file name="CollectionTag.php" hash="60f12d27d78426a8e04e01d2cbdadb48"/></dir><file name="Store.php" hash="dee8bb23b7fe48dc55e46e93f583699a"/></dir><file name="Searchanise.php" hash="0a03a35854470a310f075298c9a1abf2"/><dir name="System"><dir name="Config"><dir name="Source"><dir name="Searchanise"><file name="TypeAsync.php" hash="11d1aa481094ccbeab365b1fed33440d"/></dir></dir></dir></dir><dir name="Tag"><file name="Relation.php" hash="598f81fd8b2ac77baf24211c2ed03e55"/></dir></dir><dir name="controllers"><file name="AdvancedController.php" hash="5ea4f7fb3362d720462dc0a8e1f1497b"/><file name="AsyncController.php" hash="f589349f353e2de8c31155b2025b8bea"/><file name="CategoryController.php" hash="06eac1ad4730d42379f6bc6aae097427"/><file name="IndexController.php" hash="e3234ca51a7669741e29ff7c38789989"/><file name="InfoController.php" hash="7592aa452dcb382cc3fc584918febe01"/><file name="OptionsController.php" hash="46b8e49dd1026a5e07410b51d101d498"/><file name="ProductController.php" hash="4cf4e991446a36ea34b7c1d350971e1a"/><file name="ResultController.php" hash="2c1d838a2897ffcbb8bc61743254e934"/><file name="ResyncController.php" hash="0612f929d375427326821dfc12186be8"/><file name="SignupController.php" hash="80f87a63d6272f98a068dde35f1d140e"/></dir><dir name="etc"><file name="config.xml" hash="f01d50c8c93882ae4ab1e2f60a97a31e"/><file name="config_without_search.xml" hash="2a3c15a4e069c6fc766c9c0c2adfb3fd"/><file name="system.xml" hash="a006341e693571d11efaa9d289ebf7fa"/></dir><dir name="sql"><dir name="searchanise_setup"><file name="mysql4-install-0.1.0.php" hash="754324c8783e9cc24de86396e1587e73"/></dir></dir></dir></dir></target><target name="magedesign"><dir name="adminhtml"><dir name="default"><dir name="default"><dir name="template"><dir name="searchanise"><file name="dashboard.phtml" hash="0ec8814b915e8594b019062c071cc485"/></dir></dir><dir name="layout"><file name="searchanise.xml" hash="68baa611d05db05f8816ea2a8260e961"/></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="searchanise.xml" hash="5e904fee02cbd42324a297d513b9f582"/></dir></dir></dir><dir name="default"><dir name="default"><dir name="template"><dir name="catalogsearch"><file name="form.mini.phtml" hash="fcf8e06e66801a36c96f20ca5d187123"/></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Simtech_Searchanise.xml" hash="04148681a6648bd370ab62140cbf2ad9"/></dir></target><target name="magelocale"><dir name="en_US"><file name="Simtech_Searchanise.csv" hash="1bdb7fddc596dac1460bc3054c425187"/></dir></target></contents>
24
  <compatible/>
25
  <dependencies><required><php><min>5.2.13</min><max>6.0.0</max></php></required></dependencies>
26
  </package>