Simtech_Searchanise - Version 1.0.3

Version Notes

[+] - AJAX-based synchronization initialization added.

To change the synchronization initialization mode, go to System → Configuration → SEARCHANISE → Settings.

Setting the mode to AJAX should fix the issue with the synchronization process not starting.

Download this release

Release Info

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


Version 1.0.3

Files changed (53) hide show
  1. app/code/community/Simtech/Searchanise/Block/Async.php +39 -0
  2. app/code/community/Simtech/Searchanise/Block/Jsinit.php +96 -0
  3. app/code/community/Simtech/Searchanise/Block/Product/List/Toolbar.php +150 -0
  4. app/code/community/Simtech/Searchanise/Block/Product/Result.php +51 -0
  5. app/code/community/Simtech/Searchanise/Block/Result.php +45 -0
  6. app/code/community/Simtech/Searchanise/Helper/ApiSe.php +1665 -0
  7. app/code/community/Simtech/Searchanise/Helper/ApiXML.php +625 -0
  8. app/code/community/Simtech/Searchanise/Helper/Data.php +498 -0
  9. app/code/community/Simtech/Searchanise/Model/Advanced.php +49 -0
  10. app/code/community/Simtech/Searchanise/Model/Config.php +108 -0
  11. app/code/community/Simtech/Searchanise/Model/Config/Data.php +33 -0
  12. app/code/community/Simtech/Searchanise/Model/Import/Entity/Product.php +56 -0
  13. app/code/community/Simtech/Searchanise/Model/Layer.php +52 -0
  14. app/code/community/Simtech/Searchanise/Model/Layer/Filter/Category.php +68 -0
  15. app/code/community/Simtech/Searchanise/Model/Layer/Filter/Price.php +51 -0
  16. app/code/community/Simtech/Searchanise/Model/LayerCatalogSearch.php +52 -0
  17. app/code/community/Simtech/Searchanise/Model/Mysql4/Config.php +81 -0
  18. app/code/community/Simtech/Searchanise/Model/Mysql4/Config/Collection.php +32 -0
  19. app/code/community/Simtech/Searchanise/Model/Mysql4/Queue.php +21 -0
  20. app/code/community/Simtech/Searchanise/Model/Mysql4/Queue/Collection.php +32 -0
  21. app/code/community/Simtech/Searchanise/Model/Observer.php +651 -0
  22. app/code/community/Simtech/Searchanise/Model/Queue.php +333 -0
  23. app/code/community/Simtech/Searchanise/Model/Request.php +554 -0
  24. app/code/community/Simtech/Searchanise/Model/Resource/Advanced/Collection.php +114 -0
  25. app/code/community/Simtech/Searchanise/Model/Resource/Fulltext.php +27 -0
  26. app/code/community/Simtech/Searchanise/Model/Resource/Fulltext/Collection.php +113 -0
  27. app/code/community/Simtech/Searchanise/Model/Resource/Layer/Filter/Attribute.php +40 -0
  28. app/code/community/Simtech/Searchanise/Model/Resource/Layer/Filter/Price.php +55 -0
  29. app/code/community/Simtech/Searchanise/Model/Resource/Product/Collection.php +105 -0
  30. app/code/community/Simtech/Searchanise/Model/Resource/Product/CollectionTag.php +77 -0
  31. app/code/community/Simtech/Searchanise/Model/Resource/Store.php +61 -0
  32. app/code/community/Simtech/Searchanise/Model/System/Config/Source/Searchanise/TypeAsync.php +41 -0
  33. app/code/community/Simtech/Searchanise/Model/Tag/Relation.php +30 -0
  34. app/code/community/Simtech/Searchanise/controllers/AdvancedController.php +46 -0
  35. app/code/community/Simtech/Searchanise/controllers/AsyncController.php +92 -0
  36. app/code/community/Simtech/Searchanise/controllers/CategoryController.php +71 -0
  37. app/code/community/Simtech/Searchanise/controllers/IndexController.php +47 -0
  38. app/code/community/Simtech/Searchanise/controllers/InfoController.php +52 -0
  39. app/code/community/Simtech/Searchanise/controllers/OptionsController.php +28 -0
  40. app/code/community/Simtech/Searchanise/controllers/ProductController.php +40 -0
  41. app/code/community/Simtech/Searchanise/controllers/ResultController.php +45 -0
  42. app/code/community/Simtech/Searchanise/controllers/ResyncController.php +34 -0
  43. app/code/community/Simtech/Searchanise/controllers/SignupController.php +32 -0
  44. app/code/community/Simtech/Searchanise/etc/config.xml +483 -0
  45. app/code/community/Simtech/Searchanise/etc/system.xml +67 -0
  46. app/code/community/Simtech/Searchanise/sql/searchanise_setup/mysql4-install-0.1.0.php +46 -0
  47. app/design/adminhtml/default/default/layout/searchanise.xml +21 -0
  48. app/design/adminhtml/default/default/template/searchanise/dashboard.phtml +83 -0
  49. app/design/frontend/base/default/layout/searchanise.xml +24 -0
  50. app/design/frontend/default/default/template/catalogsearch/form.mini.phtml +33 -0
  51. app/etc/modules/Simtech_Searchanise.xml +22 -0
  52. app/locale/en_US/Simtech_Searchanise.csv +22 -0
  53. package.xml +24 -0
app/code/community/Simtech/Searchanise/Block/Async.php ADDED
@@ -0,0 +1,39 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ class Simtech_Searchanise_Block_Async extends Mage_Core_Block_Text
15
+ {
16
+ protected function _toHtml()
17
+ {
18
+ $html = '';
19
+
20
+ if (Mage::helper('searchanise/ApiSe')->checkStatusModule()) {
21
+ if (Mage::helper('searchanise/ApiSe')->checkAjaxAsync()) {
22
+ $asyncUrl = Mage::helper('searchanise/ApiSe')->getAsyncUrl(false);
23
+
24
+ $html .= "\n<object data=\"$asyncUrl\" width=\"0\" height=\"0\"></object>\n\n";
25
+
26
+ // code for ajax async
27
+ // not need in current version
28
+ // $html .=
29
+ // "<script type=\"text/javascript\">
30
+ // //<![CDATA[
31
+ // new Ajax.Request('$asyncUrl', {method: 'get', asynchronous: true});
32
+ // //]]>
33
+ // </script>";
34
+ }
35
+ }
36
+
37
+ return $html;
38
+ }
39
+ }
app/code/community/Simtech/Searchanise/Block/Jsinit.php ADDED
@@ -0,0 +1,96 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ class Simtech_Searchanise_Block_Jsinit extends Mage_Core_Block_Text
15
+ {
16
+ protected function _toHtml()
17
+ {
18
+ $html = '';
19
+
20
+ if (!Mage::helper('searchanise/ApiSe')->checkSearchaniseResult(true)) {
21
+ return $html;
22
+ }
23
+
24
+ $api_key = Mage::helper('searchanise/ApiSe')->getApiKey();
25
+
26
+ if (empty($api_key)) {
27
+ return $html;
28
+ }
29
+
30
+ $input_id = Mage::helper('searchanise/ApiSe')->getInputIdSearch();
31
+ if ($input_id == '') {
32
+ // Uncomment the lines below if it is necessary to disable search widget in frontend
33
+ //~ return '';
34
+ }
35
+ if (empty($input_id)) {
36
+ $input_id = 'search';
37
+ }
38
+ $union = 'Searchanise.AutoCmpParams.union = {};';
39
+ $restrictBy = '';
40
+
41
+ $se_service_url = Mage::helper('searchanise/ApiSe')->getServiceUrl();
42
+ $price_format = Mage::helper('searchanise/ApiSe')->getPriceFormat();
43
+ $searchWidgetsLink = Mage::helper('searchanise/ApiSe')->getSearchWidgetsLink(false);
44
+
45
+ $union .= " Searchanise.AutoCmpParams.union.price = {};";
46
+ $union .= " Searchanise.AutoCmpParams.union.price.min = '" . Mage::helper('searchanise/ApiSe')->getCurLabelForPricesUsergroup() . "';";
47
+
48
+ $minQuantityDecimals = Mage::helper('searchanise/ApiSe')->getMinQuantityDecimals();
49
+ if (!empty($minQuantityDecimals)) {
50
+ $restrictBy .= 'Searchanise.AutoCmpParams.restrictBy.quantity_decimals = ' . $minQuantityDecimals . ',';
51
+ }
52
+
53
+ $price_format['after'] = $price_format['after'] ? 'true' : 'false';
54
+
55
+ $html .=
56
+ "<script type=\"text/javascript\">
57
+ //<![CDATA[
58
+ Searchanise = {};
59
+ Searchanise.host = '{$se_service_url}';
60
+ Searchanise.api_key = '{$api_key}';
61
+ Searchanise.SearchInput = '#{$input_id}';
62
+
63
+ Searchanise.AutoCmpParams = {};
64
+ {$union}
65
+ Searchanise.AutoCmpParams.restrictBy = {};
66
+ Searchanise.AutoCmpParams.restrictBy.status = '1';
67
+ Searchanise.AutoCmpParams.restrictBy.visibility = '3|4';
68
+ Searchanise.AutoCmpParams.restrictBy.is_in_stock = '1';
69
+ {$restrictBy}
70
+
71
+ Searchanise.options = {};
72
+ Searchanise.options.LabelSuggestions = 'Popular suggestions';
73
+ Searchanise.options.LabelProducts = 'Products';
74
+ Searchanise.AdditionalSearchInputs = '#name,#description,#sku';
75
+
76
+ Searchanise.options.PriceFormat = {
77
+ rate : '{$price_format['rate']}',
78
+ decimals: '{$price_format['decimals']}',
79
+ decimals_separator: '{$price_format['decimals_separator']}',
80
+ thousands_separator: '{$price_format['thousands_separator']}',
81
+ symbol: '{$price_format['symbol']}',
82
+ after: {$price_format['after']}
83
+ };
84
+
85
+ (function() {
86
+ var __se = document.createElement('script');
87
+ __se.src = '{$searchWidgetsLink}';
88
+ __se.setAttribute('async', 'true');
89
+ document.documentElement.firstChild.appendChild(__se);
90
+ })();
91
+ //]]>
92
+ </script>";
93
+
94
+ return $html;
95
+ }
96
+ }
app/code/community/Simtech/Searchanise/Block/Product/List/Toolbar.php ADDED
@@ -0,0 +1,150 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Block_Product_List_Toolbar extends Mage_Catalog_Block_Product_List_Toolbar
16
+ {
17
+ public function getCollectionPageSize()
18
+ {
19
+ if (!Mage::helper('searchanise/ApiSe')->checkSearchaniseResult(true)) {
20
+ return parent::getCollectionPageSize();
21
+ }
22
+
23
+ return (int) $this->getLimit();
24
+ }
25
+
26
+ /**
27
+ * Get current collection page
28
+ *
29
+ * @param int $displacement
30
+ * @return int
31
+ */
32
+ public function getCollectionCurPage($displacement = 0)
33
+ {
34
+ if (!Mage::helper('searchanise/ApiSe')->checkSearchaniseResult(true)) {
35
+ return parent::getCollectionCurPage($displacement);
36
+ }
37
+
38
+ if ($this->_curPage + $displacement < 1) {
39
+ return 1;
40
+
41
+ } elseif ($this->_curPage + $displacement > $this->getLastPageNumber()) {
42
+ return $this->getLastPageNumber();
43
+
44
+ } else {
45
+ return $this->_curPage + $displacement;
46
+ }
47
+ }
48
+
49
+ public function getFirstNum()
50
+ {
51
+ if (!Mage::helper('searchanise/ApiSe')->checkSearchaniseResult(true)) {
52
+ return parent::getFirstNum();
53
+ }
54
+
55
+ $collection = $this->getCollection();
56
+ if ((!method_exists($collection, 'checkSearchaniseResult')) || (!$collection->checkSearchaniseResult()))
57
+ {
58
+ return parent::getFirstNum();
59
+ }
60
+
61
+ return $this->getCollectionPageSize()*($this->getCurrentPage()-1)+1;
62
+
63
+ }
64
+
65
+ public function getLastNum()
66
+ {
67
+ if (!Mage::helper('searchanise/ApiSe')->checkSearchaniseResult(true)) {
68
+ return parent::getLastNum();
69
+ }
70
+
71
+ $collection = $this->getCollection();
72
+ if ((!method_exists($collection, 'checkSearchaniseResult')) || (!$collection->checkSearchaniseResult())) {
73
+ return parent::getLastNum();
74
+ }
75
+
76
+ return $this->getCollectionPageSize()*($this->getCurrentPage()-1)+$collection->count();
77
+ }
78
+
79
+ public function getLastPageNum()
80
+ {
81
+ if (!Mage::helper('searchanise/ApiSe')->checkSearchaniseResult(true)) {
82
+ return parent::getLastPageNum();
83
+ }
84
+
85
+ $collection = $this->getCollection();
86
+
87
+ if ((!method_exists($collection, 'checkSearchaniseResult')) || (!$collection->checkSearchaniseResult())) {
88
+ return parent::getLastPageNum();
89
+ }
90
+
91
+ $collectionSize = (int) $collection
92
+ ->getSearchaniseRequest()
93
+ ->getTotalProduct();
94
+
95
+ $limit = (int) $this->getLimit();
96
+ if (0 === $collectionSize) {
97
+ return 1;
98
+
99
+ } elseif ($limit) {
100
+ return ceil($collectionSize/$limit);
101
+ }
102
+
103
+ return 1;
104
+ }
105
+
106
+ public function getTotalNum()
107
+ {
108
+ if (!Mage::helper('searchanise/ApiSe')->checkSearchaniseResult(true)) {
109
+ return parent::getTotalNum();
110
+ }
111
+
112
+ $collection = $this->getCollection();
113
+
114
+ if ((!method_exists($collection, 'checkSearchaniseResult')) || (!$collection->checkSearchaniseResult())) {
115
+ return parent::getTotalNum();
116
+ }
117
+
118
+ return $collection
119
+ ->getSearchaniseRequest()
120
+ ->getTotalProduct();
121
+ }
122
+
123
+ public function setCollection($collection)
124
+ {
125
+ if (!Mage::helper('searchanise/ApiSe')->checkSearchaniseResult(true)) {
126
+ return parent::setCollection($collection);
127
+ }
128
+
129
+ if ((!method_exists($collection, 'checkSearchaniseResult')) || (!$collection->checkSearchaniseResult())) {
130
+ return parent::setCollection($collection);
131
+ }
132
+
133
+ $this->_collection = $collection;
134
+
135
+ $this->_collection->setCurPage($this->getCurrentPage());
136
+
137
+ // we need to set pagination only if passed value integer and more that 0
138
+ $limit = (int)$this->getLimit();
139
+
140
+ if ($limit) {
141
+ //~ $this->_collection->setPageSize($limit);
142
+ }
143
+
144
+ if ($this->getCurrentOrder()) {
145
+ $this->_collection->setOrder($this->getCurrentOrder(), $this->getCurrentDirection());
146
+ }
147
+
148
+ return $this;
149
+ }
150
+ }
app/code/community/Simtech/Searchanise/Block/Product/Result.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Block_Product_Result extends Mage_Tag_Block_Product_Result
16
+ {
17
+ protected function _getProductCollection()
18
+ {
19
+ if (!Mage::helper('searchanise/ApiSe')->checkSearchaniseResult(true)) {
20
+ return parent::_getProductCollection();
21
+ }
22
+
23
+ if (is_null($this->_productCollection)) {
24
+ $tagModel = Mage::getModel('tag/tag');
25
+ $collection = $tagModel->getEntityCollection();
26
+
27
+ if (method_exists($collection, 'setSearchaniseRequest')) {
28
+ $collection->setSearchaniseRequest(Mage::helper('searchanise')->getSearchaniseRequest());
29
+ }
30
+
31
+ if ((!method_exists($collection, 'checkSearchaniseResult')) || (!$collection->checkSearchaniseResult())) {
32
+ return parent::_getProductCollection();
33
+ }
34
+
35
+ $this->_productCollection = $collection;
36
+ $this->_productCollection
37
+ ->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes())
38
+ ->addSearchaniseFilter()
39
+ ->addTagFilter($this->getTag()->getId())
40
+ ->addStoreFilter(Mage::app()->getStore()->getId())
41
+ ->addMinimalPrice()
42
+ ->addUrlRewrite()
43
+ ->setActiveFilter();
44
+
45
+ Mage::getSingleton('catalog/product_status')->addSaleableFilterToCollection($this->_productCollection);
46
+ Mage::getSingleton('catalog/product_visibility')->addVisibleInSiteFilterToCollection($this->_productCollection);
47
+ }
48
+
49
+ return $this->_productCollection;
50
+ }
51
+ }
app/code/community/Simtech/Searchanise/Block/Result.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Block_Result extends Mage_CatalogSearch_Block_Result
16
+ {
17
+ /**
18
+ * Retrieve search result count
19
+ *
20
+ * @return string
21
+ */
22
+ public function getResultCount()
23
+ {
24
+ if (!Mage::helper('searchanise/ApiSe')->checkSearchaniseResult(true)) {
25
+ return parent::getResultCount();
26
+ }
27
+
28
+ $collection = $this->_getProductCollection();
29
+
30
+ if ((!method_exists($collection, 'checkSearchaniseResult')) || (!$collection->checkSearchaniseResult())) {
31
+ return parent::getResultCount();
32
+ }
33
+
34
+ if (!$this->getData('result_count')) {
35
+ $size = $collection
36
+ ->getSearchaniseRequest()
37
+ ->getTotalProduct();
38
+
39
+ $this->_getQuery()->setNumResults($size);
40
+ $this->setResultCount($size);
41
+ }
42
+
43
+ return $this->getData('result_count');
44
+ }
45
+ }
app/code/community/Simtech/Searchanise/Helper/ApiSe.php ADDED
@@ -0,0 +1,1665 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ class Simtech_Searchanise_Helper_ApiSe
15
+ {
16
+ const COMPRESS_RATE = 5;
17
+
18
+ const PLATFORM_NAME = 'magento';
19
+
20
+ const CONFIG_PREFIX = 'se_';
21
+
22
+ // const MIN_QUANTITY_DECIMALS = '0.00001';
23
+ const MIN_QUANTITY_DECIMALS = ''; // not activated, because Server have floaf = decimal(12,2)
24
+
25
+ const SUGGESTIONS_MAX_RESULTS = 1;
26
+ const FLOAT_PRECISION = 2; // for server float = decimal(12,2)
27
+ const LABEL_FOR_PRICES_USERGROUP = 'se_price_';
28
+
29
+ protected static $parentPrivateKeySe;
30
+ protected static $privateKeySe = array();
31
+
32
+ const EXPORT_STATUS_QUEUED = 'queued';
33
+ const EXPORT_STATUS_START = 'start';
34
+ const EXPORT_STATUS_PROCESSING = 'processing';
35
+ const EXPORT_STATUS_SENT = 'sent';
36
+ const EXPORT_STATUS_DONE = 'done';
37
+ const EXPORT_STATUS_SYNC_ERROR = 'sync_error';
38
+ const EXPORT_STATUS_NONE = 'none';
39
+
40
+ const STATUS_NORMAL = 'normal';
41
+
42
+ public static $exportStatusTypes = array(
43
+ self::EXPORT_STATUS_QUEUED,
44
+ self::EXPORT_STATUS_START,
45
+ self::EXPORT_STATUS_PROCESSING,
46
+ self::EXPORT_STATUS_SENT,
47
+ self::EXPORT_STATUS_DONE,
48
+ self::EXPORT_STATUS_SYNC_ERROR,
49
+ self::EXPORT_STATUS_NONE,
50
+ );
51
+
52
+ const NOT_USE_HTTP_REQUEST = 'not_use_http_request';
53
+ const NOT_USE_HTTP_REQUEST_KEY = 'Y';
54
+
55
+ public static function getParamNotUseHttpRequest()
56
+ {
57
+ return self::NOT_USE_HTTP_REQUEST . '=' . self::NOT_USE_HTTP_REQUEST_KEY;
58
+ }
59
+
60
+ public static function getCronEnabled()
61
+ {
62
+ return self::getSetting('cron_enabled');
63
+ }
64
+
65
+ public static function getInputIdSearch()
66
+ {
67
+ return self::getSetting('input_id_search');
68
+ }
69
+
70
+ public static function getTypeAsync()
71
+ {
72
+ return self::getSetting('type_async');
73
+ }
74
+
75
+ public static function checkAjaxAsync()
76
+ {
77
+ return self::getTypeAsync() == 2;
78
+ }
79
+
80
+ public static function getLabelForPricesUsergroup() {
81
+ return self::LABEL_FOR_PRICES_USERGROUP;
82
+ }
83
+
84
+ public static function getCurLabelForPricesUsergroup() {
85
+ $customerGroupId = Mage::getSingleton('customer/session')->getCustomerGroupId();
86
+ if (!$customerGroupId) {
87
+ $customerGroupId = 0;
88
+ }
89
+ return self::getLabelForPricesUsergroup() . $customerGroupId;
90
+ }
91
+
92
+ public static function getFloatPrecision() {
93
+ return self::FLOAT_PRECISION;
94
+ }
95
+
96
+ public static function getSuggestionsMaxResults() {
97
+ return self::SUGGESTIONS_MAX_RESULTS;
98
+ }
99
+
100
+ public static function getMinQuantityDecimals() {
101
+ return self::MIN_QUANTITY_DECIMALS;
102
+ }
103
+
104
+ public static function getServiceUrl($onlyHttp = true)
105
+ {
106
+ $ret = self::getSetting('service_url');
107
+
108
+ if (!$onlyHttp) {
109
+ if (Mage::app()->getStore()->isCurrentlySecure()) {
110
+ $ret = str_replace('http://', 'https://', $ret);
111
+ }
112
+ }
113
+
114
+ return $ret;
115
+ }
116
+
117
+ public static function getSearchWidgetsLink($onlyHttp = true)
118
+ {
119
+ return self::getServiceUrl($onlyHttp) . '/widgets/v1.0/init.js';
120
+ }
121
+
122
+ public static function checkSearchaniseResult($searchaniseRequest = null)
123
+ {
124
+ if ((self::getStatusModule() == 'Y') &&
125
+ (self::checkExportStatus()) &&
126
+ (!empty($searchaniseRequest))) {
127
+
128
+ if ($searchaniseRequest === true) {
129
+ return true;
130
+ }
131
+
132
+ return $searchaniseRequest->checkSearchResult();
133
+ }
134
+
135
+ return false;
136
+ }
137
+
138
+ public static function getStatusModule($store = null, $moduleName = 'Simtech_Searchanise')
139
+ {
140
+ if (empty($moduleName)) {
141
+ return;
142
+ }
143
+
144
+ $disableStatus = self::getSettingStore($moduleName, $store, 'advanced/modules_disable_output/');
145
+
146
+ if ($disableStatus) {
147
+ return 'D';
148
+ }
149
+
150
+ return 'Y';
151
+ }
152
+
153
+ public static function checkStatusModule($store = null, $moduleName = 'Simtech_Searchanise')
154
+ {
155
+ return self::getStatusModule($store, $moduleName) == 'Y';
156
+ }
157
+
158
+ public static function setUseNavigation($value = null)
159
+ {
160
+ self::setSetting('use_navigation', $value, self::CONFIG_PREFIX);
161
+
162
+ return true;
163
+ }
164
+
165
+ public static function getUseNavigation($value = null)
166
+ {
167
+ return self::getSetting('use_navigation', self::CONFIG_PREFIX);
168
+ }
169
+
170
+ public static function setLastRequest($value = null)
171
+ {
172
+ self::setSetting('last_request', $value, self::CONFIG_PREFIX);
173
+
174
+ return true;
175
+ }
176
+
177
+ public static function getLastRequest()
178
+ {
179
+ return self::getSetting('last_request', self::CONFIG_PREFIX);
180
+ }
181
+
182
+ public static function setLastResync($value = null)
183
+ {
184
+ self::setSetting('last_resync', $value, self::CONFIG_PREFIX);
185
+
186
+ return true;
187
+ }
188
+
189
+ public static function getLastResync()
190
+ {
191
+ return self::getSetting('last_resync', self::CONFIG_PREFIX);
192
+ }
193
+
194
+ public static function getSearchaniseLink()
195
+ {
196
+ return 'searchanise/index';
197
+ }
198
+
199
+ public static function getAsyncLink($flNotUserHttpRequest = false)
200
+ {
201
+ $link = 'searchanise/async/';
202
+
203
+ if ($flNotUserHttpRequest) {
204
+ $link .= '?' . self::getParamNotUseHttpRequest();
205
+ }
206
+
207
+ return $link;
208
+ }
209
+
210
+ public static function getAsyncUrl($flNotUserHttpRequest = false, $storeId = '', $flCheckSecure = true)
211
+ {
212
+ if ($storeId != '') {
213
+ // need for generate correct url
214
+ Mage::app()->setCurrentStore($storeId);
215
+ }
216
+
217
+ $params = array();
218
+
219
+ if ($flCheckSecure) {
220
+ if (Mage::app()->getStore()->isCurrentlySecure()) {
221
+ $params['_secure'] = true;
222
+ }
223
+ }
224
+
225
+ $asyncUrl = Mage::getUrl(Mage::helper('searchanise/ApiSe')->getAsyncLink(false), $params);
226
+
227
+ if ($flNotUserHttpRequest) {
228
+ $asyncUrl .= strpos($asyncUrl, '?') === false ? '?' : '&';
229
+ $asyncUrl .= self::getParamNotUseHttpRequest();
230
+ }
231
+
232
+ return $asyncUrl;
233
+ }
234
+
235
+ public static function getReSyncLink()
236
+ {
237
+ return 'searchanise/resync';
238
+ }
239
+
240
+ public static function getOptionsLink()
241
+ {
242
+ return 'searchanise/options';
243
+ }
244
+
245
+ public static function getConnectLink()
246
+ {
247
+ return 'searchanise/signup';
248
+ }
249
+
250
+ public static function getLocaleCode($store = null) {
251
+ if (empty($store)) {
252
+ return self::getSetting('code', 'general/locale/');
253
+ }
254
+
255
+ return self::getSettingStore('code', $store, 'general/locale/');
256
+ }
257
+
258
+ public static function getDefaultCurrency($store = null) {
259
+ if (empty($store)) {
260
+ return self::getSetting('default', 'currency/options/');
261
+ }
262
+
263
+ return self::getSettingStore('default', $store, 'currency/options/');
264
+ }
265
+
266
+ public static function getJsPriceFormat($store = null)
267
+ {
268
+ if (empty($store)) {
269
+ return Mage::app()->getLocale()->getJsPriceFormat();
270
+ }
271
+
272
+ $format = Zend_Locale_Data::getContent(self::getLocaleCode($store), 'currencynumber');
273
+ $symbols = Zend_Locale_Data::getList(self::getLocaleCode($store), 'symbols');
274
+
275
+ $pos = strpos($format, ';');
276
+ if ($pos !== false){
277
+ $format = substr($format, 0, $pos);
278
+ }
279
+ $format = preg_replace("/[^0\#\.,]/", "", $format);
280
+ $totalPrecision = 0;
281
+ $decimalPoint = strpos($format, '.');
282
+ if ($decimalPoint !== false) {
283
+ $totalPrecision = (strlen($format) - (strrpos($format, '.')+1));
284
+ } else {
285
+ $decimalPoint = strlen($format);
286
+ }
287
+ $requiredPrecision = $totalPrecision;
288
+ $t = substr($format, $decimalPoint);
289
+ $pos = strpos($t, '#');
290
+ if ($pos !== false){
291
+ $requiredPrecision = strlen($t) - $pos - $totalPrecision;
292
+ }
293
+ $group = 0;
294
+ if (strrpos($format, ',') !== false) {
295
+ $group = ($decimalPoint - strrpos($format, ',') - 1);
296
+ } else {
297
+ $group = strrpos($format, '.');
298
+ }
299
+
300
+ $integerRequired = (strpos($format, '.') - strpos($format, '0'));
301
+
302
+ $result = array(
303
+ 'pattern' => $store->getCurrentCurrency()->getOutputFormat(),
304
+ 'precision' => $totalPrecision,
305
+ 'requiredPrecision' => $requiredPrecision,
306
+ 'decimalSymbol' => $symbols['decimal'],
307
+ 'groupSymbol' => $symbols['group'],
308
+ 'groupLength' => $group,
309
+ 'integerRequired' => $integerRequired
310
+ );
311
+
312
+ return $result;
313
+ }
314
+
315
+ public static function getPriceFormat($store = null)
316
+ {
317
+ $format = self::getJsPriceFormat($store);
318
+
319
+ if (empty($store)) {
320
+ $store = Mage::app()->getStore();
321
+ }
322
+
323
+ // fixme if need
324
+ // change $positionPrice for AdminPanelWidget like as customer area
325
+ $positionPrice = strpos($format['pattern'], '%s');
326
+
327
+ $currency = Mage::app()->getLocale()->currency($store->getCurrentCurrencyCode());
328
+ $symbol = $currency->getSymbol(self::getDefaultCurrency($store), self::getLocaleCode($store));
329
+
330
+ if (empty($symbol)) {
331
+ $symbol = str_replace('%s', '', $format['pattern']);
332
+ }
333
+
334
+ $ret = array (
335
+ 'rate' => $store->getCurrentCurrencyRate(),
336
+ 'decimals' => $format['precision'],
337
+ 'decimals_separator' => $format['decimalSymbol'],
338
+ 'thousands_separator' => $format['groupSymbol'],
339
+ 'symbol' => $symbol,
340
+ 'after' => $positionPrice == 0 ? true : false,
341
+ );
342
+
343
+ return $ret;
344
+ }
345
+
346
+ /**
347
+ * Format date using current locale options
348
+ *
349
+ * @param timestamp|int
350
+ * @param string $format
351
+ * @param bool $showTime
352
+ * @return string
353
+ */
354
+ public static function formatDate($timestamp = null, $format = 'short', $showTime = false)
355
+ {
356
+ if (empty($timestamp)) {
357
+ return '';
358
+ }
359
+
360
+ $date = Mage::app()->getLocale()->date($timestamp, null, null);
361
+
362
+ return Varien_Date::formatDate($date, $format, $showTime);
363
+ }
364
+
365
+ public static function getAddonOptions($store = null)
366
+ {
367
+ $ret = array();
368
+
369
+ $ret['parent_private_key'] = self::getParentPrivateKey();
370
+ $ret['private_key'] = self::getPrivateKeys();
371
+ $ret['export_status'] = self::getExportStatuses();
372
+
373
+ $ret['last_request'] = self::formatDate(self::getLastRequest(), Mage_Core_Model_Locale::FORMAT_TYPE_MEDIUM, true);
374
+ $ret['last_resync'] = self::formatDate(self::getLastResync(), Mage_Core_Model_Locale::FORMAT_TYPE_MEDIUM, true);
375
+
376
+ $ret['addon_status'] = self::getStatusModule() == 'Y' ? 'enabled' : 'disabled';
377
+
378
+ $ret['addon_version'] = self::getVersion();
379
+ $ret['core_version'] = Mage::getVersion();
380
+
381
+ return $ret;
382
+ }
383
+
384
+ public static function getVersion()
385
+ {
386
+ return self::getSetting('version');
387
+ }
388
+
389
+ public static function getSearchTimeout()
390
+ {
391
+ return self::getSetting('search_timeout');
392
+ }
393
+
394
+ public static function getRequestTimeout()
395
+ {
396
+ return self::getSetting('request_timeout');
397
+ }
398
+
399
+ public static function getAjaxAsyncTimeout()
400
+ {
401
+ return self::getSetting('ajax_async_timeout');
402
+ }
403
+
404
+ public static function getProductsPerPass()
405
+ {
406
+ return self::getSetting('products_per_pass');
407
+ }
408
+
409
+ public static function getMaxErrorCount()
410
+ {
411
+ return self::getSetting('max_error_count');
412
+ }
413
+
414
+ public static function getMaxProcessingThread()
415
+ {
416
+ return self::getSetting('max_processing_thread');
417
+ }
418
+
419
+ public static function getMaxProcessingTime()
420
+ {
421
+ return self::getSetting('max_processing_time');
422
+ }
423
+
424
+ public static function getMaxSearchRequestLength()
425
+ {
426
+ return self::getSetting('max_search_request_length');
427
+ }
428
+
429
+ public static function setApiKey($value, $store = null)
430
+ {
431
+ return self::setSettingStore('api_key', $store, $value, self::CONFIG_PREFIX);
432
+ }
433
+
434
+ public static function getApiKey($store = null)
435
+ {
436
+ return self::getSettingStore('api_key', $store, self::CONFIG_PREFIX);
437
+ }
438
+
439
+ public static function getDate()
440
+ {
441
+ return date('Y-m-d H:i:s');
442
+ }
443
+
444
+ public static function getTime()
445
+ {
446
+ return time();
447
+ }
448
+
449
+
450
+ public static function getStores($curStores = null, $storeIds = null)
451
+ {
452
+ if (!empty($storeIds)) {
453
+ if (!is_array($storeIds)) {
454
+ $curStores = Mage::app()->getStore($storeIds);
455
+ } else {
456
+ $curStores = array();
457
+ foreach ($storeIds as $storeId) {
458
+ $curStores[] = Mage::app()->getStore($storeId);
459
+ }
460
+ }
461
+ }
462
+
463
+ if (!empty($curStores)) {
464
+ if (!is_array($curStores)) {
465
+ $stores = array (
466
+ 0 => $curStores,
467
+ );
468
+ } else {
469
+ $stores = $curStores;
470
+ }
471
+ } else {
472
+ $stores = Mage::app()->getStores();
473
+ }
474
+
475
+ return $stores;
476
+ }
477
+
478
+ /**
479
+ * Set notification message
480
+ *
481
+ * @param string $type notification type (E - error, W - warning, N - notice)
482
+ * @param string $title notification title
483
+ * @param string $message notification message
484
+ */
485
+ public static function setNotification($type = 'N', $title = '', $message = '')
486
+ {
487
+ if (empty($session)) {
488
+ $session = Mage::getSingleton('adminhtml/session');
489
+ }
490
+
491
+ if ($type == 'N') {
492
+ $session->addNotice($title . ': '. $message);
493
+ } elseif ($type == 'W') {
494
+ $session->addWarning($title . ': '. $message);
495
+ } elseif ($type == 'E') {
496
+ $session->addError($title . ': '. $message);
497
+ }
498
+
499
+ return true;
500
+ }
501
+
502
+ public static function httpRequest($method = Zend_Http_Client::POST, $url = '', $data = array(), $cookies = array(), $basicAuth = array(), $timeout = 0, $maxredirects = 5)
503
+ {
504
+ $client = new Zend_Http_Client();
505
+
506
+ $client->setUri($url);
507
+
508
+ $client->setConfig(array(
509
+ 'maxredirects' => $maxredirects,
510
+ 'timeout' => $timeout,
511
+ ));
512
+
513
+ if ($method == Zend_Http_Client::GET) {
514
+ $client->setParameterGet($data);
515
+
516
+ } elseif ($method == Zend_Http_Client::POST) {
517
+ $client->setParameterPost($data);
518
+ }
519
+
520
+ try {
521
+ $response = $client->request($method);
522
+ } catch (Exception $e) {
523
+ self::log($e->getMessage());
524
+
525
+ return null;
526
+ }
527
+
528
+ $responseBody = $response->getBody();
529
+
530
+ // fixme in the future
531
+ // add getHeader()
532
+ //~ return array($response->getHeader(), $response->getBody());
533
+ return array('', $response->getBody());
534
+ }
535
+
536
+ /**
537
+ *
538
+ *
539
+ * @param array $arr_cat
540
+ * @param Mage_Catalog_Model_Category $category
541
+ * @return array
542
+ */
543
+ public static function getAllChildrenCategories(&$arr_cat, $category, $fl_include_cur_cat = true)
544
+ {
545
+ if (empty($arr_cat)) {
546
+ $arr_cat = array();
547
+ }
548
+
549
+ if (!empty($category)) {
550
+ if ($fl_include_cur_cat == true) {
551
+ $arr_cat[] = $category->getId();
552
+ }
553
+
554
+ $children_cat = $category->getChildrenCategories();
555
+
556
+ if (!empty($children_cat)) {
557
+ foreach ($children_cat as $cat) {
558
+ self::getAllChildrenCategories($arr_cat, $cat, $fl_include_cur_cat);
559
+ }
560
+ }
561
+ }
562
+
563
+ return $arr_cat;
564
+ }
565
+
566
+ public static function escapingCharacters($str)
567
+ {
568
+ $ret = '';
569
+
570
+ if ($str != '') {
571
+ $str = trim($str);
572
+
573
+ if ($str != '') {
574
+ $str = str_replace('|', '\|', $str);
575
+ $str = str_replace(',', '\,', $str);
576
+
577
+ $ret = $str;
578
+ }
579
+ }
580
+
581
+ return $ret;
582
+ }
583
+
584
+ public static function getPriceValueFromRequest($dataPrice)
585
+ {
586
+ $ret = '';
587
+ $priceFrom = '';
588
+ $priceTo = '';
589
+
590
+ if (is_array($dataPrice)) {
591
+ // example Array ( [from] => 0 [to] => 33 )
592
+ if (!empty($dataPrice)) {
593
+ if ($dataPrice['from'] != '') {
594
+ $priceFrom = trim($dataPrice['from']);
595
+ }
596
+ if ($dataPrice['to'] != '') {
597
+ $priceTo = trim($dataPrice['to']);
598
+ }
599
+ }
600
+ } elseif ($dataPrice != '') {
601
+ if (strpos($dataPrice, '-') === false) {
602
+ // for 1.6.X versions
603
+ $arrPrice = explode(',', $dataPrice);
604
+
605
+ if (is_array($arrPrice) && (count($arrPrice) >= 2)) {
606
+ $numberRange = (int) reset($arrPrice);
607
+ next($arrPrice);
608
+ $step = (int) current($arrPrice);
609
+
610
+ if ($number_range > 1) {
611
+ $priceFrom = ($numberRange - 1) * $step;
612
+ }
613
+ $priceTo = $numberRange * $step;
614
+ }
615
+ } else {
616
+ // For version 1.7.X versions
617
+ $arrPrice = explode('-', $dataPrice);
618
+ if (is_array($arrPrice) && (count($arrPrice) >= 2)) {
619
+ $priceFrom = (int) reset($arrPrice);
620
+ next($arrPrice);
621
+ $priceTo = (int) current($arrPrice);
622
+ }
623
+ }
624
+ }
625
+
626
+ if (($priceFrom != '') || ($priceTo != '')) {
627
+ $rate = Mage::app()->getStore()->getCurrentCurrencyRate();
628
+
629
+ if ((!$rate) || ($rate == 1)) {
630
+ // nothing
631
+ } else {
632
+ if ($priceFrom != '') {
633
+ $priceFrom /= $rate;
634
+ }
635
+ if ($priceTo != '') {
636
+ $priceTo /= $rate;
637
+ }
638
+ }
639
+ if ($priceFrom != '') {
640
+ $ret .= $priceFrom;
641
+ }
642
+ $ret .= ',';
643
+ if ($priceTo != '') {
644
+ $ret .= $priceTo;
645
+ }
646
+ }
647
+
648
+ return $ret;
649
+ }
650
+
651
+ public static function queueImport($curStore = NULL, $showNotification = true)
652
+ {
653
+ if (!self::checkParentPrivateKey()) {
654
+ return;
655
+ }
656
+
657
+ Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_PREPARE_FULL_IMPORT, NULL, $curStore);
658
+
659
+ $stores = self::getStores($curStore);
660
+
661
+ foreach ($stores as $store) {
662
+ self::setExportStatus(self::EXPORT_STATUS_QUEUED, $store);
663
+ }
664
+
665
+ if ($showNotification == true) {
666
+ self::setNotification('N', Mage::helper('searchanise')->__('Notice'), Mage::helper('searchanise')->__('The product catalog is queued for syncing with Searchanise'));
667
+ }
668
+
669
+ return true;
670
+ }
671
+
672
+ /**
673
+ * Build query from the array
674
+ *
675
+ * @param array $array data to build query from
676
+ * @param string $query part of query to attach new data
677
+ * @param string $prefix prefix
678
+ * @return string well-formed query
679
+ */
680
+ public static function buildQuery($array, $query = '', $prefix = '')
681
+ {
682
+ if (!is_array($array)) { return false; }
683
+
684
+ foreach ($array as $k => $v)
685
+ {
686
+ if (is_array($v)) {
687
+ $query = self::buildQuery($v, $query, rawurlencode(empty($prefix) ? "$k" : $prefix . "[$k]"));
688
+ } else {
689
+ $query .= (!empty($query) ? '&' : '') . (empty($prefix) ? $k : $prefix . rawurlencode("[$k]")). '=' . rawurlencode($v);
690
+ }
691
+ }
692
+
693
+ return $query;
694
+ }
695
+
696
+ public static function setSettingStore($name, $store = null, $value = null, $prefix = 'searchanise/config/')
697
+ {
698
+ if (!empty($name)) {
699
+ if (empty($store)) {
700
+ $store = Mage::app()->getStore();
701
+ }
702
+
703
+ if ($prefix == self::CONFIG_PREFIX) {
704
+ Mage::getModel('searchanise/config')->saveConfig($prefix . $name, $value, 'stores', $store->getId());
705
+ } else {
706
+ $config = new Mage_Core_Model_Config();
707
+ $config->saveConfig($prefix . $name, $value, 'stores', $store->getId());
708
+
709
+ // make changes apply right away
710
+ Mage::getConfig()->cleanCache();
711
+ }
712
+
713
+ return true;
714
+ }
715
+
716
+ return false;
717
+ }
718
+
719
+ public static function getSettingStore($name, $store = null, $prefix = 'searchanise/config/')
720
+ {
721
+ if (!empty($name)) {
722
+ if (empty($store)) {
723
+ $store = Mage::app()->getStore();
724
+ }
725
+
726
+ if ($prefix == self::CONFIG_PREFIX) {
727
+ return Mage::getModel('searchanise/config')->getConfig($prefix . $name, 'stores', $store->getId());
728
+ } else {
729
+ return $store->getConfig($prefix . $name);
730
+ }
731
+ }
732
+
733
+ return null;
734
+ }
735
+
736
+ public static function setSetting($name, $value = null, $prefix = 'searchanise/config/')
737
+ {
738
+ if (!empty($name)) {
739
+ if ($prefix == self::CONFIG_PREFIX) {
740
+ Mage::getModel('searchanise/config')->saveConfig($prefix . $name, $value);
741
+ } else {
742
+ $config = new Mage_Core_Model_Config();
743
+ $config->saveConfig($prefix . $name, $value);
744
+
745
+ // make changes apply right away
746
+ Mage::getConfig()->cleanCache();
747
+ }
748
+
749
+ return true;
750
+ }
751
+
752
+ return false;
753
+ }
754
+
755
+ public static function getSetting($name, $prefix = 'searchanise/config/')
756
+ {
757
+ if (!empty($name)) {
758
+ if ($prefix == self::CONFIG_PREFIX) {
759
+ return Mage::getModel('searchanise/config')->getConfig($prefix . $name);
760
+ } else {
761
+ return Mage::app()->getStore()->getConfig($prefix . $name);
762
+ }
763
+ }
764
+
765
+ return null;
766
+ }
767
+
768
+ public static function setExportStatus($value, $store = null)
769
+ {
770
+ return self::setSettingStore('export_status', $store, $value, self::CONFIG_PREFIX);
771
+ }
772
+
773
+ public static function getExportStatus($store = null)
774
+ {
775
+ return self::getSettingStore('export_status', $store, self::CONFIG_PREFIX);
776
+ }
777
+
778
+ public static function checkExportStatus($store = null)
779
+ {
780
+ self::checkImportIsDone($store);
781
+ return self::getExportStatus($store) == self::EXPORT_STATUS_DONE;
782
+ }
783
+
784
+ public static function getExportStatuses()
785
+ {
786
+ $ret = array();
787
+ $stores = Mage::app()->getStores();
788
+
789
+ if (!empty($stores)) {
790
+ foreach ($stores as $store) {
791
+ $ret[$store->getId()] = self::getExportStatus($store);
792
+ }
793
+ }
794
+
795
+ return $ret;
796
+ }
797
+
798
+ public static function setPrivateKey($value = null, $store = null)
799
+ {
800
+ if (empty($store)) {
801
+ $store = Mage::app()->getStore();
802
+ }
803
+
804
+ if (!empty($store)) {
805
+ self::$privateKeySe[$store->getId()] = $value;
806
+ }
807
+
808
+ return self::setSettingStore('private_key', $store, $value, self::CONFIG_PREFIX);
809
+ }
810
+
811
+ public static function getPrivateKey($store = null, $storeId = null)
812
+ {
813
+ if (!empty($storeId)) {
814
+ $store = Mage::app()->getStore($storeId);
815
+ }
816
+
817
+ if (empty($store)) {
818
+ $store = Mage::app()->getStore(0);
819
+ }
820
+
821
+ if (!empty($store)) {
822
+ if (!isset(self::$privateKeySe[$store->getId()])) {
823
+ self::$privateKeySe[$store->getId()] = self::getSettingStore('private_key', $store, self::CONFIG_PREFIX);
824
+ }
825
+
826
+ return self::$privateKeySe[$store->getId()];
827
+ }
828
+
829
+ return null;
830
+ }
831
+
832
+ public static function checkPrivateKey($store = null, $storeId = null)
833
+ {
834
+ $key = self::getPrivateKey($store, $storeId);
835
+
836
+ return empty($key) ? false : true;
837
+ }
838
+
839
+ public static function getPrivateKeys()
840
+ {
841
+ $ret = array();
842
+ $stores = Mage::app()->getStores();
843
+
844
+ if (!empty($stores)) {
845
+ foreach ($stores as $k_store => $store) {
846
+ $ret[$store->getId()] = self::getPrivateKey($store);
847
+ }
848
+ }
849
+
850
+ return $ret;
851
+ }
852
+
853
+ public static function setParentPrivateKey($value = null)
854
+ {
855
+ self::$parentPrivateKeySe = $value;
856
+
857
+ return self::setSetting('parent_private_key', $value, self::CONFIG_PREFIX);
858
+ }
859
+
860
+ public static function getParentPrivateKey()
861
+ {
862
+ if (!isset(self::$parentPrivateKeySe)) {
863
+ self::$parentPrivateKeySe = self::getSetting('parent_private_key', self::CONFIG_PREFIX);
864
+ }
865
+
866
+ return self::$parentPrivateKeySe;
867
+ }
868
+
869
+ public static function checkParentPrivateKey()
870
+ {
871
+ $parentPrivateKey = self::getParentPrivateKey();
872
+
873
+ return !empty($parentPrivateKey);
874
+ }
875
+
876
+ public static function signup($curStore = null, $showNotification = true, $flSendRequest = true)
877
+ {
878
+ @ignore_user_abort(true);
879
+ @set_time_limit(0);
880
+
881
+ $connected = false;
882
+
883
+ static $isShowed = false;
884
+
885
+ if (!empty($curStore)) {
886
+ $privateKey = self::getPrivateKey($curStore);
887
+ if (empty($privateKey)) {
888
+ //~ return false;
889
+ }
890
+ }
891
+
892
+ $email = Mage::getSingleton('admin/session')->getUser()->getEmail();
893
+
894
+ $stores = self::getStores($curStore);
895
+
896
+ $parentPrivateKey = self::getParentPrivateKey();
897
+
898
+ foreach ($stores as $store) {
899
+ $privateKey = self::getPrivateKey($store);
900
+
901
+ if (!empty($privateKey)) {
902
+ if ($flSendRequest) {
903
+ if ($store->getIsActive()) {
904
+ self::sendAddonStatusRequest('enabled', $store);
905
+ } else {
906
+ self::sendAddonStatusRequest('disabled', $store);
907
+ }
908
+ }
909
+
910
+ continue;
911
+ }
912
+
913
+ if ($showNotification == true && empty($isShowed)) {
914
+ self::echoConnectProgress('Connecting to Searchanise..');
915
+ $isShowed = true;
916
+ }
917
+
918
+ $url = $store->getUrl('', array('_nosid' => true));
919
+
920
+ // need if new store without baseUrl
921
+ if (!(strstr($url, "http"))) {
922
+ $base_url = Mage::app()->getStore()->getBaseUrl();
923
+
924
+ $url = str_replace('index.php/', $base_url, $url);
925
+ }
926
+
927
+ list($h, $res) = self::httpRequest(
928
+ Zend_Http_Client::POST,
929
+ self::getServiceUrl() . '/api/signup',
930
+ array(
931
+ 'url' => $url,
932
+ 'email' => $email,
933
+ 'version' => self::getVersion(),
934
+ 'platform' => self::PLATFORM_NAME,
935
+ 'parent_private_key' => $parentPrivateKey,
936
+ ),
937
+ array(),
938
+ array(),
939
+ self::getRequestTimeout()
940
+ );
941
+
942
+ if ($showNotification == true) {
943
+ self::echoConnectProgress('.');
944
+ }
945
+
946
+ if (!empty($res)) {
947
+ $res = self::parseResponse($res, true);
948
+
949
+ if (is_object($res)) {
950
+ $api_key = (string)$res->api;
951
+ $privateKey = (string)$res->private;
952
+
953
+ if (empty($api_key) || empty($privateKey)) {
954
+ return false;
955
+ }
956
+
957
+ if (empty($parentPrivateKey)) {
958
+ self::setParentPrivateKey($privateKey);
959
+ $parentPrivateKey = $privateKey;
960
+ }
961
+
962
+ self::setApiKey($api_key, $store);
963
+ self::setPrivateKey($privateKey, $store);
964
+
965
+ $connected = true;
966
+
967
+ } else {
968
+ if ($showNotification == true) {
969
+ self::echoConnectProgress(' Error<br />');
970
+ }
971
+
972
+ return false;
973
+ }
974
+ }
975
+
976
+ self::setExportStatus(self::EXPORT_STATUS_NONE, $store);
977
+ self::setUseNavigation(true);
978
+ }
979
+
980
+ if ($connected == true && $showNotification == true) {
981
+ self::echoConnectProgress(' Done<br />');
982
+ self::setNotification('N', Mage::helper('searchanise')->__('Notice'), Mage::helper('searchanise')->__("Congratulations, you've just connected to Searchanise"));
983
+ }
984
+
985
+ return true;
986
+ }
987
+
988
+ public static function getMinMaxProductId()
989
+ {
990
+ $start = 0;
991
+ $max = 0;
992
+ $start_collection = Mage::getModel('catalog/product')
993
+ ->getCollection()
994
+ ->addAttributeToSort('entity_id', Varien_Data_Collection::SORT_ORDER_ASC)
995
+ ->setPageSize(1)
996
+ ->load()
997
+ ->toArray();
998
+
999
+ $max_collection = Mage::getModel('catalog/product')
1000
+ ->getCollection()
1001
+ ->addAttributeToSort('entity_id', Varien_Data_Collection::SORT_ORDER_DESC)
1002
+ ->setPageSize(1)
1003
+ ->load()
1004
+ ->toArray();
1005
+
1006
+ if (!empty($start_collection)) {
1007
+ $start = reset($start_collection);
1008
+ $start = (int) $start['entity_id'];
1009
+ }
1010
+
1011
+ if (!empty($max_collection)) {
1012
+ $max = reset($max_collection);
1013
+ $max = (int) $max['entity_id'];
1014
+ }
1015
+
1016
+ return array($start, $max);
1017
+ }
1018
+
1019
+ public static function getProductIdsFormRange($start, $end, $step, $store = null)
1020
+ {
1021
+ $ret = array();
1022
+
1023
+ $products = Mage::getModel('catalog/product')
1024
+ ->getCollection()
1025
+ ->addFieldToFilter('entity_id', array("from" => $start, "to" => $end))
1026
+ ->setPageSize($step);
1027
+
1028
+ if (!empty($store)) {
1029
+ $products->addStoreFilter($store);
1030
+ }
1031
+
1032
+ $products->load();
1033
+
1034
+ if (!empty($products)) {
1035
+ foreach ($products as $product) {
1036
+ $ret[] = $product->getId();
1037
+ }
1038
+ }
1039
+
1040
+ return $ret;
1041
+ }
1042
+
1043
+ public static function getFilterableFiltersIds($store = null)
1044
+ {
1045
+ $ret = array();
1046
+
1047
+ $filters = Mage::getResourceModel('catalog/product_attribute_collection')
1048
+ ->setItemObjectClass('catalog/resource_eav_attribute')
1049
+ ->addIsFilterableFilter();
1050
+
1051
+ if (!empty($store)) {
1052
+ $filters->addStoreLabel($store->getId());
1053
+ }
1054
+
1055
+ $filters->load();
1056
+
1057
+ if (!empty($filters)) {
1058
+ foreach ($filters as $filter) {
1059
+ $ret[] = $filter->getId();
1060
+ }
1061
+ }
1062
+
1063
+ return $ret;
1064
+ }
1065
+
1066
+ public static function getFilterableInSearchFiltersIds($store = null)
1067
+ {
1068
+ $ret = array();
1069
+
1070
+ $filters = Mage::getResourceModel('catalog/product_attribute_collection')
1071
+ ->setItemObjectClass('catalog/resource_eav_attribute')
1072
+ ->addIsFilterableInSearchFilter();
1073
+
1074
+ if (!empty($store)) {
1075
+ $filters->addStoreLabel($store->getId());
1076
+ }
1077
+
1078
+ $filters->load();
1079
+
1080
+ if (!empty($filters)) {
1081
+ foreach ($filters as $filter) {
1082
+ $ret[] = $filter->getId();
1083
+ }
1084
+ }
1085
+
1086
+ return $ret;
1087
+ }
1088
+
1089
+ public static function getFiltersIds($store = null)
1090
+ {
1091
+ $filterableInSearchFiltersIds = self::getFilterableInSearchFiltersIds($store);
1092
+ $filterableFiltersIds = self::getFilterableFiltersIds($store);
1093
+
1094
+ if (empty($filterableInSearchFiltersIds)) {
1095
+ return $filterableFiltersIds;
1096
+ }
1097
+
1098
+ if (empty($filterableFiltersIds)) {
1099
+ return $filterableInSearchFiltersIds;
1100
+ }
1101
+
1102
+ foreach ($filterableFiltersIds as $key => $value) {
1103
+ if (!in_array($value, $filterableInSearchFiltersIds)) {
1104
+ $filterableInSearchFiltersIds[] = $value;
1105
+ }
1106
+ }
1107
+
1108
+ return $filterableInSearchFiltersIds;
1109
+ }
1110
+
1111
+ public static function checkStartAsync()
1112
+ {
1113
+ $ret = false;
1114
+ $q = Mage::getModel('searchanise/queue')->getNextQueue();
1115
+
1116
+ if (!empty($q)) {
1117
+ //Note: $q['started'] can be in future.
1118
+ if ($q['status'] == Simtech_Searchanise_Model_Queue::STATUS_PROCESSING && ($q['started'] + self::getMaxProcessingTime() > self::getTime())) {
1119
+ $ret = false;
1120
+
1121
+ } elseif ($q['error_count'] == self::getMaxErrorCount()) {
1122
+ $ret = false;
1123
+
1124
+ } else {
1125
+ $ret = true;
1126
+ }
1127
+ }
1128
+
1129
+ return $ret;
1130
+ }
1131
+
1132
+ public static function async()
1133
+ {
1134
+ @ignore_user_abort(true);
1135
+ @set_time_limit(0);
1136
+
1137
+ $xmlHeader = Mage::helper('searchanise/ApiXML')->getXMLHeader();
1138
+ $xmlFooter = Mage::helper('searchanise/ApiXML')->getXMLFooter();
1139
+
1140
+ self::echoConnectProgress('.');
1141
+
1142
+ $q = Mage::getModel('searchanise/queue')->getNextQueue();
1143
+
1144
+ while (!empty($q)) {
1145
+ $xml = '';
1146
+ $status = true;
1147
+ $store = Mage::app()->getStore($q['store_id']);
1148
+ $data = array();
1149
+ if ((!empty($q['data'])) && ($q['data'] != Simtech_Searchanise_Model_Queue::NOT_DATA)) {
1150
+ $data = unserialize($q['data']);
1151
+ }
1152
+
1153
+ $privateKey = self::getPrivateKey($store);
1154
+
1155
+ if (empty($privateKey)) {
1156
+ Mage::getModel('searchanise/queue')->load($q['queue_id'])->delete();
1157
+ $q = array();
1158
+
1159
+ continue;
1160
+ }
1161
+
1162
+ //Note: $q['started'] can be in future.
1163
+ if ($q['status'] == Simtech_Searchanise_Model_Queue::STATUS_PROCESSING && ($q['started'] + self::getMaxProcessingTime() > self::getTime())) {
1164
+ return Simtech_Searchanise_Model_Queue::STATUS_PROCESSING;
1165
+ }
1166
+
1167
+ if ($q['error_count'] == self::getMaxErrorCount()) {
1168
+ self::setExportStatus(self::EXPORT_STATUS_SYNC_ERROR, $store);
1169
+
1170
+ return Simtech_Searchanise_Model_Queue::STATUS_DISABLED;
1171
+ }
1172
+
1173
+ // Set queue to processing state
1174
+ Mage::getModel('searchanise/queue')
1175
+ ->load($q['queue_id'])
1176
+ ->setData('status', Simtech_Searchanise_Model_Queue::STATUS_PROCESSING)
1177
+ ->setData('started', self::getTime())
1178
+ ->save();
1179
+
1180
+ if ($q['action'] == Simtech_Searchanise_Model_Queue::ACT_PREPARE_FULL_IMPORT) {
1181
+ Mage::getModel('searchanise/queue')
1182
+ ->getCollection()
1183
+ ->addFieldToFilter('action', array("neq" => Simtech_Searchanise_Model_Queue::ACT_PREPARE_FULL_IMPORT))
1184
+ ->addFilter('store_id', $store->getId())
1185
+ ->load()
1186
+ ->delete();
1187
+
1188
+ $queueData = array(
1189
+ 'data' => Simtech_Searchanise_Model_Queue::NOT_DATA,
1190
+ 'action' => Simtech_Searchanise_Model_Queue::ACT_START_FULL_IMPORT,
1191
+ 'store_id' => $store->getId(),
1192
+ );
1193
+
1194
+ Mage::getModel('searchanise/queue')->setData($queueData)->save();
1195
+
1196
+ $i = 0;
1197
+ $step = self::getProductsPerPass() * 50;
1198
+
1199
+ $sqls_arr = array();
1200
+
1201
+ list($start, $max) = self::getMinMaxProductId();
1202
+
1203
+ do {
1204
+ $end = $start + $step;
1205
+
1206
+ $_product_ids = self::getProductIdsFormRange($start, $end, $step, $store);
1207
+
1208
+ $start = $end + 1;
1209
+
1210
+ if (empty($_product_ids)) {
1211
+ continue;
1212
+ }
1213
+ $_product_ids = array_chunk($_product_ids, self::getProductsPerPass());
1214
+
1215
+ foreach ($_product_ids as $product_ids) {
1216
+ $sqls_arr[] = array (
1217
+ 'data' => serialize($product_ids),
1218
+ 'action' => Simtech_Searchanise_Model_Queue::ACT_UPDATE,
1219
+ 'store_id' => $store->getId(),
1220
+ );
1221
+ }
1222
+
1223
+ // fixme if need
1224
+ // need change one sql if exist opportunity
1225
+ /*if (count($sqls_arr) >= 30) {
1226
+ //~ db_query("INSERT INTO ?:se_queue (`data`, `action`, `lang_code`) VALUES " . join(',', $sqls_arr));
1227
+
1228
+ self::echoConnectProgress('.');
1229
+ $sqls_arr = array();
1230
+ }*/
1231
+ } while ($end <= $max);
1232
+
1233
+ if (count($sqls_arr) > 0) {
1234
+ foreach ($sqls_arr as $queueData) {
1235
+ Mage::getModel('searchanise/queue')->setData($queueData)->save();
1236
+ }
1237
+ }
1238
+
1239
+ self::echoConnectProgress('.');
1240
+
1241
+ //
1242
+ // reSend all active filters
1243
+ //
1244
+
1245
+ $queueData = array(
1246
+ 'data' => Simtech_Searchanise_Model_Queue::NOT_DATA,
1247
+ 'action' => Simtech_Searchanise_Model_Queue::ACT_FACET_DELETE_ALL,
1248
+ 'store_id' => $store->getId(),
1249
+ );
1250
+ Mage::getModel('searchanise/queue')->setData($queueData)->save();
1251
+
1252
+ $filterIds = self::getFiltersIds($store);
1253
+
1254
+ if (!empty($filterIds)) {
1255
+ $queueData = array(
1256
+ 'data' => serialize($filterIds),
1257
+ 'action' => Simtech_Searchanise_Model_Queue::ACT_FACET_UPDATE,
1258
+ 'store_id' => $store->getId(),
1259
+ );
1260
+
1261
+ Mage::getModel('searchanise/queue')->setData($queueData)->save();
1262
+ }
1263
+
1264
+ // add facet-categories
1265
+ {
1266
+ $queueData = array(
1267
+ 'data' => serialize(Simtech_Searchanise_Model_Queue::DATA_FACET_CATEGORIES),
1268
+ 'action' => Simtech_Searchanise_Model_Queue::ACT_FACET_UPDATE,
1269
+ 'store_id' => $store->getId(),
1270
+ );
1271
+
1272
+ Mage::getModel('searchanise/queue')->setData($queueData)->save();
1273
+ }
1274
+
1275
+ // add facet-prices
1276
+ {
1277
+ $queueData = array(
1278
+ 'data' => serialize(Simtech_Searchanise_Model_Queue::DATA_FACET_PRICES),
1279
+ 'action' => Simtech_Searchanise_Model_Queue::ACT_FACET_UPDATE,
1280
+ 'store_id' => $store->getId(),
1281
+ );
1282
+
1283
+ Mage::getModel('searchanise/queue')->setData($queueData)->save();
1284
+ }
1285
+
1286
+ // add facet-tags
1287
+ {
1288
+ $queueData = array(
1289
+ 'data' => serialize(Simtech_Searchanise_Model_Queue::DATA_FACET_TAGS),
1290
+ 'action' => Simtech_Searchanise_Model_Queue::ACT_FACET_UPDATE,
1291
+ 'store_id' => $store->getId(),
1292
+ );
1293
+
1294
+ Mage::getModel('searchanise/queue')->setData($queueData)->save();
1295
+ }
1296
+
1297
+ $queueData = array(
1298
+ 'data' => Simtech_Searchanise_Model_Queue::NOT_DATA,
1299
+ 'action' => Simtech_Searchanise_Model_Queue::ACT_END_FULL_IMPORT,
1300
+ 'store_id' => $store->getId(),
1301
+ );
1302
+
1303
+ Mage::getModel('searchanise/queue')->setData($queueData)->save();
1304
+
1305
+ $status = true;
1306
+
1307
+ } elseif ($q['action'] == Simtech_Searchanise_Model_Queue::ACT_START_FULL_IMPORT) {
1308
+ $status = self::sendRequest('/api/state/update', $privateKey, array('full_import' => self::EXPORT_STATUS_START), true);
1309
+
1310
+ if ($status == true) {
1311
+ self::setExportStatus(self::EXPORT_STATUS_PROCESSING, $store);
1312
+ }
1313
+
1314
+ } elseif ($q['action'] == Simtech_Searchanise_Model_Queue::ACT_END_FULL_IMPORT) {
1315
+ $status = self::sendRequest('/api/state/update', $privateKey, array('full_import' => self::EXPORT_STATUS_DONE), true);
1316
+
1317
+ if ($status == true) {
1318
+ self::setExportStatus(self::EXPORT_STATUS_SENT, $store);
1319
+ self::setLastResync(self::getTime());
1320
+ }
1321
+
1322
+ } elseif ($q['action'] == Simtech_Searchanise_Model_Queue::ACT_FACET_DELETE_ALL) {
1323
+ $status = self::sendRequest('/api/facets/delete', $privateKey, array('all' => true), true);
1324
+
1325
+ } elseif ($q['action'] == Simtech_Searchanise_Model_Queue::ACT_FACET_UPDATE) {
1326
+ if ($data == Simtech_Searchanise_Model_Queue::DATA_FACET_CATEGORIES) {
1327
+ $xml .= Mage::helper('searchanise/ApiXML')->generateFacetXMLCategories();
1328
+
1329
+ } elseif ($data == Simtech_Searchanise_Model_Queue::DATA_FACET_PRICES) {
1330
+ $xml .= Mage::helper('searchanise/ApiXML')->generateFacetXMLPrices();
1331
+
1332
+ } elseif ($data == Simtech_Searchanise_Model_Queue::DATA_FACET_TAGS) {
1333
+ $xml .= Mage::helper('searchanise/ApiXML')->generateFacetXMLTags();
1334
+
1335
+ } else {
1336
+ $xml .= Mage::helper('searchanise/ApiXML')->generateFacetXMLFilters($data, $store);
1337
+ }
1338
+
1339
+ if (!empty($xml)) {
1340
+ $status = self::sendRequest('/api/facets/update', $privateKey, array('data' => $xmlHeader . $xml . $xmlFooter), true);
1341
+ }
1342
+
1343
+ } elseif ($q['action'] == Simtech_Searchanise_Model_Queue::ACT_FACET_DELETE) {
1344
+ if (!empty($data)) {
1345
+ foreach ($data as $facetAttribute) {
1346
+ $status = self::sendRequest('/api/facets/delete', $privateKey, array('attribute' => $facetAttribute), true);
1347
+
1348
+ self::echoConnectProgress('.');
1349
+
1350
+ if ($status == false) {
1351
+ break;
1352
+ }
1353
+ }
1354
+ }
1355
+
1356
+ } elseif ($q['action'] == Simtech_Searchanise_Model_Queue::ACT_UPDATE) {
1357
+ $xml .= Mage::helper('searchanise/ApiXML')->generateProductsXML($data, $store);
1358
+
1359
+ if (!empty($xml)) {
1360
+ if (function_exists('gzcompress')) {
1361
+ $data = gzcompress($xmlHeader . $xml . $xmlFooter, self::COMPRESS_RATE);
1362
+ } else {
1363
+ $data = $xmlHeader . $xml . $xmlFooter;
1364
+ }
1365
+ $status = self::sendRequest('/api/items/update', $privateKey, array('data' => $data), true);
1366
+ }
1367
+
1368
+ } elseif ($q['action'] == Simtech_Searchanise_Model_Queue::ACT_DELETE) {
1369
+ foreach ($data as $product_id) {
1370
+ $status = self::sendRequest('/api/items/delete', $privateKey, array('id' => $product_id), true);
1371
+
1372
+ self::echoConnectProgress('.');
1373
+
1374
+ if ($status == false) {
1375
+ break;
1376
+ }
1377
+ }
1378
+
1379
+ } elseif ($q['action'] == Simtech_Searchanise_Model_Queue::ACT_DELETE_ALL) {
1380
+ $status = self::sendRequest('/api/items/delete', $privateKey, array('all' => true), true);
1381
+
1382
+ } elseif ($q['action'] == Simtech_Searchanise_Model_Queue::ACT_PHRASE) {
1383
+ foreach ($data as $phrase) {
1384
+ $status = self::sendRequest('/api/phrases/update', $privateKey, array('phrase' => $phrase), true);
1385
+
1386
+ self::echoConnectProgress('.');
1387
+
1388
+ if ($status == false) {
1389
+ break;
1390
+ }
1391
+ }
1392
+ }
1393
+
1394
+ // Change queue item status
1395
+ if ($status == true) {
1396
+ Mage::getModel('searchanise/queue')->load($q['queue_id'])->delete();
1397
+ $q = Mage::getModel('searchanise/queue')->getNextQueue($q['queue_id']);
1398
+ } else {
1399
+ $nextStartedTime = (self::getTime() - self::getMaxProcessingTime()) + $q['error_count'] * 60;
1400
+
1401
+ $modelQueue = Mage::getModel('searchanise/queue')->load($q['queue_id']);
1402
+
1403
+ $modelQueue
1404
+ ->setData('status', Simtech_Searchanise_Model_Queue::STATUS_PROCESSING)
1405
+ ->setData('error_count', $modelQueue->getData('error_count') + 1)
1406
+ ->setData('started', $nextStartedTime)
1407
+ ->save();
1408
+
1409
+ break; //try later
1410
+ }
1411
+ self::echoConnectProgress('.');
1412
+ }
1413
+
1414
+ return 'OK';
1415
+ }
1416
+
1417
+ public static function echoConnectProgress($text)
1418
+ {
1419
+ // It is commented out as far as the warning occurs
1420
+ //~ echo $text;
1421
+ }
1422
+
1423
+ public static function sendAddonStatusRequest($status = 'enabled', $curStore = NULL)
1424
+ {
1425
+ $stores = self::getStores($curStore);
1426
+
1427
+ if (!empty($stores)) {
1428
+ foreach ($stores as $store) {
1429
+ $privateKey = self::getPrivateKey($store);
1430
+ self::sendRequest('/api/state/update', $privateKey, array('addon_status' => $status), true);
1431
+ }
1432
+ }
1433
+ }
1434
+
1435
+ public static function sendRequest($urlPart, $privateKey, $data, $onlyHttp = true)
1436
+ {
1437
+ $ret = null;
1438
+
1439
+ if (!empty($privateKey)) {
1440
+ $params = array('private_key' => $privateKey) + $data;
1441
+
1442
+ list($h, $result) = self::httpRequest(Zend_Http_Client::POST, self::getServiceUrl($onlyHttp) . $urlPart, $params, array(), array(), self::getRequestTimeout());
1443
+
1444
+ $ret = self::parseResponse($result, false);
1445
+
1446
+ self::setLastRequest(self::getTime());
1447
+ }
1448
+
1449
+ return $ret;
1450
+ }
1451
+
1452
+ /**
1453
+ * Parse response from service
1454
+ *
1455
+ * @param string $res xml service response
1456
+ * @return mixed false if errors returned, true if response is ok, xml object if data was passed in the response
1457
+ */
1458
+ public static function parseResponse($res, $showNotification = false)
1459
+ {
1460
+ $xml = simplexml_load_string($res, null, LIBXML_NOERROR);
1461
+
1462
+ if (empty($res) || $xml === false) {
1463
+ return false;
1464
+ }
1465
+
1466
+ if (!empty($xml->error)) {
1467
+ foreach ($xml->error as $e) {
1468
+ if ($showNotification == true) {
1469
+ self::setNotification('E', Mage::helper('searchanise')->__('Error'), 'Searchanise: ' . (string)$e);
1470
+ }
1471
+ }
1472
+
1473
+ return false;
1474
+ } elseif (strtolower($xml->getName()) == 'ok') {
1475
+ return true;
1476
+ } else {
1477
+ return $xml;
1478
+ }
1479
+ }
1480
+
1481
+ public static function parseStateResponse($xml, $element = false)
1482
+ {
1483
+ $res = array();
1484
+ if (!is_object($xml)) {
1485
+ return false;
1486
+ }
1487
+
1488
+ if ($xml->getName() == 'variable') {
1489
+ foreach ($xml as $v) {
1490
+ $res[$v->getName()] = (string)$v;
1491
+ }
1492
+ } else {
1493
+ return false;
1494
+ }
1495
+
1496
+ if (!empty($element)) {
1497
+ $res = isset($res[$element])? $res[$element] : false;
1498
+ }
1499
+
1500
+ return $res;
1501
+ }
1502
+
1503
+ public static function deleteKeys($stores = null)
1504
+ {
1505
+ if (empty($stores)) {
1506
+ $stores = Mage::app()->getStores();
1507
+ }
1508
+
1509
+ if (!empty($stores)) {
1510
+ foreach ($stores as $store) {
1511
+ self::sendAddonStatusRequest('deleted', $store);
1512
+
1513
+ self::setApiKey(null, $store);
1514
+ self::setPrivateKey(null, $store);
1515
+ self::setExportStatus(null, $store);
1516
+
1517
+ self::setUseNavigation(true, $store);
1518
+
1519
+ Mage::getModel('searchanise/queue')->deleteKeys($store);
1520
+ }
1521
+ }
1522
+
1523
+ return true;
1524
+ }
1525
+
1526
+ public static function checkImportIsDone($curStore = null)
1527
+ {
1528
+ $stores = self::getStores($curStore);
1529
+
1530
+ $skipTimeCheck = false;
1531
+
1532
+ foreach ($stores as $store) {
1533
+ if (self::getExportStatus($store) == self::EXPORT_STATUS_SENT && ((self::getTime() - self::getLastRequest()) > self::getRequestTimeout() || $skipTimeCheck == true)) {
1534
+ $xml = self::sendRequest('/api/state/get', self::getPrivateKey($store), array('status' => '', 'full_import' => ''), true);
1535
+
1536
+ $variables = self::parseStateResponse($xml);
1537
+
1538
+ if ((!empty($variables)) &&
1539
+ (isset($variables['status'])) &&
1540
+ ($variables['status'] == self::STATUS_NORMAL) &&
1541
+ (isset($variables['full_import'])) &&
1542
+ ($variables['full_import'] == self::EXPORT_STATUS_DONE)) {
1543
+ $skipTimeCheck = true;
1544
+ self::setExportStatus(self::EXPORT_STATUS_DONE, $store);
1545
+ }
1546
+ }
1547
+ }
1548
+
1549
+ if ($skipTimeCheck == true) {
1550
+ // nothing
1551
+ }
1552
+ }
1553
+
1554
+ public static function getPriceFilters($store = null)
1555
+ {
1556
+ $filters = Mage::getResourceModel('catalog/product_attribute_collection')
1557
+ ->setItemObjectClass('catalog/resource_eav_attribute')
1558
+ ->addIsFilterableFilter()
1559
+ ->addFieldToFilter('frontend_input', array('eq' => 'price'));
1560
+
1561
+
1562
+ if (!empty($store)) {
1563
+ $filters->addStoreLabel($store->getId());
1564
+ }
1565
+
1566
+ $filters->load();
1567
+
1568
+ return $filters;
1569
+ }
1570
+
1571
+ public static function getStoreByWebsiteIds($websiteIds = array())
1572
+ {
1573
+ $ret = array();
1574
+
1575
+ if (!empty($websiteIds)) {
1576
+ if (!is_array($websiteIds)) {
1577
+ $websiteIds = array(
1578
+ 0 => $websiteIds
1579
+ );
1580
+ }
1581
+
1582
+ $stores = Mage::app()->getStores();
1583
+
1584
+ if (!empty($stores)) {
1585
+ foreach ($stores as $k => $store) {
1586
+ $websiteId = $store->getWebsite()->getId();
1587
+
1588
+ if (in_array($websiteId, $websiteIds)) {
1589
+ $ret[] = $store->getId();
1590
+ }
1591
+ }
1592
+ }
1593
+ }
1594
+
1595
+ return $ret;
1596
+ }
1597
+
1598
+ public static function getStoreByWebsiteCodes($websiteCodes = array())
1599
+ {
1600
+ $ret = array();
1601
+
1602
+ if (!empty($websiteCodes)) {
1603
+ if (!is_array($websiteCodes)) {
1604
+ $websiteCodes = array(
1605
+ 0 => $websiteCodes
1606
+ );
1607
+ }
1608
+ $stores = Mage::app()->getStores();
1609
+
1610
+ if (!empty($stores)) {
1611
+ foreach ($stores as $k => $store) {
1612
+ $websiteCode = $store->getWebsite()->getCode();
1613
+
1614
+ if (in_array($websiteCode, $websiteCodes)) {
1615
+ $ret[] = $store->getId();
1616
+ }
1617
+ }
1618
+ }
1619
+ }
1620
+
1621
+ return $ret;
1622
+ }
1623
+
1624
+ public static function changeAmpersand($str = '')
1625
+ {
1626
+ if (!empty($str)) {
1627
+ if (strpos('&amp;', $str) !== false) {
1628
+ return $str;
1629
+ }
1630
+
1631
+ if (strpos('&', $str) !== false) {
1632
+ return str_replace('&','&amp;',$str);
1633
+ }
1634
+ }
1635
+
1636
+ return $str;
1637
+ }
1638
+
1639
+ function printR()
1640
+ {
1641
+ static $count = 0;
1642
+ $args = func_get_args();
1643
+
1644
+ if (!empty($args)) {
1645
+ echo '<ol style="font-family: Courier; font-size: 12px; border: 1px solid #dedede; background-color: #efefef; float: left; padding-right: 20px;">';
1646
+ foreach ($args as $k => $v) {
1647
+ $v = htmlspecialchars(print_r($v, true));
1648
+ if ($v == '') {
1649
+ $v = ' ';
1650
+ }
1651
+
1652
+ echo '<li><pre>' . $v . "\n" . '</pre></li>';
1653
+ }
1654
+ echo '</ol><div style="clear:left;"></div>';
1655
+ }
1656
+ $count++;
1657
+ }
1658
+
1659
+ public static function log($message = '', $type = 'Error')
1660
+ {
1661
+ Mage::log("Searchanise # {$type}: {$message}");
1662
+
1663
+ return true;
1664
+ }
1665
+ }
app/code/community/Simtech/Searchanise/Helper/ApiXML.php ADDED
@@ -0,0 +1,625 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ class Simtech_Searchanise_Helper_ApiXML extends Mage_Core_Helper_Data
15
+ {
16
+ const XML_END_LINE = "\n";
17
+
18
+ public static function getStockItem($product, $store = null)
19
+ {
20
+ $stockItem = null;
21
+
22
+ if (Mage::helper('catalog')->isModuleEnabled('Mage_CatalogInventory')) {
23
+ $stockItem = Mage::getModel('cataloginventory/stock_item')
24
+ ->loadByProduct($product);
25
+ }
26
+
27
+ return $stockItem;
28
+ }
29
+
30
+ public static function getTagCollection($product, $store = null)
31
+ {
32
+ $tagCollection = Mage::getModel('tag/tag')
33
+ ->getResourceCollection()
34
+ ->setFlag('relation', true)
35
+ ->setActiveFilter();
36
+
37
+ if (!empty($store)) {
38
+ $tagCollection->addStoreFilter($store->getId(), true);
39
+ }
40
+
41
+ return $tagCollection
42
+ ->addPopularity()
43
+ ->addStatusFilter(Mage::getModel('tag/tag')->getApprovedStatus())
44
+ ->addStoresVisibility()
45
+ ->addProductFilter($product->getId())
46
+ ->load();
47
+ }
48
+
49
+ public static function generateProductXML($product, $store = null)
50
+ {
51
+ $entry = '<entry>' . self::XML_END_LINE;
52
+ $entry .= '<id>' . $product->getId() . '</id>' . self::XML_END_LINE;
53
+
54
+ $entry .= '<title><![CDATA[' . $product->getName() . ']]></title>' . self::XML_END_LINE;
55
+
56
+ $summary = $product->getData('short_description');
57
+
58
+ if ($summary == '') {
59
+ $summary = $product->getData('description');
60
+ }
61
+ $entry .= '<summary><![CDATA[' . $summary. ']]></summary>' . self::XML_END_LINE;
62
+
63
+ $productUrl = $product->getProductUrl(false);
64
+ $productUrl = Mage::helper('searchanise/ApiSe')->changeAmpersand($productUrl);
65
+ $entry .= '<link href="' . $productUrl . '" />' . self::XML_END_LINE;
66
+
67
+ // fixme in the future
68
+ // maybe exist simple solution get customerGroupPrices
69
+ $customerGroups = Mage::getModel('customer/group')->getCollection()->load();
70
+ $defaultPrice = '';
71
+
72
+ if ($customerGroups) {
73
+ if (($product->getData('type_id') == Mage_Catalog_Model_Product_Type::TYPE_BUNDLE) ||
74
+ ($product->getData('type_id') == Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE)) {
75
+ $productsCustomerGroup = self::getProduct($product->getId(), $store, true);
76
+ if ($productsCustomerGroup) {
77
+ foreach ($productsCustomerGroup as $productCustomerGroup) {
78
+ $defaultPrice = $productCustomerGroup->getData('min_price');
79
+ break;
80
+ }
81
+ }
82
+ }
83
+
84
+ foreach ($customerGroups as $kCostomerGroup => $customerGroup) {
85
+ $price = '';
86
+ $minPrice = '';
87
+
88
+ if (($product->getData('type_id') == Mage_Catalog_Model_Product_Type::TYPE_BUNDLE) ||
89
+ ($product->getData('type_id') == Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE)) {
90
+ $price = $defaultPrice;
91
+ } else {
92
+ $productsCustomerGroup = self::getProduct($product->getId(), $store, false, $customerGroup->getId());
93
+ if ($productsCustomerGroup) {
94
+ foreach ($productsCustomerGroup as $productCustomerGroup) {
95
+ $price = $productCustomerGroup->getData('price');
96
+ $minPrice = $productCustomerGroup->getData('min_price');
97
+ break;
98
+ }
99
+ }
100
+ }
101
+
102
+ if ($minPrice != '') {
103
+ $price = $minPrice;
104
+ }
105
+
106
+ if ($price != '') {
107
+ $price = round($price, Mage::helper('searchanise/ApiSe')->getFloatPrecision());
108
+ }
109
+
110
+ if ($customerGroup->getId() == Mage_Customer_Model_Group::NOT_LOGGED_IN_ID) {
111
+ // Uncomment the lines below
112
+ // if use special withnout "From Date" and "To Date"
113
+ // $specialPrice = $product->getData('special_price');
114
+ // if ($specialPrice != '') {
115
+ // $price = $specialPrice;
116
+ // }
117
+ $entry .= '<cs:price>' . $price . '</cs:price>'. self::XML_END_LINE;
118
+ $defaultPrice = $price;
119
+ }
120
+ $label_ = Mage::helper('searchanise/ApiSe')->getLabelForPricesUsergroup() . $customerGroup->getId();
121
+ $entry .= '<cs:attribute name="' . $label_ . '" type="float">' . $price . '</cs:attribute>' . self::XML_END_LINE;
122
+ }
123
+ }
124
+
125
+ $entry .= '<cs:product_code><![CDATA[' . $product->getSku() . ']]></cs:product_code>' . self::XML_END_LINE;
126
+ // <quantity>
127
+ {
128
+ $quantity = 1;
129
+ $stockItem = self::getStockItem($product);
130
+ if ($stockItem) {
131
+ $manageStock = null;
132
+ if ($stockItem->getData('use_config_manage_stock')) {
133
+ $manageStock = Mage::getStoreConfig(Mage_CatalogInventory_Model_Stock_Item::XML_PATH_MANAGE_STOCK);
134
+ } else {
135
+ $manageStock = $stockItem->getData('manage_stock');
136
+ }
137
+
138
+ if (!$manageStock) {
139
+ $quantity = 1;
140
+ } else {
141
+ $isInStock = $stockItem->getIsInStock();
142
+ if (!empty($isInStock)) {
143
+ $quantity = $stockItem->getQty();
144
+ } else {
145
+ $quantity = 0;
146
+ }
147
+ }
148
+ }
149
+
150
+ $entry .= '<cs:quantity>' . ceil($quantity) . '</cs:quantity>' . self::XML_END_LINE;
151
+ $entry .= '<cs:attribute name="is_in_stock" type="text">' . ($quantity > 0) . '</cs:attribute>' . self::XML_END_LINE;
152
+ $quantity = round($quantity, Mage::helper('searchanise/ApiSe')->getFloatPrecision());
153
+ $entry .= '<cs:attribute name="quantity_decimals" type="float">' . $quantity . '</cs:attribute>' . self::XML_END_LINE;
154
+ }
155
+ // </quantity>
156
+
157
+ // <image_link>
158
+ {
159
+ $image_link = '';
160
+ $small_image = null;
161
+ // Uncomment the lines below if it is necessary to send image icons.
162
+ //~ $small_image = $product->getData('small_image');
163
+
164
+ if (!empty($small_image) && $small_image != 'no_selection') {
165
+ $image_link = $product->getSmallImageUrl();
166
+
167
+ } else {
168
+ $image = $product->getData('image');
169
+
170
+ if (!empty($image) && $image != 'no_selection') {
171
+ $image_link = $product->getImageUrl();
172
+ } else {
173
+ $thumbnail = $product->getData('thumbnail');
174
+
175
+ if (!empty($thumbnail) && $thumbnail != 'no_selection') { $image_link = $product->getThumbnailUrl(); }
176
+ }
177
+ }
178
+
179
+ $entry .= '<cs:image_link><![CDATA[' . $image_link . ']]></cs:image_link>' . self::XML_END_LINE;
180
+ }
181
+ // </image_link>
182
+
183
+ // <attributes_position>
184
+ {
185
+ $entry .= '<cs:attribute name="position" type="int">';
186
+
187
+ // fixme in the feature
188
+ // sort by "position" disabled
189
+ $entry .= $product->getData('position');
190
+
191
+ $entry .= '</cs:attribute>' . self::XML_END_LINE;
192
+ }
193
+ // </attributes_position>
194
+
195
+ // <attributes>
196
+ {
197
+ //~ $product->getAttributes();
198
+ $attributes = Mage::getResourceModel('catalog/product_attribute_collection');
199
+ $attributes
200
+ ->setItemObjectClass('catalog/resource_eav_attribute')
201
+ ->setOrder('position', 'ASC')
202
+ ->load();
203
+
204
+ if (!empty($attributes)) {
205
+ foreach ($attributes as $attribute) {
206
+ $inputType = $attribute->getData('frontend_input');
207
+
208
+ if ($inputType == 'price') {
209
+ $entry .= '<cs:attribute name="attribute_' . $attribute->getId() . '" type="float">';
210
+ $entry .= $defaultPrice;
211
+ $entry .= '</cs:attribute>' . self::XML_END_LINE;
212
+
213
+ } elseif ($inputType == 'select') {
214
+ $entry .= '<cs:attribute name="attribute_' . $attribute->getId() . '" type="text">';
215
+
216
+ $value = (int) $product->getData($attribute->getAttributeCode());
217
+ if (!empty($value)) {
218
+ $entry .= $value;
219
+ }
220
+
221
+ $entry .= '</cs:attribute>' . self::XML_END_LINE;
222
+
223
+ } elseif ($inputType == 'multiselect') {
224
+ $entry .= '<cs:attribute name="attribute_' . $attribute->getId() . '" type="text">';
225
+ // fixme in the future
226
+ // need for fixed bug of Server
227
+ $entry .= ' ';
228
+
229
+ $values = $product->getData($attribute->getAttributeCode());
230
+ if (!empty($values)) {
231
+ $arr_values = explode(',', $values);
232
+ if (!empty($arr_values)) {
233
+ foreach ($arr_values as $value) {
234
+ if (!empty($value)) {
235
+ $entry .= '<value>' . $value . '</value>';
236
+ }
237
+ }
238
+ }
239
+ }
240
+
241
+ $entry .= '</cs:attribute>' . self::XML_END_LINE;
242
+
243
+ } elseif (($inputType == 'text') || ($inputType == 'textarea')) {
244
+ $value = $product->getData($attribute->getAttributeCode());
245
+
246
+ if ($value != '') {
247
+ $entry .= '<cs:attribute name="attribute_' . $attribute->getId() . '" type="text" text_search="Y" weight="0">';
248
+
249
+ $entry .= '<![CDATA[' . $value . ']]>';
250
+
251
+ $entry .= '</cs:attribute>' . self::XML_END_LINE;
252
+ }
253
+ } else {
254
+ // attribute is not filtrable
255
+ }
256
+ }
257
+ }
258
+ }
259
+ // </attributes>
260
+
261
+ // <categories>
262
+ {
263
+ $entry .= '<cs:attribute name="categories" type="text">';
264
+ // need, it's important
265
+ $entry .= ' ';
266
+ $category_ids = $product->getCategoryIds();
267
+ if (!empty($category_ids)) {
268
+ foreach ($category_ids as $cat_key => $category_id) {
269
+ $entry .= '<value>' . $category_id . '</value>';
270
+ }
271
+ }
272
+ $entry .= '</cs:attribute>' . self::XML_END_LINE;
273
+ }
274
+ // </categories>
275
+
276
+ // <status>
277
+ $entry .= '<cs:attribute name="status" type="text">' . $product->getStatus() . '</cs:attribute>' . self::XML_END_LINE;
278
+ // </status>
279
+
280
+ // <visibility>
281
+ $entry .= '<cs:attribute name="visibility" type="text">' . $product->getData('visibility'). '</cs:attribute>' . self::XML_END_LINE;
282
+ // </visibility>
283
+
284
+ // <tags>
285
+ {
286
+ $entry .= '<cs:attribute name="tags" type="text">';
287
+ // fixme in the future
288
+ // need for fixed bug of Server
289
+ $entry .= ' ';
290
+
291
+ $tags = self::getTagCollection($product, $store);
292
+
293
+ if (!empty($tags)) {
294
+ foreach ($tags as $tag){
295
+ if (!empty($tag)){
296
+ $entry .= '<value>' . $tag->getId() . '</value>';
297
+ }
298
+ }
299
+ }
300
+
301
+ $entry .= '</cs:attribute>' . self::XML_END_LINE;
302
+ }
303
+ // </tags>
304
+
305
+ $entry .= '</entry>' . self::XML_END_LINE;
306
+
307
+ return $entry;
308
+ }
309
+
310
+ public static function getOptionCollection($filter, $store = null)
311
+ {
312
+ // not used in current module
313
+ $optionCollection = Mage::getResourceModel('eav/entity_attribute_option_collection');
314
+
315
+ if (!empty($store)) {
316
+ $optionCollection->setStoreFilter($store); //fixme need check
317
+ }
318
+
319
+ return $optionCollection
320
+ ->setAttributeFilter($filter->getId())
321
+ ->setPositionOrder('desc', true)
322
+ ->load();
323
+ }
324
+
325
+ public static function getPriceNavigationStep($store = null)
326
+ {
327
+ if (empty($store)) {
328
+ $store = Mage::app()->getStore(0);
329
+ }
330
+
331
+ $priceRangeCalculation = $store->getConfig(Mage_Catalog_Model_Layer_Filter_Price::XML_PATH_RANGE_CALCULATION);
332
+
333
+ if ($priceRangeCalculation == Mage_Catalog_Model_Layer_Filter_Price::RANGE_CALCULATION_MANUAL) {
334
+ return $store->getConfig(Mage_Catalog_Model_Layer_Filter_Price::XML_PATH_RANGE_STEP);
335
+ }
336
+
337
+ return null;
338
+ }
339
+
340
+ public static function generateFacetXMLFromFilter($filter, $store = null)
341
+ {
342
+ $entry = '<entry>' . self::XML_END_LINE;
343
+ $entry .= '<title><![CDATA[' . $filter->getData('frontend_label') . ']]></title>' . self::XML_END_LINE;
344
+ $entry .= '<cs:position>' . $filter->getPosition() . '</cs:position>' . self::XML_END_LINE;
345
+
346
+ $inputType = $filter->getData('frontend_input');
347
+
348
+ $entry .= '<cs:attribute>attribute_' . $filter->getId() . '</cs:attribute>' . self::XML_END_LINE;
349
+
350
+ // "Can be used only with catalog input type Dropdown, Multiple Select and Price".
351
+ if (($inputType == 'select') || ($inputType == 'multiselect')) {
352
+ $entry .= '<cs:type>select</cs:type>' . self::XML_END_LINE;
353
+
354
+ } elseif ($inputType == 'price') {
355
+ $entry .= '<cs:type>dynamic</cs:type>' . self::XML_END_LINE;
356
+ $step = self::getPriceNavigationStep($store);
357
+
358
+ if (!empty($step)) {
359
+ $entry .= '<cs:min_range>' . $step . '</cs:min_range>' . self::XML_END_LINE;
360
+ }
361
+
362
+ // attribute is not filtrable
363
+ } else {
364
+ return '';
365
+ }
366
+
367
+ $entry .= '</entry>' . self::XML_END_LINE;
368
+
369
+ return $entry;
370
+ }
371
+
372
+ public static function generateFacetXMLFromCustom($title = '', $position = 0, $attribute = '', $type = '')
373
+ {
374
+ $entry = '<entry>' . self::XML_END_LINE;
375
+
376
+ $entry .= '<title><![CDATA[' . $title .']]></title>' . self::XML_END_LINE;
377
+ $entry .= '<cs:position>' . $position . '</cs:position>' . self::XML_END_LINE;
378
+ $entry .= '<cs:attribute>' . $attribute . '</cs:attribute>' . self::XML_END_LINE;
379
+ $entry .= '<cs:type>' . $type .'</cs:type>' . self::XML_END_LINE;
380
+
381
+ $entry .= '</entry>' . self::XML_END_LINE;
382
+
383
+ return $entry;
384
+ }
385
+
386
+ private static function getProduct($productIds = null, $store = null, $flAddMinimalPrice = true, $customerGroupId = null)
387
+ {
388
+ $products = Mage::getModel('catalog/product')
389
+ ->getCollection()
390
+ ->addAttributeToSelect('*');
391
+
392
+ if (!empty($store)) {
393
+ $products
394
+ ->setStoreId($store)
395
+ ->addStoreFilter($store);
396
+ } else {
397
+ $products->setStoreId(Mage::app()->getStores());
398
+ }
399
+
400
+ if (!empty($productIds)) {
401
+ if (is_array($productIds)) {
402
+ $products->addFieldToFilter('entity_id', array('in' => $productIds));
403
+ } else {
404
+ $products->addFieldToFilter('entity_id', array('eq' => $productIds));
405
+ }
406
+ }
407
+
408
+ if ($flAddMinimalPrice == true) {
409
+ $products->addMinimalPrice($customerGroupId);
410
+ }
411
+
412
+ if ($customerGroupId) {
413
+ if (!$store) {
414
+ $products->addPriceData($customerGroupId, $store->getWebsiteId());
415
+ } else {
416
+ $products->addPriceData($customerGroupId);
417
+ }
418
+ }
419
+
420
+ $products
421
+ ->addUrlRewrite()
422
+ ->load();
423
+
424
+ return $products;
425
+ }
426
+
427
+ private static function getProducts($productIds = null, $store = null, $flAddMinimalPrice = false, $customerGroupId = null)
428
+ {
429
+ $products = Mage::getModel('catalog/product')
430
+ ->getCollection()
431
+ ->addAttributeToSelect('*');
432
+
433
+ if (!empty($store)) {
434
+ $products
435
+ ->setStoreId($store)
436
+ ->addStoreFilter($store);
437
+ } else {
438
+ $products->setStoreId(Mage::app()->getStores());
439
+ }
440
+
441
+ if (!empty($productIds)) {
442
+ if (is_array($productIds)) {
443
+ $products->addFieldToFilter('entity_id', array('in' => $productIds));
444
+ } else {
445
+ $products->addFieldToFilter('entity_id', array('eq' => $productIds));
446
+ }
447
+ }
448
+
449
+ if ($flAddMinimalPrice == true) {
450
+ $products->addMinimalPrice();
451
+ }
452
+
453
+ if ($customerGroupId) {
454
+ if (!$store) {
455
+ $products->addPriceData($customerGroupId, $store->getWebsiteId());
456
+ } else {
457
+ $products->addPriceData($customerGroupId);
458
+ }
459
+ }
460
+
461
+ $products
462
+ ->addUrlRewrite()
463
+ ->load();
464
+
465
+ return $products;
466
+ }
467
+
468
+ // Main functions //
469
+ public static function generateProductsXML($productIds = null, $store = null, $flAddMinimalPrice = false)
470
+ {
471
+ if ($store) {
472
+ // need for generate correct url
473
+ Mage::app()->setCurrentStore($store->getId());
474
+ }
475
+ $ret = '';
476
+
477
+ $products = self::getProducts($productIds, $store, $flAddMinimalPrice);
478
+ $arrProduct = $products->toArray();
479
+
480
+ // additional check for products without minimal price
481
+ // deprecated, because use only $flAddMinimalPrice = false in current module
482
+ if ($flAddMinimalPrice === true) {
483
+ if ((empty($arrProduct)) || (count($arrProduct) == 0)) {
484
+ return self::generateProductsXML($productIds, $store, false);
485
+ }
486
+ $products2 = self::getProducts($productIds, $store, false);
487
+ $arrProduct2 = $products2->toArray();
488
+ if (count($arrProduct2) > count($arrProduct)) {
489
+ $additionalProductsIds = array();
490
+ foreach ($arrProduct2 as $productId => $product) {
491
+ if (!array_key_exists($productId, $arrProduct)) {
492
+ $additionalProductsIds[] = $productId;
493
+ }
494
+ }
495
+ if (!empty($additionalProductsIds)) {
496
+ $additionalProducts = self::getProducts($additionalProductsIds, $store, false);
497
+ $arrAdditionalProducts = $additionalProducts->toArray();
498
+ if ((!empty($arrAdditionalProducts)) && (count($arrAdditionalProducts) != 0)) {
499
+ foreach ($additionalProducts as $product) {
500
+ $ret .= self::generateProductXML($product, $store);
501
+ }
502
+ }
503
+ }
504
+ }
505
+ }
506
+
507
+ if ((!empty($arrProduct)) && (count($arrProduct) != 0)) {
508
+ foreach ($products as $product) {
509
+ $ret .= self::generateProductXML($product, $store);
510
+ }
511
+ }
512
+
513
+ return $ret;
514
+ }
515
+
516
+ public static function generateFacetXMLFilters($attributeIds = null, $store = null)
517
+ {
518
+ $ret = '';
519
+
520
+ $filters = Mage::getResourceModel('catalog/product_attribute_collection')
521
+ ->setItemObjectClass('catalog/resource_eav_attribute');
522
+
523
+ if (!empty($store)) {
524
+ $filters->addStoreLabel($store->getId());
525
+ }
526
+
527
+ if (!empty($attributeIds)) {
528
+ if (is_array($attributeIds)) {
529
+ $filters->addFieldToFilter('main_table.attribute_id', array('in' => $attributeIds));
530
+ } else {
531
+ $filters->addFieldToFilter('main_table.attribute_id', array('eq' => $attributeIds));
532
+ }
533
+ }
534
+
535
+ $filters->load();
536
+
537
+ if (!empty($filters)) {
538
+ foreach ($filters as $filter) {
539
+ $ret .= self::generateFacetXMLFromFilter($filter, $store);
540
+ }
541
+ }
542
+
543
+ return $ret;
544
+ }
545
+
546
+ public static function generateFacetXMLCategories()
547
+ {
548
+ return self::generateFacetXMLFromCustom('Category', 0, 'categories', 'select');
549
+ }
550
+
551
+ public static function generateFacetXMLPrices($store = null)
552
+ {
553
+ $entry = '';
554
+ $step = self::getPriceNavigationStep($store);
555
+
556
+ $entry .= '<entry>' . self::XML_END_LINE;
557
+ $entry .= '<title><![CDATA[Price]]></title>' . self::XML_END_LINE;
558
+ // not set
559
+ // $entry .= '<cs:position>' . 0 . '</cs:position>' . self::XML_END_LINE;
560
+ $entry .= '<cs:attribute>price</cs:attribute>' . self::XML_END_LINE;
561
+
562
+ $entry .= '<cs:type>dynamic</cs:type>' . self::XML_END_LINE;
563
+
564
+ if (!empty($step)) {
565
+ $entry .= '<cs:min_range>' . $step . '</cs:min_range>' . self::XML_END_LINE;
566
+ }
567
+
568
+ $entry .= '</entry>' . self::XML_END_LINE;
569
+
570
+ return $entry;
571
+
572
+ // deprecated, because use "union"
573
+ $customerGroups = Mage::getModel('customer/group')->getCollection()->load();
574
+ if ($customerGroups) {
575
+ foreach ($customerGroups as $kCostomerGroup => $customerGroup) {
576
+ $entry .= '<entry>' . self::XML_END_LINE;
577
+ $entry .= '<title><![CDATA[Price (' . $customerGroup->getId() . ')]]></title>' . self::XML_END_LINE;
578
+ // not set
579
+ // $entry .= '<cs:position>' . 0 . '</cs:position>' . self::XML_END_LINE;
580
+ $label_ = Mage::helper('searchanise/ApiSe')->getLabelForPricesUsergroup() . $customerGroup->getId();
581
+ $entry .= '<cs:attribute>' . $label_ . '</cs:attribute>' . self::XML_END_LINE;
582
+
583
+ $entry .= '<cs:type>dynamic</cs:type>' . self::XML_END_LINE;
584
+
585
+ if (!empty($step)) {
586
+ $entry .= '<cs:min_range>' . $step . '</cs:min_range>' . self::XML_END_LINE;
587
+ }
588
+
589
+ $entry .= '</entry>' . self::XML_END_LINE;
590
+ }
591
+ }
592
+
593
+ return $entry;
594
+ }
595
+
596
+ public static function generateFacetXMLTags()
597
+ {
598
+ return self::generateFacetXMLFromCustom('Tag', 0, 'tags', 'select');
599
+ }
600
+
601
+ public static function getXMLHeader($store = null)
602
+ {
603
+ $url = '';
604
+
605
+ if (empty($store)) {
606
+ $store = Mage::app()->getStore()->getBaseUrl();
607
+ } else {
608
+ $url = $store->getUrl();
609
+ }
610
+
611
+ $date = date('c');
612
+
613
+ return '<?xml version="1.0" encoding="UTF-8"?>' .
614
+ '<feed xmlns="http://www.w3.org/2005/Atom" xmlns:cs="http://searchanise.com/ns/1.0">' .
615
+ '<title>Searchanise data feed</title>' .
616
+ "<updated>{$date}</updated>" .
617
+ "<id><![CDATA[{$url}]]></id>";
618
+ }
619
+
620
+ public static function getXMLFooter()
621
+ {
622
+ return '</feed>';
623
+ }
624
+ }
625
+
app/code/community/Simtech/Searchanise/Helper/Data.php ADDED
@@ -0,0 +1,498 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Data extends Mage_Core_Helper_Abstract
16
+ {
17
+ const DISABLE_VAR_NAME = 'disabled_module_searchanise';
18
+ const DISABLE_KEY = 'Y';
19
+
20
+ const DEBUG_VAR_NAME = 'debug_module_searchanise';
21
+ const DEBUG_KEY = 'Y';
22
+
23
+ const TEXT_FIND = 'TEXT_FIND';
24
+ const TEXT_ADVANCED_FIND = 'TEXT_ADVANCED_FIND';
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,
33
+ self::TEXT_ADVANCED_FIND,
34
+ self::VIEW_CATEGORY,
35
+ self::VIEW_TAG,
36
+ );
37
+
38
+ /**
39
+ * Searchanise request
40
+ *
41
+ * @var Simtech_Searchanise_Model_Request
42
+ */
43
+ protected $_searchaniseRequest = null;
44
+
45
+ public function initSearchaniseRequest()
46
+ {
47
+ $this->_searchaniseRequest = Mage::getModel('searchanise/request');
48
+
49
+ return $this;
50
+ }
51
+
52
+ public function checkSearchaniseResult()
53
+ {
54
+ return Mage::helper('searchanise/ApiSe')->checkSearchaniseResult($this->_searchaniseRequest);
55
+ }
56
+
57
+ public function setSearchaniseRequest($request)
58
+ {
59
+ $this->_searchaniseRequest = $request;
60
+ }
61
+
62
+ public function getSearchaniseRequest()
63
+ {
64
+ return $this->_searchaniseRequest;
65
+ }
66
+
67
+ public function getDisableText()
68
+ {
69
+ if (is_null($this->_disableText)) {
70
+ $this->_disableText = $this->_getRequest()->getParam(self::DISABLE_VAR_NAME);
71
+ }
72
+
73
+ return $this->_disableText;
74
+ }
75
+
76
+ public function checkEnabled()
77
+ {
78
+ return ($this->getDisableText() != self::DISABLE_KEY) ? true : false;
79
+ }
80
+
81
+ public function getDebugText()
82
+ {
83
+ if (is_null($this->_debugText)) {
84
+ $this->_debugText = $this->_getRequest()->getParam(self::DEBUG_VAR_NAME);
85
+ }
86
+
87
+ return $this->_debugText;
88
+ }
89
+
90
+ public function checkDebug()
91
+ {
92
+ return ($this->getDebugText() == self::DEBUG_KEY) ? true : false;
93
+ }
94
+
95
+ protected function setDefaultSort(&$params, $type)
96
+ {
97
+ if (empty($params)) {
98
+ $params = array();
99
+ }
100
+
101
+ if (in_array($type, self::$_searchaniseTypes)) {
102
+ if ($type == self::TEXT_FIND) {
103
+ $params['sortBy'] = 'relevance';
104
+ $params['sortOrder'] = 'desc';
105
+
106
+ } elseif ($type == self::TEXT_ADVANCED_FIND) {
107
+ $params['sortBy'] = 'title';
108
+ $params['sortOrder'] = 'asc';
109
+
110
+ } elseif ($type == self::VIEW_CATEGORY) {
111
+ $params['sortBy'] = 'position';
112
+ $params['sortOrder'] = 'asc';
113
+
114
+ } elseif ($type == self::VIEW_TAG) {
115
+ $params['sortBy'] = 'title';
116
+ $params['sortOrder'] = 'asc';
117
+ }
118
+
119
+ if (empty($params['restrictBy'])) {
120
+ $params['restrictBy'] = array();
121
+ }
122
+ if (empty($params['queryBy'])) {
123
+ $params['queryBy'] = array();
124
+ }
125
+ if (empty($params['union'])) {
126
+ $params['union'] = array();
127
+ }
128
+ }
129
+ }
130
+
131
+ protected function getUrlSuggestion($suggestion)
132
+ {
133
+ $query = array(
134
+ 'q' => $suggestion,
135
+ Mage::getBlockSingleton('page/html_pager')->getPageVarName() => null // exclude current page from urls
136
+ );
137
+
138
+ return Mage::getUrl('*/*/*', array('_current'=>true, '_use_rewrite'=>true, '_query'=>$query));
139
+ }
140
+
141
+ public function execute($type = null, $controller = null, $block_toolbar = null, $data = null)
142
+ {
143
+ if (!$this->checkEnabled()) {
144
+ return;
145
+ }
146
+
147
+ if (!Mage::helper('searchanise/ApiSe')->getUseNavigation()) {
148
+ if (($type != self::TEXT_FIND) && ($type != self::TEXT_ADVANCED_FIND)) {
149
+ return;
150
+ }
151
+ }
152
+ if (empty($params)) {
153
+ $params = array();
154
+ }
155
+
156
+ // Set default value.
157
+ $this->setDefaultSort($params, $type);
158
+
159
+ $params['restrictBy']['status'] = '1';
160
+ $params['union']['price']['min'] = Mage::helper('searchanise/ApiSe')->getCurLabelForPricesUsergroup();
161
+ $params['startIndex'] = 0; // tmp
162
+ $showOutOfStock = Mage::getStoreConfigFlag(Mage_CatalogInventory_Helper_Data::XML_PATH_SHOW_OUT_OF_STOCK);
163
+ if ($showOutOfStock) {
164
+ // nothing
165
+ } else {
166
+ $params['restrictBy']['is_in_stock'] = '1';
167
+ }
168
+
169
+ if (in_array($type, self::$_searchaniseTypes)) {
170
+ if ($type == self::TEXT_FIND) {
171
+ $params['q'] = Mage::helper('catalogsearch')->getQueryText();
172
+ if ($params['q']) {
173
+ $params['q'] = trim($params['q']);
174
+ }
175
+
176
+ $params['facets'] = 'true';
177
+ $params['suggestions'] = 'true';
178
+ $params['query_correction'] = 'false';
179
+ $params['suggestionsMaxResults'] = Mage::helper('searchanise/ApiSe')->getSuggestionsMaxResults();
180
+
181
+ $params['restrictBy']['visibility'] = '3|4';
182
+ $minQuantityDecimals = Mage::helper('searchanise/ApiSe')->getMinQuantityDecimals();
183
+ if (!empty($minQuantityDecimals)) {
184
+ $params['restrictBy']['quantity_decimals'] = $minQuantityDecimals . ',';
185
+ }
186
+
187
+ } elseif ($type == self::TEXT_ADVANCED_FIND) {
188
+ $params['facets'] = 'false';
189
+ $params['suggestions'] = 'false';
190
+ $params['query_correction'] = 'false';
191
+
192
+ $params['restrictBy']['visibility'] = '3|4';
193
+ $minQuantityDecimals = Mage::helper('searchanise/ApiSe')->getMinQuantityDecimals();
194
+ if (!empty($minQuantityDecimals)) {
195
+ $params['restrictBy']['quantity_decimals'] = $minQuantityDecimals . ',';
196
+ }
197
+
198
+ } elseif ($type == self::VIEW_CATEGORY) {
199
+ // fixme in the future
200
+ // need to add check to display block "Layered Navigation"
201
+ if (true) {
202
+ $params['facets'] = 'true';
203
+
204
+ } else {
205
+ $params['facets'] = 'false';
206
+ }
207
+
208
+ $params['suggestions'] = 'false';
209
+ $params['restrictBy']['visibility'] = '2|4';
210
+
211
+ } elseif ($type == self::VIEW_TAG) {
212
+ $params['facets'] = 'false';
213
+ $params['suggestions'] = 'false';
214
+
215
+ $params['restrictBy']['visibility'] = '3|2|4';
216
+ }
217
+ }
218
+
219
+ if ((!empty($controller)) && (!empty($block_toolbar))) {
220
+ if ($availableOrders = $block_toolbar->getAvailableOrders()) {
221
+ if (in_array($type, self::$_searchaniseTypes)) {
222
+ if ($type == self::TEXT_FIND) {
223
+ unset($availableOrders['position']);
224
+
225
+ $availableOrders = array_merge(
226
+ array('relevance' => $controller->__('Relevance')),
227
+ $availableOrders
228
+ );
229
+
230
+ $block_toolbar->setAvailableOrders($availableOrders);
231
+ } elseif ($type == self::TEXT_ADVANCED_FIND) {
232
+ unset($availableOrders['position']);
233
+ $block_toolbar->setAvailableOrders($availableOrders);
234
+
235
+ } elseif ($type == self::VIEW_TAG) {
236
+ unset($availableOrders['position']);
237
+
238
+ $block_toolbar->setAvailableOrders($availableOrders);
239
+ }
240
+ }
241
+ }
242
+
243
+ $sort_by = $block_toolbar->getCurrentOrder();
244
+ $sort_order = $block_toolbar->getCurrentDirection();
245
+
246
+ $max_results = (int) $block_toolbar->getLimit();
247
+ $start_index = 0;
248
+ $cur_page = (int) $block_toolbar->getCurrentPage();
249
+ $start_index = $cur_page > 1 ? ($cur_page - 1) * $max_results : 0;
250
+
251
+ if ($max_results) {
252
+ $params['maxResults'] = $max_results;
253
+ }
254
+ if ($start_index) {
255
+ $params['startIndex'] = $start_index;
256
+ }
257
+
258
+ if ($sort_by) {
259
+ if ($sort_by == 'name') {
260
+ $params['sortBy'] = 'title';
261
+ } else {
262
+ $params['sortBy'] = $sort_by;
263
+ }
264
+ }
265
+
266
+ if ($sort_order) {
267
+ $params['sortOrder'] = $sort_order;
268
+ }
269
+ }
270
+
271
+ //ADD FACETS
272
+ $arrAttributes = array();
273
+ $arrInputType = array(); // need for save type $arrAttributes
274
+ if (!empty($controller)) {
275
+ // CATEGORIES
276
+ {
277
+ $arr_cat = null;
278
+
279
+ if ((in_array($type, self::$_searchaniseTypes)) && ($type != self::VIEW_TAG)) {
280
+ $cat_id = (int) $controller->getRequest()->getParam('cat');
281
+ if (!empty($cat_id)) {
282
+ $arr_cat = array();
283
+ $arr_cat[] = $cat_id; // need if not exist children categories
284
+
285
+ $categories = Mage::getModel('catalog/category')
286
+ ->getCollection()
287
+ ->setStoreId(Mage::app()->getStore()->getId())
288
+ ->addFieldToFilter('entity_id', $cat_id)
289
+ ->load()
290
+ ;
291
+
292
+ if (!empty($categories)) {
293
+ foreach ($categories as $cat) {
294
+ if (!empty($cat)) {
295
+ $arr_cat = $cat->getAllChildren(true);
296
+ }
297
+ }
298
+ }
299
+ } elseif (($type == self::VIEW_CATEGORY) && (!empty($data))) {
300
+ // data = category
301
+ $arr_cat = $data->getAllChildren(true);
302
+ }
303
+ }
304
+
305
+ if (!empty($arr_cat)) {
306
+ if (is_array($arr_cat)) {
307
+ $params['restrictBy']['categories'] = implode('|', $arr_cat);
308
+ } else {
309
+ $params['restrictBy']['categories'] = $arr_cat;
310
+ }
311
+ }
312
+ }
313
+ // ATTRIBUTES
314
+ {
315
+ $attributes = Mage::getResourceModel('catalog/product_attribute_collection');
316
+ $attributes
317
+ ->setItemObjectClass('catalog/resource_eav_attribute')
318
+ ->load();
319
+
320
+ if (!empty($attributes)) {
321
+ foreach ($attributes as $id => $attr) {
322
+ $arrAttributes[$id] = $attr->getName();
323
+ $arrInputType[$id] = $attr->getData('frontend_input');
324
+ }
325
+
326
+ if (!empty($arrAttributes)) {
327
+ $req_params = $controller->getRequest()->getParams();
328
+
329
+ if (!empty($req_params)) {
330
+ foreach ($req_params as $name => $val) {
331
+ $id = array_search($name, $arrAttributes);
332
+ if (($name) && ($id)) {
333
+ // hook, need for 'union'
334
+ if ($name == 'price') {
335
+ $valPrice = Mage::helper('searchanise/ApiSe')->getPriceValueFromRequest($val);
336
+ if ($valPrice != '') {
337
+ $params['restrictBy']['price'] = $valPrice;
338
+ }
339
+ continue;
340
+ }
341
+
342
+ if ($arrInputType[$id] == 'price') {
343
+ $valPrice = Mage::helper('searchanise/ApiSe')->getPriceValueFromRequest($val);
344
+
345
+ if ($valPrice != '') {
346
+ $params['restrictBy']['attribute_' . $id] = $valPrice;
347
+ }
348
+
349
+ } elseif (($arrInputType[$id] == 'text') || ($arrInputType[$id] == 'textarea')) {
350
+ if ($val != '') {
351
+ $val = Mage::helper('searchanise/ApiSe')->escapingCharacters($val);
352
+
353
+ if ($val != '') {
354
+ $params['queryBy']['attribute_' . $id] = $val;
355
+ }
356
+ }
357
+
358
+ } elseif (($arrInputType[$id] == 'select') ||
359
+ ($arrInputType[$id] == 'multiselect') ||
360
+ ($arrInputType[$id] == 'boolean')) {
361
+ if ($val) {
362
+ if (is_array($val)) {
363
+ $params['restrictBy']['attribute_' . $id] = implode('|', $val);
364
+ } else {
365
+ $params['restrictBy']['attribute_' . $id] = $val;
366
+ }
367
+ }
368
+
369
+ } else {
370
+ // nothing
371
+ }
372
+ }
373
+ }
374
+ }
375
+ }
376
+ }
377
+ }
378
+ // TAGS
379
+ if ((in_array($type, self::$_searchaniseTypes)) && ($type == self::VIEW_TAG)) {
380
+ if ($data) {
381
+ // data = tag
382
+ $params['restrictBy']['tags'] = $data->getId();
383
+ }
384
+ }
385
+ }
386
+
387
+ // need for other sort_by
388
+ if (!empty($arrAttributes)) {
389
+ $id = array_search($params['sortBy'], $arrAttributes);
390
+ if (!empty($id)) {
391
+ $params['sortBy'] = 'attribute_' . $id;
392
+ }
393
+ }
394
+
395
+ if (!Mage::helper('searchanise/ApiSe')->getUseNavigation()) {
396
+ if (empty($params['queryBy']) && (!isset($params['q']) || $params['q'] == '')) {
397
+ return;
398
+ }
399
+ }
400
+
401
+ Mage::helper('searchanise')
402
+ ->initSearchaniseRequest()
403
+ ->getSearchaniseRequest()
404
+ ->setStore(Mage::app()->getStore())
405
+ ->setSearchParams($params)
406
+ ->sendSearchRequest()
407
+ ->getSearchResult();
408
+
409
+ //add suggestions
410
+ $suggestionsMaxResults = Mage::helper('searchanise/ApiSe')->getSuggestionsMaxResults();
411
+ if ((!empty($suggestionsMaxResults)) && (in_array($type, self::$_searchaniseTypes)) && ($type == self::TEXT_FIND)) {
412
+ $res = Mage::helper('searchanise')->getSearchaniseRequest();
413
+
414
+ if ($res->getTotalProduct() == 0) {
415
+ $sugs = Mage::helper('searchanise')->getSearchaniseRequest()->getSuggestions();
416
+
417
+ if ((!empty($sugs)) && (count($sugs) > 0)) {
418
+ $message = Mage::helper('searchanise')->__('Did you mean: ');
419
+ $link = '';
420
+ $textFind = Mage::helper('catalogsearch')->getQueryText();
421
+ $count_sug = 0;
422
+
423
+ foreach ($sugs as $k => $sug) {
424
+ if ((!empty($sug)) && ($sug != $textFind)) {
425
+ $link .= '<a href="' . self::getUrlSuggestion($sug). '">' . $sug .'</a>';
426
+
427
+ if (end($sugs) == $sug) {
428
+ $link .= '?';
429
+ } else {
430
+ $link .= ', ';
431
+ }
432
+ $count_sug++;
433
+ }
434
+ if ($count_sug >= $suggestionsMaxResults) {
435
+ break;
436
+ }
437
+ }
438
+
439
+ if ($link != '') {
440
+ Mage::helper('catalogsearch')->addNoteMessage($message . $link);
441
+ }
442
+ }
443
+ }
444
+ }
445
+ }
446
+
447
+ /**
448
+ * Get specified products limit display per page
449
+ *
450
+ * @return string
451
+ */
452
+ public function getLimit()
453
+ {
454
+ //~ $limit = $this->_getData('_current_limit');
455
+ //~ if ($limit) {
456
+ //~ return $limit;
457
+ //~ }
458
+
459
+ $limits = $this->getAvailableLimit();
460
+ $defaultLimit = $this->getDefaultPerPageValue();
461
+ if (!$defaultLimit || !isset($limits[$defaultLimit])) {
462
+ $keys = array_keys($limits);
463
+ $defaultLimit = $keys[0];
464
+ }
465
+
466
+ $limit = $this->getRequest()->getParam($this->getLimitVarName());
467
+ if ($limit && isset($limits[$limit])) {
468
+ if ($limit == $defaultLimit) {
469
+ Mage::getSingleton('catalog/session')->unsLimitPage();
470
+ } else {
471
+ $this->_memorizeParam('limit_page', $limit);
472
+ }
473
+ } else {
474
+ $limit = Mage::getSingleton('catalog/session')->getLimitPage();
475
+ }
476
+ if (!$limit || !isset($limits[$limit])) {
477
+ $limit = $defaultLimit;
478
+ }
479
+
480
+ $this->setData('_current_limit', $limit);
481
+ return $limit;
482
+ }
483
+
484
+ /**
485
+ * Retrieve available limits for current view mode
486
+ *
487
+ * @return array
488
+ */
489
+ public function getAvailableLimit()
490
+ {
491
+ $currentMode = $this->getCurrentMode();
492
+ if (in_array($currentMode, array('list', 'grid'))) {
493
+ return $this->_getAvailableLimit($currentMode);
494
+ } else {
495
+ return $this->_defaultAvailableLimit;
496
+ }
497
+ }
498
+ }
app/code/community/Simtech/Searchanise/Model/Advanced.php ADDED
@@ -0,0 +1,49 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Model_Advanced extends Mage_CatalogSearch_Model_Advanced
16
+ {
17
+ /**
18
+ * Prepare product collection
19
+ *
20
+ * @param Mage_CatalogSearch_Model_Resource_Advanced_Collection $collection
21
+ * @return Mage_Catalog_Model_Layer
22
+ */
23
+ public function prepareProductCollection($collection)
24
+ {
25
+ if (!Mage::helper('searchanise/ApiSe')->checkSearchaniseResult(true)) {
26
+ return parent::prepareProductCollection($collection);
27
+ }
28
+
29
+ if (method_exists($collection, 'setSearchaniseRequest')) {
30
+ $collection->setSearchaniseRequest(Mage::helper('searchanise')->getSearchaniseRequest());
31
+ }
32
+
33
+ if ((!method_exists($collection, 'checkSearchaniseResult')) || (!$collection->checkSearchaniseResult())) {
34
+ return parent::prepareProductCollection($collection);
35
+ }
36
+
37
+ $collection->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes())
38
+ ->addSearchaniseFilter()
39
+ ->setStore(Mage::app()->getStore())
40
+ ->addMinimalPrice()
41
+ ->addTaxPercents()
42
+ ->addStoreFilter();
43
+
44
+ Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($collection);
45
+ Mage::getSingleton('catalog/product_visibility')->addVisibleInSearchFilterToCollection($collection);
46
+
47
+ return $this;
48
+ }
49
+ }
app/code/community/Simtech/Searchanise/Model/Config.php ADDED
@@ -0,0 +1,108 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Model_Config extends Mage_Core_Model_Abstract
16
+ {
17
+ /**
18
+ * Resource model
19
+ * Used for operations with DB
20
+ *
21
+ * @var Mage_Searchanise_Model_Mysql4_Config
22
+ */
23
+ protected $_resourceModel;
24
+
25
+ protected function _construct()
26
+ {
27
+ $this->_init('searchanise/config', 'config_id');
28
+ }
29
+
30
+ /**
31
+ * Get config resource model
32
+ *
33
+ * @return Mage_Searchanise_Store_Mysql4_Config
34
+ */
35
+ public function getResourceModel()
36
+ {
37
+ if (is_null($this->_resourceModel)) {
38
+ $this->_resourceModel = Mage::getResourceModel('searchanise/config');
39
+ }
40
+
41
+ return $this->_resourceModel;
42
+ }
43
+
44
+ /**
45
+ * Retrieve store configuration data
46
+ *
47
+ * @param string $path
48
+ * @param string $scope
49
+ * @param int $scopeId
50
+ * @return string|null
51
+ */
52
+ public function getConfig($path, $scope = 'default', $scopeId = 0)
53
+ {
54
+ $path = rtrim($path, '/');
55
+
56
+ $collection = $this->getCollection()
57
+ ->addFieldToFilter('path', $path)
58
+ ->addFieldToFilter('scope', $scope)
59
+ ->addFieldToFilter('scope_id', $scopeId)
60
+ ->setPageSize(1)
61
+ ->load();
62
+
63
+ if (!empty($collection)) {
64
+ foreach ($collection as $key => $data) {
65
+ $value = $data->getValue();
66
+
67
+ if (!empty($value)) {
68
+ return $value;
69
+ }
70
+ }
71
+ }
72
+
73
+ return;
74
+ }
75
+
76
+ /**
77
+ * Save config value to DB
78
+ *
79
+ * @param string $path
80
+ * @param string $value
81
+ * @param string $scope
82
+ * @param int $scopeId
83
+ * @return Mage_Searchanise_Store_Config
84
+ */
85
+ public function saveConfig($path, $value, $scope = 'default', $scopeId = 0)
86
+ {
87
+ $resource = $this->getResourceModel();
88
+ $resource->saveConfig(rtrim($path, '/'), $value, $scope, $scopeId);
89
+
90
+ return $this;
91
+ }
92
+
93
+ /**
94
+ * Delete config value from DB
95
+ *
96
+ * @param string $path
97
+ * @param string $scope
98
+ * @param int $scopeId
99
+ * @return Mage_Searchanise_Model_Config
100
+ */
101
+ public function deleteConfig($path, $scope = 'default', $scopeId = 0)
102
+ {
103
+ $resource = $this->getResourceModel();
104
+ $resource->deleteConfig(rtrim($path, '/'), $scope, $scopeId);
105
+
106
+ return $this;
107
+ }
108
+ }
app/code/community/Simtech/Searchanise/Model/Config/Data.php ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Model_Config_Data extends Mage_Adminhtml_Model_Config_Data
16
+ {
17
+ /**
18
+ * Save config section
19
+ * Require set: section, website, store and groups
20
+ *
21
+ * @return Mage_Adminhtml_Model_Config_Data
22
+ */
23
+ public function save()
24
+ {
25
+ Mage::dispatchEvent('searchanise_adminhtml_config_data_save_before', array('object' => $this));
26
+
27
+ $ret = parent::save();
28
+
29
+ Mage::dispatchEvent('searchanise_adminhtml_config_data_save_after', array('object' => $ret));
30
+
31
+ return $ret;
32
+ }
33
+ }
app/code/community/Simtech/Searchanise/Model/Import/Entity/Product.php ADDED
@@ -0,0 +1,56 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Model_Import_Entity_Product extends Mage_ImportExport_Model_Import_Entity_Product
16
+ {
17
+ /**
18
+ * Delete products.
19
+ *
20
+ * @return Mage_ImportExport_Model_Import_Entity_Product
21
+ */
22
+ protected function _deleteProducts()
23
+ {
24
+ $idToDelete = null;
25
+
26
+ while ($bunch = $this->_dataSourceModel->getNextBunch()) {
27
+ $idToDelete = array();
28
+
29
+ foreach ($bunch as $rowNum => $rowData) {
30
+ if ($this->validateRow($rowData, $rowNum) && self::SCOPE_DEFAULT == $this->getRowScope($rowData)) {
31
+ $idToDelete[] = $this->_oldSku[$rowData[self::COL_SKU]]['entity_id'];
32
+ }
33
+ }
34
+ }
35
+
36
+ Mage::dispatchEvent('searchanise_import_delete_product_entity_after', array('idToDelete' => $idToDelete));
37
+
38
+ return parent::_deleteProducts();
39
+ }
40
+
41
+ /**
42
+ * Update and insert data in entity table.
43
+ *
44
+ * @param array $entityRowsIn Row for insert
45
+ * @param array $entityRowsUp Row for update
46
+ * @return Mage_ImportExport_Model_Import_Entity_Product
47
+ */
48
+ protected function _saveProductEntity(array $entityRowsIn, array $entityRowsUp)
49
+ {
50
+ $ret = parent::_saveProductEntity($entityRowsIn, $entityRowsUp);
51
+
52
+ Mage::dispatchEvent('searchanise_import_save_product_entity_after', array('_newSku' => ($ret->_newSku)));
53
+
54
+ return $ret;
55
+ }
56
+ }
app/code/community/Simtech/Searchanise/Model/Layer.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Model_Layer extends Mage_Catalog_Model_Layer
16
+ {
17
+ /**
18
+ * Prepare product collection
19
+ *
20
+ * @param Mage_Catalog_Model_Resource_Eav_Resource_Product_Collection $collection
21
+ * @return Mage_Catalog_Model_Layer
22
+ */
23
+ public function prepareProductCollection($collection)
24
+ {
25
+ if (!Mage::helper('searchanise/ApiSe')->checkSearchaniseResult(true)) {
26
+ return parent::prepareProductCollection($collection);
27
+ }
28
+
29
+ if (method_exists($collection, 'setSearchaniseRequest')) {
30
+ $collection->setSearchaniseRequest(Mage::helper('searchanise')->getSearchaniseRequest());
31
+ }
32
+
33
+ if ((!method_exists($collection, 'checkSearchaniseResult')) || (!$collection->checkSearchaniseResult())) {
34
+ return parent::prepareProductCollection($collection);
35
+ }
36
+
37
+ $collection
38
+ ->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes())
39
+ ->addSearchaniseFilter()
40
+ ->addMinimalPrice()
41
+ ->addFinalPrice()
42
+ ->addTaxPercents()
43
+ //->addStoreFilter()
44
+ ->addUrlRewrite($this->getCurrentCategory()->getId());
45
+
46
+ Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($collection);
47
+ Mage::getSingleton('catalog/product_visibility')->addVisibleInCatalogFilterToCollection($collection);
48
+
49
+ return $this;
50
+ }
51
+ }
52
+
app/code/community/Simtech/Searchanise/Model/Layer/Filter/Category.php ADDED
@@ -0,0 +1,68 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Model_Layer_Filter_Category extends Mage_Catalog_Model_Layer_Filter_Category
16
+ {
17
+ /**
18
+ * Get data array for building category filter items
19
+ *
20
+ * @return array
21
+ */
22
+ protected function _getItemsData()
23
+ {
24
+ if (!Mage::helper('searchanise/ApiSe')->checkSearchaniseResult(true)) {
25
+ return parent::_getItemsData();
26
+ }
27
+
28
+ $collection = $this->getLayer()->getProductCollection();
29
+
30
+ if ((!method_exists($collection, 'checkSearchaniseResult')) || (!$collection->checkSearchaniseResult()))
31
+ {
32
+ return parent::_getItemsData();
33
+ }
34
+
35
+ $key = $this->getLayer()->getStateKey().'_SUBCATEGORIES';
36
+ $data = $this->getLayer()->getAggregator()->getCacheData($key);
37
+
38
+ if ($data === null)
39
+ {
40
+ $categoty = $this->getCategory();
41
+ /** @var $categoty Mage_Catalog_Model_Categeory */
42
+ $categories = $categoty->getChildrenCategories();
43
+
44
+ $this->getLayer()->getProductCollection()
45
+ ->addCountToCategories($categories);
46
+
47
+ $data = array();
48
+ foreach ($categories as $category) {
49
+ $productCount = $collection
50
+ ->getSearchaniseRequest()
51
+ ->getCountProductCategory($category);
52
+
53
+ if ($category->getIsActive() && $productCount)
54
+ {
55
+ $data[] = array(
56
+ 'label' => Mage::helper('core')->htmlEscape($category->getName()),
57
+ 'value' => $category->getId(),
58
+ 'count' => $productCount,
59
+ );
60
+ }
61
+ }
62
+ $tags = $this->getLayer()->getStateTags();
63
+ $this->getLayer()->getAggregator()->saveCacheData($data, $key, $tags);
64
+ }
65
+
66
+ return $data;
67
+ }
68
+ }
app/code/community/Simtech/Searchanise/Model/Layer/Filter/Price.php ADDED
@@ -0,0 +1,51 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Model_Layer_Filter_Price extends Mage_Catalog_Model_Layer_Filter_Price
16
+ {
17
+ /**
18
+ * Get price range for building filter steps
19
+ *
20
+ * @return int
21
+ */
22
+ public function getPriceRange()
23
+ {
24
+ if (!Mage::helper('searchanise/ApiSe')->checkSearchaniseResult(true)) {
25
+ return parent::getPriceRange();
26
+ }
27
+
28
+ $collection = $this->getLayer()->getProductCollection();
29
+
30
+ if ((!method_exists($collection, 'checkSearchaniseResult')) || (!$collection->checkSearchaniseResult())) {
31
+ return parent::getPriceRange();
32
+ }
33
+
34
+ $newRange = $collection
35
+ ->getSearchaniseRequest()
36
+ ->getPriceRangeFromAttribute($this->getAttributeModel());
37
+ if (!$newRange) {
38
+ return parent::getPriceRange();
39
+ }
40
+
41
+ $rate = Mage::app()->getStore()->getCurrentCurrencyRate();
42
+
43
+ if ((!$rate) || ($rate == 1)) {
44
+ // nothing
45
+ } else {
46
+ $newRange *= $rate;
47
+ }
48
+
49
+ return $newRange;
50
+ }
51
+ }
app/code/community/Simtech/Searchanise/Model/LayerCatalogSearch.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Model_LayerCatalogSearch extends Mage_CatalogSearch_Model_Layer
16
+ {
17
+ /**
18
+ * Prepare product collection
19
+ *
20
+ * @param Mage_Catalog_Model_Resource_Eav_Resource_Product_Collection $collection
21
+ * @return Mage_Catalog_Model_Layer
22
+ */
23
+ public function prepareProductCollection($collection)
24
+ {
25
+ if (!Mage::helper('searchanise/ApiSe')->checkSearchaniseResult(true)) {
26
+ return parent::prepareProductCollection($collection);
27
+ }
28
+
29
+ if (method_exists($collection, 'setSearchaniseRequest')) {
30
+ $collection->setSearchaniseRequest(Mage::helper('searchanise')->getSearchaniseRequest());
31
+ }
32
+
33
+ if ((!method_exists($collection, 'checkSearchaniseResult')) || (!$collection->checkSearchaniseResult())) {
34
+ return parent::prepareProductCollection($collection);
35
+ }
36
+
37
+ $collection
38
+ ->addAttributeToSelect(Mage::getSingleton('catalog/config')->getProductAttributes())
39
+ ->addSearchaniseFilter()
40
+ ->setStore(Mage::app()->getStore())
41
+ ->addMinimalPrice()
42
+ ->addFinalPrice()
43
+ ->addTaxPercents()
44
+ ->addStoreFilter()
45
+ ->addUrlRewrite();
46
+
47
+ Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($collection);
48
+ Mage::getSingleton('catalog/product_visibility')->addVisibleInSearchFilterToCollection($collection);
49
+
50
+ return $this;
51
+ }
52
+ }
app/code/community/Simtech/Searchanise/Model/Mysql4/Config.php ADDED
@@ -0,0 +1,81 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Model_Mysql4_Config extends Mage_Core_Model_Mysql4_Abstract
16
+ {
17
+ /**
18
+ * Define main table
19
+ *
20
+ */
21
+ protected function _construct()
22
+ {
23
+ $this->_init('searchanise/config', 'config_id');
24
+ }
25
+
26
+ /**
27
+ * Save config value
28
+ *
29
+ * @param string $path
30
+ * @param string $value
31
+ * @param string $scope
32
+ * @param int $scopeId
33
+ * @return Mage_Searchanise_Model_Resource_Config
34
+ */
35
+ public function saveConfig($path, $value, $scope, $scopeId)
36
+ {
37
+ $writeAdapter = $this->_getWriteAdapter();
38
+ $select = $writeAdapter->select()
39
+ ->from($this->getMainTable())
40
+ ->where('path = ?', $path)
41
+ ->where('scope = ?', $scope)
42
+ ->where('scope_id = ?', $scopeId);
43
+ $row = $writeAdapter->fetchRow($select);
44
+
45
+ $newData = array(
46
+ 'scope' => $scope,
47
+ 'scope_id' => $scopeId,
48
+ 'path' => $path,
49
+ 'value' => $value
50
+ );
51
+
52
+ if ($row) {
53
+ $whereCondition = array($this->getIdFieldName() . '=?' => $row[$this->getIdFieldName()]);
54
+ $writeAdapter->update($this->getMainTable(), $newData, $whereCondition);
55
+ } else {
56
+ $writeAdapter->insert($this->getMainTable(), $newData);
57
+ }
58
+
59
+ return $this;
60
+ }
61
+
62
+ /**
63
+ * Delete config value
64
+ *
65
+ * @param string $path
66
+ * @param string $scope
67
+ * @param int $scopeId
68
+ * @return Mage_Searchanise_Model_Resource_Config
69
+ */
70
+ public function deleteConfig($path, $scope, $scopeId)
71
+ {
72
+ $adapter = $this->_getWriteAdapter();
73
+ $adapter->delete($this->getMainTable(), array(
74
+ $adapter->quoteInto('path = ?', $path),
75
+ $adapter->quoteInto('scope = ?', $scope),
76
+ $adapter->quoteInto('scope_id = ?', $scopeId)
77
+ ));
78
+
79
+ return $this;
80
+ }
81
+ }
app/code/community/Simtech/Searchanise/Model/Mysql4/Config/Collection.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Model_Mysql4_Config_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
16
+ {
17
+ protected function _construct()
18
+ {
19
+ parent::_construct();
20
+ }
21
+
22
+ public function delete()
23
+ {
24
+ $delete_collection = $this->toArray();
25
+
26
+ if (!empty($delete_collection['items'])) {
27
+ foreach ($delete_collection['items'] as $item) {
28
+ Mage::getModel('searchanise/config')->load($item['config_id'])->delete();
29
+ }
30
+ }
31
+ }
32
+ }
app/code/community/Simtech/Searchanise/Model/Mysql4/Queue.php ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Model_Mysql4_Queue extends Mage_Core_Model_Mysql4_Abstract
16
+ {
17
+ protected function _construct()
18
+ {
19
+ $this->_init('searchanise/queue', 'queue_id');
20
+ }
21
+ }
app/code/community/Simtech/Searchanise/Model/Mysql4/Queue/Collection.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Model_Mysql4_Queue_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
16
+ {
17
+ protected function _construct()
18
+ {
19
+ parent::_construct();
20
+ }
21
+
22
+ public function delete()
23
+ {
24
+ $delete_collection = $this->toArray();
25
+
26
+ if (!empty($delete_collection['items'])) {
27
+ foreach ($delete_collection['items'] as $item) {
28
+ Mage::getModel('searchanise/queue')->load($item['queue_id'])->delete();
29
+ }
30
+ }
31
+ }
32
+ }
app/code/community/Simtech/Searchanise/Model/Observer.php ADDED
@@ -0,0 +1,651 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Model_Observer
16
+ {
17
+ protected static $newAttributes = array();
18
+ protected static $productIdsInCategory = array();
19
+
20
+ public function __construct()
21
+ {
22
+ // nothing for now
23
+ }
24
+
25
+ public function autoSync()
26
+ {
27
+ Mage::helper('searchanise/ApiSe')->log('start cron autoSync', 'information');
28
+
29
+ // only run if set to
30
+ $cron_enabled = Mage::helper('searchanise/ApiSe')->getCronEnabled();
31
+ if ($cron_enabled){
32
+ Mage::helper('searchanise/ApiSe')->log('cron is enabled', 'information');
33
+ $result = Mage::helper('searchanise/ApiSe')->async();
34
+ echo $result;
35
+
36
+ } else {
37
+ Mage::helper('searchanise/ApiSe')->log('cron is not enabled', 'information');
38
+ }
39
+
40
+ Mage::helper('searchanise/ApiSe')->log('end cron autoSync', 'information');
41
+
42
+ return $this;
43
+ }
44
+
45
+ // FOR PRODUCTS //
46
+ /**
47
+ * Before save product
48
+ *
49
+ * @param Varien_Event_Observer $observer
50
+ * @return Mage_CatalogIndex_Model_Observer
51
+ */
52
+ public function catalogProductSaveBefore(Varien_Event_Observer $observer)
53
+ {
54
+ Mage::getModel('searchanise/queue')->addActionDeleteProductFromOldStore($observer->getEvent()->getProduct());
55
+
56
+ return $this;
57
+ }
58
+
59
+ /**
60
+ * After save product
61
+ *
62
+ * @param Varien_Event_Observer $observer
63
+ * @return Mage_CatalogIndex_Model_Observer
64
+ */
65
+ public function catalogProductSaveAfter(Varien_Event_Observer $observer)
66
+ {
67
+ // fixme in the future
68
+ // Add a check-up for changes of the parameters which are related to other languages and storefronts.
69
+ //~ Mage::getModel('searchanise/queue')->addActionUpdateProduct($observer->getEvent()->getProduct(), $observer->getEvent()->getProduct()->getStoreId());
70
+ Mage::getModel('searchanise/queue')->addActionUpdateProduct($observer->getEvent()->getProduct());
71
+
72
+ return $this;
73
+ }
74
+
75
+ /**
76
+ * Before delete product
77
+ *
78
+ * @param Varien_Event_Observer $observer
79
+ * @return Mage_CatalogIndex_Model_Observer
80
+ */
81
+ public function catalogProductDeleteBefore(Varien_Event_Observer $observer)
82
+ {
83
+ Mage::getModel('searchanise/queue')->addActionDeleteProduct($observer->getEvent()->getProduct());
84
+
85
+ return $this;
86
+ }
87
+
88
+ /**
89
+ * Product attribute update
90
+ *
91
+ * @param Varien_Event_Observer $observer
92
+ * @return Mage_CatalogIndex_Model_Observer
93
+ */
94
+ public function catalogProductAttributeUpdateBefore(Varien_Event_Observer $observer)
95
+ {
96
+ $productIds = $observer->getEvent()->getData('product_ids');
97
+
98
+ if (!empty($productIds)) {
99
+ foreach ($productIds as $k => $productId) {
100
+ $product = Mage::getModel('catalog/product')
101
+ ->load($productId);
102
+
103
+ if (!empty($product)) {
104
+ $storeIds = $product->getStoreIds();
105
+
106
+ if (!empty($storeIds)) {
107
+ foreach ($storeIds as $k => $storeId) {
108
+ Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_UPDATE, $product->getId(), null, $storeId);
109
+ }
110
+ }
111
+ }
112
+ }
113
+ }
114
+
115
+ return $this;
116
+ }
117
+
118
+ /**
119
+ * Product website update
120
+ *
121
+ * @param Varien_Event_Observer $observer
122
+ * @return Mage_CatalogIndex_Model_Observer
123
+ */
124
+ public function catalogProductWebsiteUpdateBefore(Varien_Event_Observer $observer)
125
+ {
126
+ $productIds = $observer->getEvent()->getData('product_ids');
127
+ $websiteIds = $observer->getEvent()->getData('website_ids');
128
+ $action = $observer->getEvent()->getData('action');
129
+ $storeIds = Mage::helper('searchanise/ApiSe')->getStoreByWebsiteIds($websiteIds);
130
+
131
+ if ((!empty($storeIds)) && (!empty($productIds))) {
132
+ foreach ($productIds as $k => $productId) {
133
+ if ($action == 'add') {
134
+ foreach ($storeIds as $k => $storeId) {
135
+ Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_UPDATE, $productId, null, $storeId);
136
+ }
137
+
138
+ } elseif ($action == 'remove') {
139
+ $productOld = Mage::getModel('catalog/product')
140
+ ->load($productId);
141
+
142
+ if (!empty($productOld)) {
143
+ $storeIdsOld = $productOld->getStoreIds();
144
+
145
+ if (!empty($storeIdsOld)) {
146
+ foreach ($storeIds as $k => $storeId) {
147
+ if (in_array($storeId, $storeIdsOld)) {
148
+ Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_DELETE, $productId, null, $storeId);
149
+ }
150
+ }
151
+ }
152
+ }
153
+ }
154
+ }
155
+ }
156
+
157
+ return $this;
158
+ }
159
+
160
+ // FOR CATEGORIES //
161
+ /**
162
+ * Save category before
163
+ *
164
+ * @param Varien_Event_Observer $observer
165
+ * @return Mage_CatalogIndex_Model_Observer
166
+ */
167
+ public function catalogCategorySaveBefore(Varien_Event_Observer $observer)
168
+ {
169
+ $category = $observer->getEvent()->getCategory();
170
+
171
+ if ($category && $category->getId()) {
172
+ $products = $category->getProductCollection();
173
+ Mage::getModel('searchanise/queue')->addActionProducts($products);
174
+
175
+ // save current products ids
176
+ // need for find new products in catalogCategorySaveAfter
177
+ if (!empty($products)) {
178
+ self::$productIdsInCategory = array();
179
+
180
+ foreach ($products as $product) {
181
+ if ($product->getId()) {
182
+ self::$productIdsInCategory[] = $product->getId();
183
+ }
184
+ }
185
+ }
186
+ }
187
+
188
+ return $this;
189
+ }
190
+
191
+ /**
192
+ * Save category after
193
+ *
194
+ * @param Varien_Event_Observer $observer
195
+ * @return Mage_CatalogIndex_Model_Observer
196
+ */
197
+ public function catalogCategorySaveAfter(Varien_Event_Observer $observer)
198
+ {
199
+ $category = $observer->getEvent()->getCategory();
200
+
201
+ if ($category && $category->getId()) {
202
+ $products = $category->getProductCollection();
203
+
204
+ if (!empty($products)) {
205
+ if (empty(self::$productIdsInCategory)) {
206
+ Mage::getModel('searchanise/queue')->addActionProducts($products);
207
+ } else {
208
+ $productIds = array();
209
+ foreach ($products as $product) {
210
+ $id = $product->getId();
211
+ if ((!empty($id)) && (!in_array($id, self::$productIdsInCategory))) {
212
+ $productIds[] = $id;
213
+ }
214
+ }
215
+
216
+ Mage::getModel('searchanise/queue')->addActionProductIds($productIds);
217
+ }
218
+ }
219
+ }
220
+
221
+ return $this;
222
+ }
223
+
224
+ // FOR SALES //
225
+ /**
226
+ *
227
+ *
228
+ * @param Varien_Event_Observer $observer
229
+ * @return Mage_CatalogIndex_Model_Observer
230
+ */
231
+ public function salesOrderSaveAfter(Varien_Event_Observer $observer)
232
+ {
233
+ $order = $observer->getEvent()->getOrder();
234
+
235
+ if ($order && $order->getId()) {
236
+ Mage::getModel('searchanise/queue')->addActionOrderItems($order->getItemsCollection());
237
+ }
238
+
239
+ return $this;
240
+ }
241
+
242
+ // FOR IMPORTEXPORT //
243
+ /**
244
+ *
245
+ *
246
+ * @param Varien_Event_Observer $observer
247
+ * @return Mage_CatalogIndex_Model_Observer
248
+ */
249
+ public function searchaniseImportSaveProductEntityAfter(Varien_Event_Observer $observer)
250
+ {
251
+ $_newSku = $observer->getData('_newSku');
252
+
253
+ if (!empty($_newSku)) {
254
+ $productIds = array();
255
+
256
+ foreach ($_newSku as $entity) {
257
+ if ($entity['entity_id']) {
258
+ $productIds[] = $entity['entity_id'];
259
+ }
260
+ }
261
+
262
+ if (!empty($productIds)) {
263
+ Mage::getModel('searchanise/queue')->addActionProductIds($productIds , Simtech_Searchanise_Model_Queue::ACT_UPDATE);
264
+ }
265
+ }
266
+
267
+ return $this;
268
+ }
269
+
270
+ /**
271
+ *
272
+ *
273
+ * @param Varien_Event_Observer $observer
274
+ * @return Mage_CatalogIndex_Model_Observer
275
+ */
276
+ public function searchaniseImportDeleteProductEntityAfter(Varien_Event_Observer $observer)
277
+ {
278
+ $idToDelete = $observer->getData('idToDelete');
279
+
280
+ if (!empty($idToDelete)) {
281
+ Mage::getModel('searchanise/queue')->addActionProductIds($idToDelete, Simtech_Searchanise_Model_Queue::ACT_DELETE);
282
+ }
283
+
284
+ return $this;
285
+ }
286
+
287
+ // FOR CORE //
288
+ /**
289
+ * Before save store
290
+ *
291
+ * @param Varien_Event_Observer $observer
292
+ * @return Mage_CatalogIndex_Model_Observer
293
+ */
294
+ public function searchaniseCoreSaveStoreBefore(Varien_Event_Observer $observer)
295
+ {
296
+ $store = $observer->getData('store');
297
+
298
+ if ($store && $store->getId()) {
299
+ $isActive = $store->getIsActive();
300
+ $isActiveOld = null;
301
+ $storeOld = Mage::app()->getStore($store->getId());
302
+
303
+ if (empty($storeOld)) {
304
+ $isActiveOld = $storeOld->getIsActive();
305
+ }
306
+
307
+ if ($isActiveOld != $isActive) {
308
+ if (Mage::helper('searchanise/ApiSe')->signup($store, false, false) == true) {
309
+ if ($isActive) {
310
+ Mage::helper('searchanise/ApiSe')->sendAddonStatusRequest('enabled', $store);
311
+ Mage::helper('searchanise/ApiSe')->queueImport($store, false);
312
+ Mage::helper('searchanise/ApiSe')->setNotification(
313
+ 'N',
314
+ Mage::helper('searchanise')->__('Notice'),
315
+ str_replace('[language]', $store->getName(), Mage::helper('searchanise')->__('Searchanise: New search engine for [language] created. Catalog import started'))
316
+ );
317
+ } else {
318
+ Mage::helper('searchanise/ApiSe')->sendAddonStatusRequest('disabled', $store);
319
+ }
320
+ }
321
+ }
322
+ }
323
+
324
+ return $this;
325
+ }
326
+
327
+ /**
328
+ * Save store
329
+ *
330
+ * @param Varien_Event_Observer $observer
331
+ * @return Mage_CatalogIndex_Model_Observer
332
+ */
333
+ public function searchaniseCoreSaveStoreAfter(Varien_Event_Observer $observer)
334
+ {
335
+ $store = $observer->getData('store');
336
+
337
+ if ($store && $store->getId()) {
338
+ $checkPrivateKey = Mage::helper('searchanise/ApiSe')->checkPrivateKey($store);
339
+
340
+ if (Mage::helper('searchanise/ApiSe')->signup($store, false, false) == true) {
341
+ if (!$checkPrivateKey) {
342
+ if ($store->getIsActive()) {
343
+ Mage::helper('searchanise/ApiSe')->queueImport($store, false);
344
+ Mage::helper('searchanise/ApiSe')->setNotification(
345
+ 'N',
346
+ Mage::helper('searchanise')->__('notice'),
347
+ str_replace('[language]', $store->getName(), Mage::helper('searchanise')->__('Searchanise: New search engine for [language] created. Catalog import started'))
348
+ );
349
+ }
350
+ }
351
+ }
352
+ }
353
+
354
+ return $this;
355
+ }
356
+
357
+ /**
358
+ * Delete store
359
+ *
360
+ * @param Varien_Event_Observer $observer
361
+ * @return Mage_CatalogIndex_Model_Observer
362
+ */
363
+ public function searchaniseCoreDeleteStoreAfter(Varien_Event_Observer $observer)
364
+ {
365
+ $store = $observer->getData('store');
366
+
367
+ if ($store && $store->getId()) {
368
+ Mage::helper('searchanise/ApiSe')->deleteKeys($store);
369
+ }
370
+
371
+ return $this;
372
+ }
373
+
374
+ // FOR ADMINHTML //
375
+ /**
376
+ * Before save adminhtml config data
377
+ *
378
+ * @param Varien_Event_Observer $observer
379
+ * @return Mage_CatalogIndex_Model_Observer
380
+ */
381
+ public function searchaniseAdminhtmlConfigDataSaveBefore(Varien_Event_Observer $observer)
382
+ {
383
+ $model = $observer->getData('object');
384
+ $groups = $model->getGroups();
385
+ $section = $model->getSection();
386
+ $storesIds = $model->getStore();
387
+ $website = $model->getWebsite();
388
+
389
+ if (empty($storesIds)) {
390
+ if (!empty($website)) {
391
+ $storesIds = Mage::helper('searchanise/ApiSe')->getStoreByWebsiteCodes($website);
392
+ }
393
+ }
394
+
395
+ $stores = Mage::helper('searchanise/ApiSe')->getStores(null, $storesIds);
396
+
397
+ if (!empty($stores)) {
398
+ if ($section == 'catalog') {
399
+
400
+ // Change status module
401
+ } elseif ($section == 'advanced') {
402
+ foreach ($groups as $group => $groupData) {
403
+ if (isset($groupData['fields']['Simtech_Searchanise']['value'])) {
404
+ $status = ($groupData['fields']['Simtech_Searchanise']['value']) ? 'D' : 'Y';
405
+
406
+ foreach ($stores as $k => $store) {
407
+ if ($store->getIsActive()) {
408
+ $statusOld = Mage::helper('searchanise/ApiSe')->getStatusModule($store);
409
+
410
+ if ($statusOld != $status) {
411
+ if (Mage::helper('searchanise/ApiSe')->signup($store, false, false) == true) {
412
+ if ($status == 'Y') {
413
+ Mage::helper('searchanise/ApiSe')->sendAddonStatusRequest('enabled', $store);
414
+ Mage::helper('searchanise/ApiSe')->queueImport($store, false);
415
+ Mage::helper('searchanise/ApiSe')->setNotification(
416
+ 'N',
417
+ Mage::helper('searchanise')->__('Notice'),
418
+ str_replace('[language]', $store->getName(), Mage::helper('searchanise')->__('Searchanise: New search engine for [language] created. Catalog import started'))
419
+ );
420
+ } else {
421
+ Mage::helper('searchanise/ApiSe')->sendAddonStatusRequest('disabled', $store);
422
+ }
423
+ }
424
+ }
425
+ }
426
+ }
427
+ }
428
+ }
429
+ }
430
+ }
431
+
432
+ return $this;
433
+ }
434
+ /**
435
+ * After save adminhtml config data
436
+ *
437
+ * @param Varien_Event_Observer $observer
438
+ * @return Mage_CatalogIndex_Model_Observer
439
+ */
440
+ public function searchaniseAdminhtmlConfigDataSaveAfter(Varien_Event_Observer $observer)
441
+ {
442
+ $model = $observer->getData('object');
443
+ $section = $model->getSection();
444
+ $storesIds = $model->getStore();
445
+ $website = $model->getWebsite();
446
+
447
+ if (empty($storesIds)) {
448
+ if (!empty($website)) {
449
+ $storesIds = Mage::helper('searchanise/ApiSe')->getStoreByWebsiteCodes($website);
450
+ }
451
+ }
452
+
453
+ $stores = Mage::helper('searchanise/ApiSe')->getStores(null, $storesIds);
454
+
455
+ if (!empty($stores)) {
456
+ if ($section == 'catalog') {
457
+ foreach ($stores as $k => $store) {
458
+ $filters = Mage::helper('searchanise/ApiSe')->getPriceFilters($store);
459
+
460
+ if (!empty($filters)) {
461
+ foreach ($filters as $filter) {
462
+ Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_FACET_UPDATE, $filter->getId(), $store);
463
+ }
464
+ }
465
+
466
+ // change facet-prices
467
+ {
468
+ $queueData = array(
469
+ 'data' => serialize(Simtech_Searchanise_Model_Queue::DATA_FACET_PRICES),
470
+ 'action' => Simtech_Searchanise_Model_Queue::ACT_FACET_UPDATE,
471
+ 'store_id' => $store->getId(),
472
+ );
473
+
474
+ Mage::getModel('searchanise/queue')->setData($queueData)->save();
475
+ }
476
+ }
477
+
478
+ // Change status module
479
+ } elseif ($section == 'advanced') {
480
+
481
+ }
482
+ }
483
+
484
+ return $this;
485
+ }
486
+
487
+ // FOR EAV //
488
+ /**
489
+ * Before save attribute
490
+ *
491
+ * @param Varien_Event_Observer $observer
492
+ * @return Mage_CatalogIndex_Model_Observer
493
+ */
494
+ public function catalogEntityAttributeSaveBefore(Varien_Event_Observer $observer)
495
+ {
496
+ $attribute = $observer->getEvent()->getAttribute();
497
+
498
+ if ($attribute && $attribute->getId()) {
499
+ $isFilterable = $attribute->getData('is_filterable');
500
+ $isFilterableInSearch = $attribute->getData('is_filterable_in_search');
501
+ $flFacet = ($isFilterable) || ($isFilterableInSearch);
502
+
503
+ $flFacetOld = null;
504
+
505
+ $attributeOld = Mage::getModel('catalog/entity_attribute')
506
+ ->load($attribute->getId());
507
+
508
+ if (!empty($attributeOld)) {
509
+ $isFilterableOld = $attributeOld->getData('is_filterable');
510
+ $isFilterableInSearchOld = $attributeOld->getData('is_filterable_in_search');
511
+
512
+ $flFacetOld = ($isFilterableOld) || ($isFilterableInSearchOld);
513
+ }
514
+
515
+ if ($flFacet != $flFacetOld) {
516
+ if ($flFacet) {
517
+ Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_FACET_UPDATE, $attribute->getId());
518
+ } else {
519
+ Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_FACET_DELETE, $attribute->getId());
520
+ }
521
+ }
522
+ }
523
+
524
+ if (($attribute) && (!$attribute->getId())) {
525
+ self::$newAttributes[$attribute->getData('attribute_code')] = true;
526
+ } else {
527
+ // uncomment if need this checking
528
+ // self::$newAttributes[$attribute->getData('attribute_code')] = false;
529
+ }
530
+
531
+ return $this;
532
+ }
533
+
534
+ /**
535
+ * Save attribute
536
+ *
537
+ * @param Varien_Event_Observer $observer
538
+ * @return Mage_CatalogIndex_Model_Observer
539
+ */
540
+ public function catalogEntityAttributeSaveAfter(Varien_Event_Observer $observer)
541
+ {
542
+ $attribute = $observer->getEvent()->getAttribute();
543
+
544
+ if ($attribute && $attribute->getId()) {
545
+ $attributeCode = $attribute->getData('attribute_code');
546
+
547
+ if ((!empty(self::$newAttributes)) &&
548
+ (array_key_exists($attributeCode, self::$newAttributes)) &&
549
+ (self::$newAttributes[$attributeCode])) {
550
+ $isFilterable = $attribute->getData('is_filterable');
551
+ $isFilterableInSearch = $attribute->getData('is_filterable_in_search');
552
+ $flFacet = ($isFilterable) || ($isFilterableInSearch);
553
+
554
+ if ($flFacet) {
555
+ Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_FACET_UPDATE, $attribute->getId());
556
+ }
557
+ }
558
+ }
559
+
560
+ return $this;
561
+ }
562
+
563
+ /**
564
+ * Delete attribute
565
+ *
566
+ * @param Varien_Event_Observer $observer
567
+ * @return Mage_CatalogIndex_Model_Observer
568
+ */
569
+ public function catalogEntityAttributeDeleteAfter(Varien_Event_Observer $observer)
570
+ {
571
+ $attribute = $observer->getEvent()->getAttribute();
572
+
573
+ if ($attribute && $attribute->getId()) {
574
+ $isFilterable = $attribute->getData('is_filterable');
575
+ $isFilterableInSearch = $attribute->getData('is_filterable_in_search');
576
+ $flFacet = ($isFilterable) || ($isFilterableInSearch);
577
+
578
+ if ($flFacet) {
579
+ Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_FACET_DELETE, $attribute->getId());
580
+ }
581
+ }
582
+
583
+ return $this;
584
+ }
585
+
586
+ // FOR TAG //
587
+ /**
588
+ * After save tag
589
+ *
590
+ * @param Varien_Event_Observer $observer
591
+ * @return Mage_CatalogIndex_Model_Observer
592
+ */
593
+ public function tagSaveAfter(Varien_Event_Observer $observer)
594
+ {
595
+ $tag = $observer->getEvent()->getData('object');
596
+
597
+ if (!empty($tag)) {
598
+ $productIds = $tag->getRelatedProductIds();
599
+
600
+ Mage::getModel('searchanise/queue')->addActionProductIds($productIds, Simtech_Searchanise_Model_Queue::ACT_UPDATE);
601
+ }
602
+
603
+ return $this;
604
+ }
605
+
606
+ /**
607
+ * Before delete tag
608
+ *
609
+ * @param Varien_Event_Observer $observer
610
+ * @return Mage_CatalogIndex_Model_Observer
611
+ */
612
+ public function tagDeleteBefore(Varien_Event_Observer $observer)
613
+ {
614
+ $tag = $observer->getEvent()->getData('object');
615
+
616
+ if (!empty($tag)) {
617
+ $productIds = $tag->getRelatedProductIds();
618
+
619
+ Mage::getModel('searchanise/queue')->addActionProductIds($productIds, Simtech_Searchanise_Model_Queue::ACT_UPDATE);
620
+ }
621
+
622
+ return $this;
623
+ }
624
+
625
+ /**
626
+ * Add tag to product
627
+ *
628
+ * @param Varien_Event_Observer $observer
629
+ * @return Mage_CatalogIndex_Model_Observer
630
+ */
631
+ public function searchaniseTagRelationSaveAfter(Varien_Event_Observer $observer)
632
+ {
633
+ // fixme in the future
634
+ // need add check approved tag
635
+ $tagRelation = $observer->getEvent()->getData('object');
636
+
637
+ if (!empty($tagRelation)) {
638
+ $tag = Mage::getModel('tag/tag')
639
+ ->setData('tag_id', $tagRelation->getTagId())
640
+ ->load();
641
+
642
+ if (!empty($tag)) {
643
+ $productIds = $tag->getRelatedProductIds();
644
+
645
+ Mage::getModel('searchanise/queue')->addActionProductIds($productIds, Simtech_Searchanise_Model_Queue::ACT_UPDATE);
646
+ }
647
+ }
648
+
649
+ return $this;
650
+ }
651
+ }
app/code/community/Simtech/Searchanise/Model/Queue.php ADDED
@@ -0,0 +1,333 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Model_Queue extends Mage_Core_Model_Abstract
16
+ {
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,
41
+ self::ACT_START_FULL_IMPORT,
42
+ self::ACT_END_FULL_IMPORT,
43
+ );
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,
56
+ );
57
+
58
+ const STATUS_PENDING = 'pending';
59
+ const STATUS_DISABLED = 'disabled';
60
+ const STATUS_PROCESSING = 'processing';
61
+
62
+ public static $statusTypes = array(
63
+ self::STATUS_PENDING,
64
+ self::STATUS_DISABLED,
65
+ self::STATUS_PROCESSING,
66
+ );
67
+
68
+ protected function _construct()
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();
79
+
80
+ if (!empty($queue['items'])) {
81
+ foreach ($queue['items'] as $item) {
82
+ try {
83
+ Mage::getModel('searchanise/queue')->load($item['queue_id'])->delete();
84
+ } catch (Mage_Core_Exception $e) {
85
+ Mage::helper('searchanise/ApiSe')->log($e->getMessage(), 'Delete error');
86
+ }
87
+ }
88
+ }
89
+ }
90
+
91
+ return true;
92
+ }
93
+
94
+ public function getNextQueueArray($queue_id = null)
95
+ {
96
+ $collection = $this->getCollection()
97
+ ->addOrder('queue_id', 'ASC')
98
+ ->setPageSize(1);
99
+
100
+ if (!empty($queue_id)) {
101
+ $collection->addFieldToFilter('queue_id', array("gt" => $queue_id));
102
+ }
103
+
104
+ return $collection->load()->toArray();
105
+ }
106
+
107
+ public function getNextQueue($queue_id = null)
108
+ {
109
+ $q = array();
110
+ $queue_arr = self::getNextQueueArray();
111
+
112
+ if (!empty($queue_arr['items'])) {
113
+ $q = reset($queue_arr['items']);
114
+ }
115
+
116
+ return $q;
117
+ }
118
+
119
+ public function addAction($action, $data = NULL, $cur_store = null, $cur_store_id = null)
120
+ {
121
+ if (in_array($action, self::$actionTypes))
122
+ {
123
+ if (!Mage::helper('searchanise/ApiSe')->checkParentPrivateKey()) {
124
+ return false;
125
+ }
126
+
127
+ $data = serialize((array)$data);
128
+ $data = array($data);
129
+
130
+ $stores = Mage::helper('searchanise/ApiSe')->getStores($cur_store, $cur_store_id);
131
+
132
+ if ($action == self::ACT_PREPARE_FULL_IMPORT && !empty($cur_store)) {
133
+ // Trucate queue for all
134
+ Mage::getModel('searchanise/queue')
135
+ ->getCollection()
136
+ ->addFilter('store_id', $cur_store->getId())
137
+ ->clear();
138
+ }
139
+
140
+ foreach ($data as $d) {
141
+ foreach ($stores as $k_store => $store) {
142
+ if (Mage::helper('searchanise/ApiSe')->getStatusModule($store) != 'Y') {
143
+ if (!in_array($action, self::$mainActionTypes)) {
144
+ continue;
145
+ }
146
+ }
147
+
148
+ if ($action != self::ACT_PHRASE) {
149
+ // Remove duplicate actions
150
+ $exist_actions = Mage::getModel('searchanise/queue')
151
+ ->getCollection()
152
+ ->addFilter('status', self::STATUS_PENDING)
153
+ ->addFilter('action', $action)
154
+ ->addFilter('data', $data)
155
+ ->addFilter('store_id', $store->getId())
156
+ ->load()
157
+ ->delete();
158
+ }
159
+
160
+ $queue_data = array(
161
+ 'action' => $action,
162
+ 'data' => $d,
163
+ 'store_id' => $store->getId(),
164
+ );
165
+
166
+ $this->setData($queue_data)->save();
167
+ }
168
+ }
169
+
170
+ return true;
171
+ }
172
+
173
+ return false;
174
+ }
175
+
176
+ public function addActionProducts($products)
177
+ {
178
+ if (!empty($products)) {
179
+ $productIds = array();
180
+
181
+ foreach ($products as $product) {
182
+ if ($product->getId()) {
183
+ $productIds[] = $product->getId();
184
+ }
185
+ if (count($productIds) >= Mage::helper('searchanise/ApiSe')->getProductsPerPass()) {
186
+ Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_UPDATE, $productIds);
187
+ $productIds = array();
188
+ }
189
+ }
190
+
191
+ if ((!empty($productIds)) && (count($productIds) > 0)) {
192
+ Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_UPDATE, $productIds);
193
+ }
194
+ }
195
+
196
+ return $this;
197
+ }
198
+
199
+ public function addActionProductIdsForAllStore($productIds, $action = self::ACT_UPDATE)
200
+ {
201
+ if (!empty($productIds)) {
202
+ if (count($productIds) <= Mage::helper('searchanise/ApiSe')->getProductsPerPass()) {
203
+ Mage::getModel('searchanise/queue')->addAction($action, $productIds);
204
+ } else {
205
+ $actProductIds = array();
206
+
207
+ foreach ($productIds as $productId) {
208
+ if ($productId) {
209
+ $actProductIds[] = $productId;
210
+ }
211
+ if (count($actProductIds) >= Mage::helper('searchanise/ApiSe')->getProductsPerPass()) {
212
+ Mage::getModel('searchanise/queue')->addAction($action, $actProductIds);
213
+ $actProductIds = array();
214
+ }
215
+ }
216
+
217
+ if (!empty($actProductIds)) {
218
+ Mage::getModel('searchanise/queue')->addAction($action, $productIds);
219
+ }
220
+ }
221
+ }
222
+
223
+ return $this;
224
+ }
225
+
226
+ public function addActionProductIds($productIds, $action = self::ACT_UPDATE)
227
+ {
228
+ if (!empty($productIds)) {
229
+ if (!is_array($productIds)) {
230
+ $productIds = array(0 => $productIds);
231
+ }
232
+
233
+ foreach ($productIds as $k => $productId) {
234
+ $storeIds = null;
235
+ $product = Mage::getModel('catalog/product')
236
+ ->load($productId);
237
+
238
+ if (!empty($product)) {
239
+ $storeIds = $product->getStoreIds();
240
+ }
241
+
242
+ Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_UPDATE, $productId, null, $storeIds);
243
+ }
244
+ }
245
+
246
+ return $this;
247
+ }
248
+
249
+ public function addActionOrderItems($items)
250
+ {
251
+ if (!empty($items)) {
252
+ $productIds = array();
253
+
254
+ foreach ($items as $item) {
255
+ if ($item->getProductId()) {
256
+ $productIds[] = $item->getProductId();
257
+ }
258
+ if (count($productIds) >= Mage::helper('searchanise/ApiSe')->getProductsPerPass()) {
259
+ Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_UPDATE, $productIds, null, $item->getStoreId());
260
+ $productIds = array();
261
+ }
262
+ }
263
+
264
+ if (!empty($productIds)) {
265
+ Mage::getModel('searchanise/queue')->addAction(Simtech_Searchanise_Model_Queue::ACT_UPDATE, $productIds, null, $item->getStoreId());
266
+ }
267
+ }
268
+
269
+ return $this;
270
+ }
271
+
272
+ public function addActionDeleteProductFromOldStore($product = null)
273
+ {
274
+ if ($product && $product->getId()) {
275
+ $storeIds = $product->getStoreIds();
276
+
277
+ $product_old = Mage::getModel('catalog/product')
278
+ ->load($product->getId());
279
+
280
+ if (!empty($product_old)) {
281
+ $storeIdsOld = $product_old->getStoreIds();
282
+
283
+ if (!empty($storeIdsOld)) {
284
+ foreach ($storeIdsOld as $k => $storeIdOld) {
285
+ if ((empty($storeIds)) || (!in_array($storeIdOld, $storeIds))) {
286
+ $this->addAction(Simtech_Searchanise_Model_Queue::ACT_DELETE, $product->getId(), null, $storeIdOld);
287
+ }
288
+ }
289
+ }
290
+ }
291
+ }
292
+
293
+ return $this;
294
+ }
295
+
296
+ public function addActionDeleteProduct($product = null)
297
+ {
298
+ if ($product && $product->getId()) {
299
+ $storeIds = $product->getStoreIds();
300
+
301
+ if (!empty($storeIds)) {
302
+ foreach ($storeIds as $k => $storeId) {
303
+ $this->addAction(Simtech_Searchanise_Model_Queue::ACT_DELETE, $product->getId(), null, $storeId);
304
+ }
305
+ }
306
+ }
307
+
308
+ return $this;
309
+ }
310
+
311
+ public function addActionUpdateProduct($product = null, $storeIds = null)
312
+ {
313
+ if ($product && $product->getId()) {
314
+ if (!empty($storeIds)) {
315
+ if (!is_array($storeIds)) {
316
+ $storeIds = array(0 => $storeIds);
317
+ }
318
+ }
319
+
320
+ if (empty($storeIds)) {
321
+ $storeIds = $product->getStoreIds();
322
+ }
323
+
324
+ if (!empty($storeIds)) {
325
+ foreach ($storeIds as $k => $storeId) {
326
+ $this->addAction(Simtech_Searchanise_Model_Queue::ACT_UPDATE, $product->getId(), null, $storeId);
327
+ }
328
+ }
329
+ }
330
+
331
+ return $this;
332
+ }
333
+ }
app/code/community/Simtech/Searchanise/Model/Request.php ADDED
@@ -0,0 +1,554 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Simtech_Searchanise_Model_Request extends Mage_Core_Model_Abstract
4
+ {
5
+ protected $searchResult = null;
6
+ protected $productIdsSting = null;
7
+ protected $attributesCount = array();
8
+
9
+ const SEPARATOR_ITEMS = "'";
10
+
11
+ protected $searchParams = array();
12
+
13
+ protected $apiKey = '';
14
+ protected $privateKey = '';
15
+ protected $store = null;
16
+
17
+ protected function _construct()
18
+ {
19
+ return $this;
20
+ }
21
+
22
+ public function setStore($value)
23
+ {
24
+ $this->store = $value;
25
+
26
+ return $this;
27
+ }
28
+
29
+ public function getStore()
30
+ {
31
+ return $this->store;
32
+ }
33
+
34
+ public function getPrivateKey()
35
+ {
36
+ return Mage::helper('searchanise/ApiSe')->getPrivateKey($this->store);
37
+ }
38
+
39
+ public function getApiKey()
40
+ {
41
+ return Mage::helper('searchanise/ApiSe')->getApiKey($this->store);
42
+ }
43
+
44
+ public function checkApiKey()
45
+ {
46
+ if ($this->getApiKey()) {
47
+ return true;
48
+ }
49
+
50
+ return false;
51
+ }
52
+
53
+ public function checkSearchResult()
54
+ {
55
+ if (!empty($this->searchResult)) {
56
+ return true;
57
+ }
58
+
59
+ return false;
60
+ }
61
+
62
+ public function setSearchResult($value = array())
63
+ {
64
+ $this->searchResult = $value;
65
+
66
+ $this->setProductIdsString();
67
+ $this->setAttributesCount();
68
+
69
+ return $this;
70
+ }
71
+
72
+ public function getSearchResult()
73
+ {
74
+ return $this->searchResult;
75
+ }
76
+
77
+ public function setAttributesCount($value = array())
78
+ {
79
+ $this->attributesCount = $value;
80
+
81
+ return $this;
82
+ }
83
+
84
+ public function getAttributesCount()
85
+ {
86
+ return $this->attributesCount;
87
+ }
88
+
89
+ public function setAttributesCountLabel($value = '', $label = '')
90
+ {
91
+ if (empty($this->attributesCount)) {
92
+ $this->attributesCount = array();
93
+ }
94
+
95
+ $this->attributesCount[$label] = $value;
96
+
97
+ return $this;
98
+ }
99
+
100
+ public function getAttributesCountLabel($label = '')
101
+ {
102
+ if (!empty($label)) {
103
+ return $this->attributesCount[$label];
104
+ }
105
+
106
+ return null;
107
+ }
108
+
109
+ public function checkAttributesCountLabel($label = '')
110
+ {
111
+ if (isset($this->attributesCount[$label])) {
112
+ return true;
113
+ }
114
+
115
+ return false;
116
+ }
117
+
118
+ public function getProductIds()
119
+ {
120
+ $res = $this->getSearchResult();
121
+
122
+ return empty($res['items']) ? array() : $res['items'];
123
+ }
124
+
125
+ public function setProductIdsString($value = '')
126
+ {
127
+ $this->productIdsString = $value;
128
+
129
+ return $this;
130
+ }
131
+
132
+ public function getProductIdsString()
133
+ {
134
+ if (empty($this->productIdsString))
135
+ {
136
+ $res = $this->getSearchResult();
137
+ $productIdsString = '';
138
+
139
+ if (!empty($res['items'])) {
140
+ foreach ($res['items'] as $k => $item)
141
+ {
142
+ if (!empty($item['product_id'])) {
143
+ if (empty($productIdsString)) {
144
+ $productIdsString = self::SEPARATOR_ITEMS . $item['product_id'] . self::SEPARATOR_ITEMS;
145
+ } else {
146
+ $productIdsString .= ',' . self::SEPARATOR_ITEMS . $item['product_id'] . self::SEPARATOR_ITEMS;
147
+ }
148
+ }
149
+ }
150
+ }
151
+
152
+ $this->setProductIdsString($productIdsString);
153
+ }
154
+
155
+ return $this->productIdsString;
156
+ }
157
+
158
+ public function getTotalProduct()
159
+ {
160
+ $res = $this->getSearchResult();
161
+
162
+ return empty($res['totalItems']) ? 0 : $res['totalItems'];
163
+ }
164
+
165
+ public function getSuggestions()
166
+ {
167
+ $res = $this->getSearchResult();
168
+
169
+ return empty($res['suggestions']) ? null : $res['suggestions'];
170
+ }
171
+
172
+ public function setSearchParams($params = array())
173
+ {
174
+ $this->searchParams = $params;
175
+
176
+ return $this;
177
+ }
178
+
179
+ public function setSearchParam($key, $value)
180
+ {
181
+ if (empty($this->searchParams)) {
182
+ $this->searchParams = array();
183
+ }
184
+
185
+ $this->searchParams[$key] = $value;
186
+
187
+ return $this;
188
+ }
189
+
190
+ public function getSearchParams()
191
+ {
192
+ return $this->searchParams;
193
+ }
194
+
195
+ protected function getStrFromParams($params = array(), $mainKey = null)
196
+ {
197
+ $ret = '';
198
+
199
+ if (!empty($params)) {
200
+ foreach ($params as $key => $param) {
201
+ if (is_array($param)) {
202
+ $ret .= $this->getStrFromParams($param, $key);
203
+ } else {
204
+ if (!$mainKey) {
205
+ $ret .= $key . '=' . $param . '&';
206
+ } else {
207
+ $ret .= $mainKey . '[' . $key . ']=' . $param . '&';
208
+ }
209
+ }
210
+ }
211
+ }
212
+
213
+ return $ret;
214
+ }
215
+
216
+ public function getSearchParamsStr()
217
+ {
218
+ return $this->getStrFromParams($this->getSearchParams());
219
+ }
220
+
221
+ public function mergeSearchParams($new_params = array())
222
+ {
223
+ return $this->setSearchParams(array_merge($new_params, $this->getSearchParams()));
224
+ }
225
+
226
+ public function unsetSearchParams($key = '')
227
+ {
228
+ if (isset($this->searchParams[$key])) {
229
+ unset($this->searchParams[$key]);
230
+ }
231
+
232
+ return $this;
233
+ }
234
+
235
+ public function checkSearchParams($key = '')
236
+ {
237
+ if (empty($this->searchParams[$key])) {
238
+ return $this->unsetSearchParams($key);
239
+ }
240
+
241
+ return $this;
242
+ }
243
+
244
+ public function sendSearchRequest()
245
+ {
246
+ $this->setSearchResult();
247
+
248
+ if (!$this->checkApiKey()) {
249
+ return $this;
250
+ }
251
+
252
+ $default_params = array(
253
+ 'items' => 'true',
254
+ 'facets' => 'true',
255
+ 'output' => 'json',
256
+ );
257
+
258
+ $this
259
+ ->mergeSearchParams($default_params)
260
+ ->checkSearchParams('restrictBy')
261
+ ->checkSearchParams('union');
262
+
263
+ $query = Mage::helper('searchanise/ApiSe')->buildQuery($this->getSearchParams());
264
+ $this->setSearchParam('api_key', $this->getApiKey());
265
+ if (Mage::helper('searchanise')->checkDebug()) {
266
+ Mage::helper('searchanise/ApiSe')->printR($this->getSearchParamsStr());
267
+ Mage::helper('searchanise/ApiSe')->printR($this->getSearchParams());
268
+ }
269
+
270
+ if (strlen($query) > Mage::helper('searchanise/ApiSe')->getMaxSearchRequestLength()) {
271
+ list($header, $received) = Mage::helper('searchanise/ApiSe')->httpRequest(
272
+ Zend_Http_Client::POST,
273
+ Mage::helper('searchanise/ApiSe')->getServiceUrl() . '/search?api_key=' . $this->getApiKey(),
274
+ $this->getSearchParams(),
275
+ array(),
276
+ array(),
277
+ Mage::helper('searchanise/ApiSe')->getSearchTimeout()
278
+ );
279
+ } else {
280
+ list($header, $received) = Mage::helper('searchanise/ApiSe')->httpRequest(
281
+ Zend_Http_Client::GET,
282
+ Mage::helper('searchanise/ApiSe')->getServiceUrl() . '/search',
283
+ $this->getSearchParams(),
284
+ array(),
285
+ array(),
286
+ Mage::helper('searchanise/ApiSe')->getSearchTimeout()
287
+ );
288
+ }
289
+
290
+ if (empty($received)) {
291
+ return $this;
292
+ }
293
+ $result = Mage::helper('core')->jsonDecode($received);
294
+ if (Mage::helper('searchanise')->checkDebug()) {
295
+ Mage::helper('searchanise/ApiSe')->printR($result);
296
+ }
297
+
298
+ if (isset($result['error'])) {
299
+ if ($result['error'] == 'EMPTY_API_KEY') {
300
+ // nothing
301
+ } elseif ($result['error'] == 'INVALID_API_KEY') {
302
+ if ($this->getStore()) {
303
+ Mage::helper('searchanise/ApiSe')->deleteKeys($this->getStore());
304
+
305
+ if (Mage::helper('searchanise/ApiSe')->signup($this->getStore(), false) == true) {
306
+ Mage::helper('searchanise/ApiSe')->queueImport($this->getStore(), false);
307
+ }
308
+ }
309
+ } elseif ($result['error'] == 'TO_BIG_START_INDEX') {
310
+ // nothing
311
+ } elseif ($result['error'] == 'SEARCH_DATA_NOT_IMPORTED') {
312
+ // nothing
313
+ } elseif ($result['error'] == 'FULL_IMPORT_PROCESSED') {
314
+ // nothing
315
+ } elseif ($result['error'] == 'FACET_ERROR_TOO_MANY_ATTRIBUTES') {
316
+ // nothing
317
+ } elseif ($result['error'] == 'NEED_RESYNC_YOUR_CATALOG') {
318
+ Mage::helper('searchanise/ApiSe')->queueImport($this->getStore(), false);
319
+ } elseif ($result['error'] == 'NAVIGATION_DISABLED') {
320
+ Mage::helper('searchanise/ApiSe')->setUseNavigation(false);
321
+ }
322
+
323
+ Mage::helper('searchanise/ApiSe')->log($result['error']);
324
+
325
+ return $this;
326
+ }
327
+
328
+ if (empty($result) || !is_array($result) || !isset($result['totalItems'])) {
329
+ return $this;
330
+ }
331
+
332
+ $this->setSearchResult($result);
333
+
334
+ return $this;
335
+ }
336
+
337
+ /**
338
+ *
339
+ *
340
+ * @param Mage_Catalog_Model_Layer_Filter_Attribute $filter
341
+ * @return array
342
+ */
343
+ public function getCountAttribute($filter)
344
+ {
345
+ $ret = array();
346
+ if (empty($filter)) {
347
+ return $ret;
348
+ }
349
+
350
+ $attribute = $filter->getAttributeModel();
351
+ if (empty($attribute)) {
352
+ return $ret;
353
+ }
354
+
355
+ $label = 'attribute_' . $attribute->getId();
356
+
357
+ if (!$this->checkAttributesCountLabel($label)) {
358
+ $vals = array();
359
+ $res = $this->getSearchResult();
360
+
361
+ if (!empty($res['facets'])) {
362
+ foreach ($res['facets'] as $facet) {
363
+ if ($facet['attribute'] == $label) {
364
+ if (!empty($facet['buckets'])) {
365
+ foreach ($facet['buckets'] as $bucket) {
366
+ if ($bucket['count'] > 0) {
367
+ $vals[$bucket['value'] ] = $bucket['count'];
368
+ }
369
+ }
370
+ }
371
+ }
372
+ }
373
+ }
374
+
375
+ $this->setAttributesCountLabel($vals, $label);
376
+ }
377
+
378
+ return $this->getAttributesCountLabel($label);
379
+ }
380
+
381
+ public function getCurrentCurrencyRange($range, $store = null)
382
+ {
383
+ $rate = $this->getCurrentCurrencyRate($store);
384
+
385
+ if (!empty($rate)) {
386
+ return $range / $rate;
387
+ }
388
+
389
+ return $range;
390
+ }
391
+
392
+ public function getCurrentCurrencyRate($store = null)
393
+ {
394
+ if (empty($store)) {
395
+ $store = Mage::app()->getStore();
396
+ }
397
+
398
+ if (!empty($store)) {
399
+ return $store->getCurrentCurrencyRate();
400
+ }
401
+
402
+ return 0;
403
+ }
404
+
405
+ /**
406
+ * Retrieve array with products counts per price range
407
+ *
408
+ * @param Mage_Catalog_Model_Layer_Filter_Price $filter
409
+ * @param int $range
410
+ * @return array
411
+ */
412
+ public function getCountAttributePrice($filter, $range)
413
+ {
414
+ $ret = array();
415
+
416
+ $rate = $this->getCurrentCurrencyRate($this->store);
417
+
418
+ if ((empty($filter)) || (empty($rate))) {
419
+ return $ret;
420
+ }
421
+
422
+ $attribute = $filter->getAttributeModel();
423
+ if (empty($attribute)) {
424
+ return $ret;
425
+ }
426
+
427
+ $name = $attribute->getName();
428
+ // hook, need for 'union'
429
+ if ($name == 'price') {
430
+ $label = 'price';
431
+ } else {
432
+ $label = 'attribute_' . $attribute->getId();
433
+ }
434
+
435
+ if (!$this->checkAttributesCountLabel($label)) {
436
+ $vals = array();
437
+ $res = $this->getSearchResult();
438
+
439
+ if (!empty($res['facets'])) {
440
+ foreach ($res['facets'] as $facet) {
441
+ if ($facet['attribute'] == $label) {
442
+ if (!empty($facet['buckets'])) {
443
+ foreach ($facet['buckets'] as $bucket) {
444
+ // Example
445
+ //~ [value] => 1000-2000
446
+ //~ [title] => 1000 - 2000
447
+ //~ [from] => 1000
448
+ //~ [to] => 2000
449
+ //~ [count] => 2
450
+ $numberStep = round($bucket['to'] * $rate / $range);
451
+
452
+ if ($numberStep > 0) {
453
+ $vals[$numberStep] = $bucket['count'];
454
+ }
455
+ }
456
+ }
457
+ }
458
+ }
459
+ }
460
+
461
+ $this->setAttributesCountLabel($vals, $label);
462
+ }
463
+
464
+ return $this->getAttributesCountLabel($label);
465
+ }
466
+
467
+ /**
468
+ * Retrieve array with products counts per price range
469
+ *
470
+ * @param Mage_Catalog_Model_Resource_Eav_Attribute $attribute
471
+ * @return array
472
+ */
473
+ public function getPriceRangeFromAttribute($attribute)
474
+ {
475
+ $ret = 0;
476
+
477
+ if (!$attribute) {
478
+ return $ret;
479
+ }
480
+
481
+ $label = 'attribute_' . $attribute->getId();
482
+ $vals = array();
483
+ $res = $this->getSearchResult();
484
+
485
+ if (!empty($res['facets'])) {
486
+ foreach ($res['facets'] as $facet) {
487
+ if ($facet['attribute'] == $label) {
488
+ if (!empty($facet['buckets'])) {
489
+ foreach ($facet['buckets'] as $bucket) {
490
+ // Example
491
+ //~ [value] => 1000-2000
492
+ //~ [title] => 1000 - 2000
493
+ //~ [from] => 1000
494
+ //~ [to] => 2000
495
+ //~ [count] => 2
496
+
497
+ return $bucket['to'] - $bucket['from'];
498
+ }
499
+ }
500
+ }
501
+ }
502
+ }
503
+
504
+ return $ret;
505
+ }
506
+
507
+ public function getCountProductCategory($category)
508
+ {
509
+ $ret = null;
510
+ if (empty($category)) {
511
+ return $ret;
512
+ }
513
+
514
+ $label = 'category' . $category->getId();
515
+
516
+ if (!$this->checkAttributesCountLabel($label))
517
+ {
518
+ $val = 0;
519
+ $res = $this->getSearchResult();
520
+
521
+ if (!empty($res['facets']))
522
+ {
523
+ // fixme in the future
524
+ // error calc count product in category
525
+ $arr_cat = null;
526
+ Mage::helper('searchanise/ApiSe')->getAllChildrenCategories($arr_cat, $category);
527
+
528
+ foreach ($res['facets'] as $facet)
529
+ {
530
+ if ($facet['attribute'] == 'categories')
531
+ {
532
+ if (!empty($facet['buckets']))
533
+ {
534
+ foreach ($facet['buckets'] as $bucket)
535
+ {
536
+ if (in_array($bucket['value'], $arr_cat)) {
537
+ $val += $bucket['count'];
538
+ }
539
+ }
540
+ }
541
+ }
542
+ }
543
+ }
544
+
545
+ if ($val > $this->getTotalProduct()) {
546
+ $val = $this->getTotalProduct();
547
+ }
548
+
549
+ $this->setAttributesCountLabel($val, $label);
550
+ }
551
+
552
+ return $this->getAttributesCountLabel($label);
553
+ }
554
+ }
app/code/community/Simtech/Searchanise/Model/Resource/Advanced/Collection.php ADDED
@@ -0,0 +1,114 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Model_Resource_Advanced_Collection extends Mage_CatalogSearch_Model_Resource_Advanced_Collection
16
+ {
17
+ /**
18
+ * Searchanise request
19
+ *
20
+ * @var Simtech_Searchanise_Model_Request
21
+ */
22
+ protected $_searchaniseRequest = null;
23
+
24
+ public function initSearchaniseRequest()
25
+ {
26
+ $this->_searchaniseRequest = Mage::getModel('searchanise/request');
27
+
28
+ return $this;
29
+ }
30
+
31
+ public function checkSearchaniseResult()
32
+ {
33
+ return Mage::helper('searchanise/ApiSe')->checkSearchaniseResult($this->_searchaniseRequest);
34
+ }
35
+
36
+ public function setSearchaniseRequest($request)
37
+ {
38
+ $this->_searchaniseRequest = $request;
39
+ }
40
+
41
+ public function getSearchaniseRequest()
42
+ {
43
+ return $this->_searchaniseRequest;
44
+ }
45
+
46
+ public function addSearchaniseFilter()
47
+ {
48
+ $this->addFieldToFilter('entity_id', array('in' => $this->getSearchaniseRequest()->getProductIds()));
49
+
50
+ return $this;
51
+ }
52
+
53
+ /**
54
+ * Set Order field
55
+ *
56
+ * @param string $attribute
57
+ * @param string $dir
58
+ * @return Mage_CatalogSearch_Model_Resource_Fulltext_Collection
59
+ */
60
+ public function setOrder($attribute, $dir = 'desc')
61
+ {
62
+ if (!Mage::helper('searchanise/ApiSe')->checkSearchaniseResult(true)) {
63
+ return parent::setOrder($attribute, $dir);
64
+ }
65
+
66
+ if (!$this->checkSearchaniseResult()) {
67
+ return parent::setOrder($attribute, $dir);
68
+ }
69
+
70
+ if ($attribute == 'relevance') {
71
+ $product_ids = $this
72
+ ->getSearchaniseRequest()
73
+ ->getProductIdsString();
74
+ if (!empty($product_ids)) {
75
+ $this->getSelect()->order("FIELD (e.entity_id, {$product_ids}) {$dir}");
76
+ }
77
+ } else {
78
+ parent::setOrder($attribute, $dir);
79
+ }
80
+
81
+ return $this;
82
+ }
83
+
84
+ /**
85
+ * Retrieve collection last page number
86
+ *
87
+ * @return int
88
+ */
89
+ public function getLastPageNumber()
90
+ {
91
+ if (!Mage::helper('searchanise/ApiSe')->checkSearchaniseResult(true)) {
92
+ return parent::getLastPageNumber();
93
+ }
94
+
95
+ if (!$this->checkSearchaniseResult()) {
96
+ return parent::getLastPageNumber();
97
+ }
98
+
99
+ $collectionSize = (int) $this
100
+ ->getSearchaniseRequest()
101
+ ->getTotalProduct();
102
+
103
+ if (0 === $collectionSize) {
104
+ return 1;
105
+ }
106
+ elseif ($this->_pageSize) {
107
+ return ceil($collectionSize/$this->_pageSize);
108
+ }
109
+ else{
110
+ return 1;
111
+ }
112
+ }
113
+ }
114
+
app/code/community/Simtech/Searchanise/Model/Resource/Fulltext.php ADDED
@@ -0,0 +1,27 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ require_once("Mage/CatalogSearch/Model/Resource/Fulltext.php");
15
+
16
+ class Simtech_Searchanise_Model_Resource_Fulltext extends Mage_CatalogSearch_Model_Resource_Fulltext
17
+ {
18
+ public function prepareResult($object, $queryText, $query)
19
+ {
20
+ if (!Mage::helper('searchanise')->checkSearchaniseResult()) {
21
+ return parent::prepareResult($object, $queryText, $query);
22
+ }
23
+
24
+ return $this;
25
+ }
26
+ }
27
+
app/code/community/Simtech/Searchanise/Model/Resource/Fulltext/Collection.php ADDED
@@ -0,0 +1,113 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Model_Resource_Fulltext_Collection extends Mage_CatalogSearch_Model_Resource_Fulltext_Collection
16
+ {
17
+ /**
18
+ * Searchanise request
19
+ *
20
+ * @var Simtech_Searchanise_Model_Request
21
+ */
22
+ protected $_searchaniseRequest = null;
23
+
24
+ public function initSearchaniseRequest()
25
+ {
26
+ $this->_searchaniseRequest = Mage::getModel('searchanise/request');
27
+
28
+ return $this;
29
+ }
30
+
31
+ public function checkSearchaniseResult()
32
+ {
33
+ return Mage::helper('searchanise/ApiSe')->checkSearchaniseResult($this->_searchaniseRequest);
34
+ }
35
+
36
+ public function setSearchaniseRequest($request)
37
+ {
38
+ $this->_searchaniseRequest = $request;
39
+ }
40
+
41
+ public function getSearchaniseRequest()
42
+ {
43
+ return $this->_searchaniseRequest;
44
+ }
45
+
46
+ public function addSearchaniseFilter()
47
+ {
48
+ $this->addFieldToFilter('entity_id', array('in' => $this->getSearchaniseRequest()->getProductIds()));
49
+
50
+ return $this;
51
+ }
52
+
53
+ /**
54
+ * Set Order field
55
+ *
56
+ * @param string $attribute
57
+ * @param string $dir
58
+ * @return Mage_CatalogSearch_Model_Resource_Fulltext_Collection
59
+ */
60
+ public function setOrder($attribute, $dir = 'desc')
61
+ {
62
+ if (!Mage::helper('searchanise/ApiSe')->checkSearchaniseResult(true)) {
63
+ return parent::setOrder($attribute, $dir);
64
+ }
65
+
66
+ if (!$this->checkSearchaniseResult()) {
67
+ return parent::setOrder($attribute, $dir);
68
+ }
69
+
70
+ if ($attribute == 'relevance') {
71
+ $product_ids = $this
72
+ ->getSearchaniseRequest()
73
+ ->getProductIdsString();
74
+ if (!empty($product_ids)) {
75
+ $this->getSelect()->order("FIELD (e.entity_id, {$product_ids}) {$dir}");
76
+ }
77
+ } else {
78
+ parent::setOrder($attribute, $dir);
79
+ }
80
+
81
+ return $this;
82
+ }
83
+
84
+ /**
85
+ * Retrieve collection last page number
86
+ *
87
+ * @return int
88
+ */
89
+ public function getLastPageNumber()
90
+ {
91
+ if (!Mage::helper('searchanise/ApiSe')->checkSearchaniseResult(true)) {
92
+ return parent::getLastPageNumber();
93
+ }
94
+
95
+ if (!$this->checkSearchaniseResult()) {
96
+ return parent::getLastPageNumber();
97
+ }
98
+
99
+ $collectionSize = (int) $this
100
+ ->getSearchaniseRequest()
101
+ ->getTotalProduct();
102
+
103
+ if (0 === $collectionSize) {
104
+ return 1;
105
+ }
106
+ elseif ($this->_pageSize) {
107
+ return ceil($collectionSize/$this->_pageSize);
108
+ }
109
+ else{
110
+ return 1;
111
+ }
112
+ }
113
+ }
app/code/community/Simtech/Searchanise/Model/Resource/Layer/Filter/Attribute.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Model_Resource_Layer_Filter_Attribute extends Mage_Catalog_Model_Resource_Layer_Filter_Attribute
16
+ {
17
+ /**
18
+ * Retrieve array with products counts per attribute option
19
+ *
20
+ * @param Mage_Catalog_Model_Layer_Filter_Attribute $filter
21
+ * @return array
22
+ */
23
+ public function getCount($filter)
24
+ {
25
+ if (!Mage::helper('searchanise/ApiSe')->checkSearchaniseResult(true)) {
26
+ return parent::getCount($filter);
27
+ }
28
+
29
+ $collection = $filter->getLayer()->getProductCollection();
30
+
31
+ if ((!method_exists($collection, 'checkSearchaniseResult')) || (!$collection->checkSearchaniseResult()))
32
+ {
33
+ return parent::getCount($filter);
34
+ }
35
+
36
+ return $collection
37
+ ->getSearchaniseRequest()
38
+ ->getCountAttribute($filter);
39
+ }
40
+ }
app/code/community/Simtech/Searchanise/Model/Resource/Layer/Filter/Price.php ADDED
@@ -0,0 +1,55 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Model_Resource_Layer_Filter_Price extends Mage_Catalog_Model_Resource_Layer_Filter_Price
16
+ {
17
+ public function getCount($filter, $range)
18
+ {
19
+ if (!Mage::helper('searchanise/ApiSe')->checkSearchaniseResult(true)) {
20
+ return parent::getCount($filter, $range);
21
+ }
22
+
23
+ $collection = $filter->getLayer()->getProductCollection();
24
+
25
+ if ((!method_exists($collection, 'checkSearchaniseResult')) || (!$collection->checkSearchaniseResult())) {
26
+ return parent::getCount($filter, $range);
27
+ }
28
+
29
+ return $collection
30
+ ->getSearchaniseRequest()
31
+ ->getCountAttributePrice($filter, $range);
32
+ }
33
+
34
+ /**
35
+ * Apply price range filter to product collection
36
+ *
37
+ * @param Mage_Catalog_Model_Layer_Filter_Price $filter
38
+ * @return Mage_Catalog_Model_Resource_Layer_Filter_Price
39
+ */
40
+ public function applyPriceRange($filter)
41
+ {
42
+ if (!Mage::helper('searchanise/ApiSe')->checkSearchaniseResult(true)) {
43
+ return parent::applyPriceRange($filter);
44
+ }
45
+
46
+ $collection = $filter->getLayer()->getProductCollection();
47
+
48
+ if ((!method_exists($collection, 'checkSearchaniseResult')) || (!$collection->checkSearchaniseResult())) {
49
+ return parent::applyPriceRange($filter);
50
+ }
51
+ // disable internal price filter
52
+
53
+ return $this;
54
+ }
55
+ }
app/code/community/Simtech/Searchanise/Model/Resource/Product/Collection.php ADDED
@@ -0,0 +1,105 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Model_Resource_Product_Collection extends Mage_Catalog_Model_Resource_Product_Collection
16
+ {
17
+ /**
18
+ * Searchanise request
19
+ *
20
+ * @var Simtech_Searchanise_Model_Request
21
+ */
22
+ protected $_searchaniseRequest = null;
23
+
24
+ public function initSearchaniseRequest()
25
+ {
26
+ $this->_searchaniseRequest = Mage::getModel('searchanise/request');
27
+
28
+ return $this;
29
+ }
30
+
31
+ public function checkSearchaniseResult()
32
+ {
33
+ return Mage::helper('searchanise/ApiSe')->checkSearchaniseResult($this->_searchaniseRequest);
34
+ }
35
+
36
+ public function setSearchaniseRequest($request)
37
+ {
38
+ $this->_searchaniseRequest = $request;
39
+ }
40
+
41
+ public function getSearchaniseRequest()
42
+ {
43
+ return $this->_searchaniseRequest;
44
+ }
45
+
46
+ public function addSearchaniseFilter()
47
+ {
48
+ $this->addFieldToFilter('entity_id', array('in' => $this->getSearchaniseRequest()->getProductIds()));
49
+
50
+ return $this;
51
+ }
52
+
53
+ /**
54
+ * Retrieve collection last page number
55
+ *
56
+ * @return int
57
+ */
58
+ public function getLastPageNumber()
59
+ {
60
+ if (!$this->checkSearchaniseResult()) {
61
+ return parent::getLastPageNumber();
62
+ }
63
+
64
+ $collectionSize = (int) $this
65
+ ->getSearchaniseRequest()
66
+ ->getTotalProduct();
67
+
68
+ if (0 === $collectionSize) {
69
+ return 1;
70
+ } elseif ($this->_pageSize) {
71
+ return ceil($collectionSize/$this->_pageSize);
72
+ }
73
+
74
+ return 1;
75
+ }
76
+
77
+ /**
78
+ * Set Order field
79
+ *
80
+ * @param string $attribute
81
+ * @param string $dir
82
+ * @return Mage_CatalogSearch_Model_Resource_Fulltext_Collection
83
+ */
84
+ public function setOrder($attribute, $dir = 'desc')
85
+ {
86
+ if (!$this->checkSearchaniseResult()) {
87
+ return parent::setOrder($attribute, $dir);
88
+ }
89
+
90
+ if ($attribute == 'relevance') {
91
+ $product_ids = $this
92
+ ->getSearchaniseRequest()
93
+ ->getProductIdsString();
94
+
95
+ if (!empty($product_ids)){
96
+ $this->getSelect()->order("FIELD (e.entity_id, {$product_ids}) {$dir}");
97
+ }
98
+
99
+ } else {
100
+ parent::setOrder($attribute, $dir);
101
+ }
102
+
103
+ return $this;
104
+ }
105
+ }
app/code/community/Simtech/Searchanise/Model/Resource/Product/CollectionTag.php ADDED
@@ -0,0 +1,77 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Model_Resource_Product_CollectionTag extends Mage_Tag_Model_Resource_Product_Collection
16
+ {
17
+ /**
18
+ * Searchanise request
19
+ *
20
+ * @var Simtech_Searchanise_Model_Request
21
+ */
22
+ protected $_searchaniseRequest = null;
23
+
24
+ public function initSearchaniseRequest()
25
+ {
26
+ $this->_searchaniseRequest = Mage::getModel('searchanise/request');
27
+
28
+ return $this;
29
+ }
30
+
31
+ public function checkSearchaniseResult()
32
+ {
33
+ return Mage::helper('searchanise/ApiSe')->checkSearchaniseResult($this->_searchaniseRequest);
34
+ }
35
+
36
+ public function setSearchaniseRequest($request)
37
+ {
38
+ $this->_searchaniseRequest = $request;
39
+ }
40
+
41
+ public function getSearchaniseRequest()
42
+ {
43
+ return $this->_searchaniseRequest;
44
+ }
45
+
46
+ public function addSearchaniseFilter()
47
+ {
48
+ $this->addFieldToFilter('entity_id', array('in' => $this->getSearchaniseRequest()->getProductIds()));
49
+
50
+ return $this;
51
+ }
52
+
53
+ /**
54
+ * Retrieve collection last page number
55
+ *
56
+ * @return int
57
+ */
58
+ public function getLastPageNumber()
59
+ {
60
+ if (!$this->checkSearchaniseResult()) {
61
+ return parent::getLastPageNumber();
62
+ }
63
+
64
+ $collectionSize = (int) $this
65
+ ->getSearchaniseRequest()
66
+ ->getTotalProduct();
67
+
68
+ if (0 === $collectionSize) {
69
+ return 1;
70
+
71
+ } elseif ($this->_pageSize) {
72
+ return ceil($collectionSize/$this->_pageSize);
73
+ }
74
+
75
+ return 1;
76
+ }
77
+ }
app/code/community/Simtech/Searchanise/Model/Resource/Store.php ADDED
@@ -0,0 +1,61 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Model_Resource_Store extends Mage_Core_Model_Resource_Store
16
+ {
17
+ /**
18
+ * Check store code before save
19
+ *
20
+ * @param Mage_Core_Model_Abstract $model
21
+ * @return Mage_Core_Model_Resource_Store
22
+ */
23
+ protected function _beforeSave(Mage_Core_Model_Abstract $model)
24
+ {
25
+ $ret = parent::_beforeSave($model);
26
+
27
+ Mage::dispatchEvent('searchanise_core_save_store_before', array('store' => $model));
28
+
29
+ return $ret;
30
+ }
31
+
32
+ /**
33
+ * Update Store Group data after save store
34
+ *
35
+ * @param Mage_Core_Model_Abstract $object
36
+ * @return Mage_Core_Model_Resource_Store
37
+ */
38
+ protected function _afterSave(Mage_Core_Model_Abstract $object)
39
+ {
40
+ $ret = parent::_afterSave($object);
41
+
42
+ Mage::dispatchEvent('searchanise_core_save_store_after', array('store' => $object));
43
+
44
+ return $ret;
45
+ }
46
+
47
+ /**
48
+ * Remove core configuration data after delete store
49
+ *
50
+ * @param Mage_Core_Model_Abstract $model
51
+ * @return Mage_Core_Model_Resource_Store
52
+ */
53
+ protected function _afterDelete(Mage_Core_Model_Abstract $model)
54
+ {
55
+ $ret = parent::_afterDelete($model);
56
+
57
+ Mage::dispatchEvent('searchanise_core_delete_store_after', array('store' => $model));
58
+
59
+ return $ret;
60
+ }
61
+ }
app/code/community/Simtech/Searchanise/Model/System/Config/Source/Searchanise/TypeAsync.php ADDED
@@ -0,0 +1,41 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ class Simtech_Searchanise_Model_System_Config_Source_Searchanise_TypeAsync
15
+ {
16
+ /**
17
+ * Retrieve option values array
18
+ *
19
+ * @return array
20
+ */
21
+ public function toOptionArray()
22
+ {
23
+ return array(
24
+ array('value' => 1, 'label' => Mage::helper('searchanise')->__('Cron')),
25
+ array('value' => 2, 'label' => Mage::helper('searchanise')->__('Ajax')),
26
+ );
27
+ }
28
+
29
+ /**
30
+ * Get options in "key-value" format
31
+ *
32
+ * @return array
33
+ */
34
+ public function toArray()
35
+ {
36
+ return array(
37
+ 1 => Mage::helper('searchanise')->__('Cron'),
38
+ 2 => Mage::helper('searchanise')->__('Ajax'),
39
+ );
40
+ }
41
+ }
app/code/community/Simtech/Searchanise/Model/Tag/Relation.php ADDED
@@ -0,0 +1,30 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_Model_Tag_Relation extends Mage_Tag_Model_Tag_Relation
16
+ {
17
+ /**
18
+ * Processing object after save data
19
+ *
20
+ * @return Mage_Core_Model_Abstract
21
+ */
22
+ protected function _afterSave()
23
+ {
24
+ $ret = parent::_afterSave();
25
+
26
+ Mage::dispatchEvent('searchanise_tag_relation_save_after', array('object' => $this));
27
+
28
+ return $ret;
29
+ }
30
+ }
app/code/community/Simtech/Searchanise/controllers/AdvancedController.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ require_once("Mage/CatalogSearch/controllers/AdvancedController.php");
15
+
16
+ class Simtech_Searchanise_AdvancedController extends Mage_CatalogSearch_AdvancedController
17
+ {
18
+ protected $_defaultToolbarBlock = 'catalog/product_list_toolbar';
19
+ protected $_defaultListBlock = 'catalog/product_list';
20
+
21
+ /**
22
+ * Display search result
23
+ */
24
+ public function resultAction()
25
+ {
26
+ if (!Mage::helper('searchanise/ApiSe')->checkSearchaniseResult(true)) {
27
+ return parent::resultAction();
28
+ }
29
+
30
+ try {
31
+ $query = $this->getRequest()->getQuery();
32
+ } catch (Mage_Core_Exception $e) {
33
+ return parent::resultAction();
34
+ }
35
+
36
+ if ($query) {
37
+ if (Mage::helper('searchanise')->checkEnabled()) {
38
+ $block_toolbar = $this->getLayout()->createBlock($this->_defaultToolbarBlock, microtime());
39
+
40
+ Mage::helper('searchanise')->execute(Simtech_Searchanise_Helper_Data::TEXT_ADVANCED_FIND, $this, $block_toolbar, $query);
41
+ }
42
+ }
43
+
44
+ return parent::resultAction();
45
+ }
46
+ }
app/code/community/Simtech/Searchanise/controllers/AsyncController.php ADDED
@@ -0,0 +1,92 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ class Simtech_Searchanise_AsyncController extends Mage_Core_Controller_Front_Action
15
+ {
16
+ protected $_notUseHttpRequestText = null;
17
+
18
+ public function getNotUseHttpRequestText()
19
+ {
20
+ if (is_null($this->_notUseHttpRequestText)) {
21
+ $this->_notUseHttpRequestText = $this->getRequest()->getParam(Simtech_Searchanise_Helper_ApiSe::NOT_USE_HTTP_REQUEST);
22
+ }
23
+
24
+ return $this->_notUseHttpRequestText;
25
+ }
26
+
27
+ public function checkNotUseHttpRequest()
28
+ {
29
+ return ($this->getNotUseHttpRequestText() == Simtech_Searchanise_Helper_ApiSe::NOT_USE_HTTP_REQUEST_KEY) ? true : false;
30
+ }
31
+
32
+ /**
33
+ * Dispatch event before action
34
+ *
35
+ * @return void
36
+ */
37
+ public function preDispatch()
38
+ {
39
+ $this->setFlag('', self::FLAG_NO_START_SESSION, 1);
40
+ $this->setFlag('', self::FLAG_NO_CHECK_INSTALLATION, 1);
41
+ $this->setFlag('', self::FLAG_NO_COOKIES_REDIRECT, 0);
42
+ $this->setFlag('', self::FLAG_NO_PRE_DISPATCH, 1);
43
+
44
+ parent::preDispatch();
45
+ }
46
+
47
+ /*
48
+ * async
49
+ */
50
+ public function indexAction()
51
+ {
52
+ if (Mage::helper('searchanise/ApiSe')->getStatusModule() == 'Y') {
53
+ Mage::app('admin')->setUseSessionInUrl(false);
54
+ Mage::app('customer')->setUseSessionInUrl(false);
55
+
56
+ if (Mage::helper('searchanise/ApiSe')->checkStartAsync()) {
57
+ $check = $this->checkNotUseHttpRequest();
58
+ // code if need not use httprequest
59
+ // not need in current version
60
+ // $check = true;
61
+
62
+ if ($check) {
63
+ @ignore_user_abort(true);
64
+ @set_time_limit(0);
65
+
66
+ $result = Mage::helper('searchanise/ApiSe')->async();
67
+
68
+ die($result);
69
+
70
+ } else {
71
+ @ignore_user_abort(false);
72
+ @set_time_limit(Mage::helper('searchanise/ApiSe')->getAjaxAsyncTimeout());
73
+ $asyncUrl = Mage::helper('searchanise/ApiSe')->getAsyncUrl(false, 0, false);
74
+
75
+ Mage::helper('searchanise/ApiSe')->httpRequest(
76
+ Zend_Http_Client::GET,
77
+ $asyncUrl,
78
+ array(
79
+ Simtech_Searchanise_Helper_ApiSe::NOT_USE_HTTP_REQUEST => Simtech_Searchanise_Helper_ApiSe::NOT_USE_HTTP_REQUEST_KEY,
80
+ ),
81
+ array(),
82
+ array(),
83
+ Mage::helper('searchanise/ApiSe')->getAjaxAsyncTimeout(),
84
+ 2
85
+ );
86
+ }
87
+ }
88
+ }
89
+
90
+ return $this;
91
+ }
92
+ }
app/code/community/Simtech/Searchanise/controllers/CategoryController.php ADDED
@@ -0,0 +1,71 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ require_once("Mage/Catalog/controllers/CategoryController.php");
15
+
16
+ class Simtech_Searchanise_CategoryController extends Mage_Catalog_CategoryController
17
+ {
18
+ protected $_defaultToolbarBlock = 'catalog/product_list_toolbar';
19
+ protected $_defaultListBlock = 'catalog/product_list';
20
+
21
+ protected function _getCurCategory()
22
+ {
23
+ $categoryId = (int) $this->getRequest()->getParam('id', false);
24
+
25
+ if (!$categoryId) {
26
+ return null;
27
+ }
28
+
29
+ $category = Mage::getModel('catalog/category')
30
+ ->setStoreId(Mage::app()->getStore()->getId())
31
+ ->load($categoryId);
32
+
33
+ if (!Mage::helper('catalog/category')->canShow($category)) {
34
+ return null;
35
+ }
36
+
37
+ return $category;
38
+ }
39
+
40
+ /**
41
+ * Category view action
42
+ */
43
+ public function viewAction()
44
+ {
45
+ if (!Mage::helper('searchanise/ApiSe')->checkSearchaniseResult(true)) {
46
+ return parent::viewAction();
47
+ }
48
+
49
+ if ($category = $this->_getCurCategory()) {
50
+ // If you need a this check, please, uncomment
51
+ //~ $is_anchor = $category->getData('is_anchor');
52
+ //~
53
+ //~ if ($is_anchor == 'Y')
54
+ {
55
+ $display_mode = $category->getData('display_mode');
56
+
57
+ // This check not need
58
+ // if (($display_mode == 'PRODUCTS') || ($display_mode == 'PRODUCTS_AND_PAGE'))
59
+ {
60
+ if (Mage::helper('searchanise')->checkEnabled()) {
61
+ $block_toolbar = $this->getLayout()->createBlock($this->_defaultToolbarBlock, microtime());
62
+
63
+ Mage::helper('searchanise')->execute(Simtech_Searchanise_Helper_Data::VIEW_CATEGORY, $this, $block_toolbar, $category);
64
+ }
65
+ }
66
+ }
67
+ }
68
+
69
+ return parent::viewAction();
70
+ }
71
+ }
app/code/community/Simtech/Searchanise/controllers/IndexController.php ADDED
@@ -0,0 +1,47 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ class Simtech_Searchanise_IndexController extends Mage_Adminhtml_Controller_Action
15
+ {
16
+ protected function _initAction()
17
+ {
18
+ $this->_setActiveMenu('searchanise/index/index');
19
+
20
+ return $this;
21
+ }
22
+
23
+ /*
24
+ * dashboard
25
+ */
26
+ public function indexAction()
27
+ {
28
+ $this->loadLayout();
29
+
30
+ $this->_addContent($this->getLayout()->createBlock('core/text', 'inner-wrap-start')->setText('<div id="searchanise-settings-wrapper">'));
31
+ $this->_addContent(
32
+ $this->getLayout()->createBlock('adminhtml/template')
33
+ ->setTemplate('searchanise/dashboard.phtml'));
34
+
35
+ $this->_addContent($this->getLayout()->createBlock('core/text', 'inner-wrap-end')->setText('</div>'));
36
+
37
+ $this->renderLayout();
38
+ }
39
+
40
+ public function termsAction()
41
+ {
42
+ // TODO: add wrapper for non-ajax requests - LOW priority
43
+ // return terms text pulled from server
44
+ print $this->getLayout()->createBlock("searchanise/Adminhtml_Index_Terms")->toHtml();
45
+ exit();
46
+ }
47
+ }
app/code/community/Simtech/Searchanise/controllers/InfoController.php ADDED
@@ -0,0 +1,52 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_InfoController extends Mage_Core_Controller_Front_Action
16
+ {
17
+ const OUTPUT = 'visual';
18
+ const PARENT_PRIVATE_KEY = 'parent_private_key';
19
+
20
+ public function indexAction()
21
+ {
22
+ $visual = $this->getRequest()->getParam(self::OUTPUT);
23
+ $parentPrivateKey = $this->getRequest()->getParam(self::PARENT_PRIVATE_KEY);
24
+
25
+ if ((empty($parentPrivateKey)) ||
26
+ (Mage::helper('searchanise/ApiSe')->getParentPrivateKey() !== $parentPrivateKey)) {
27
+ $_options = Mage::helper('searchanise/ApiSe')->getAddonOptions();
28
+ $options = array('status' => $_options['addon_status']);
29
+ foreach ($_options as $k => $v) {
30
+ if (strpos($k, 'api_key') !== false) {
31
+ $options[$k] = $v;
32
+ }
33
+ }
34
+
35
+ if ($visual) {
36
+ Mage::helper('searchanise/ApiSe')->printR($options);
37
+ } else {
38
+ echo Mage::helper('core')->jsonEncode($options);
39
+ }
40
+ } else {
41
+ $options = Mage::helper('searchanise/ApiSe')->getAddonOptions();
42
+
43
+ if ($visual) {
44
+ Mage::helper('searchanise/ApiSe')->printR($options);
45
+ } else {
46
+ echo Mage::helper('core')->jsonEncode($options);
47
+ }
48
+ }
49
+
50
+ die();
51
+ }
52
+ }
app/code/community/Simtech/Searchanise/controllers/OptionsController.php ADDED
@@ -0,0 +1,28 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ class Simtech_Searchanise_OptionsController extends Mage_Adminhtml_Controller_Action
15
+ {
16
+ const PARAM_USE_NAVIGATION = 'snize_use_navigation';
17
+
18
+ /*
19
+ * options
20
+ */
21
+ public function indexAction()
22
+ {
23
+ $useNavigation = $this->getRequest()->getParam(self::PARAM_USE_NAVIGATION);
24
+ Mage::helper('searchanise/ApiSe')->setUseNavigation($useNavigation == 'true' ? true : false);
25
+
26
+ exit;
27
+ }
28
+ }
app/code/community/Simtech/Searchanise/controllers/ProductController.php ADDED
@@ -0,0 +1,40 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ require_once("Mage/Tag/controllers/ProductController.php");
15
+
16
+ class Simtech_Searchanise_ProductController extends Mage_Tag_ProductController
17
+ {
18
+ protected $_defaultToolbarBlock = 'catalog/product_list_toolbar';
19
+ protected $_defaultListBlock = 'catalog/product_list';
20
+
21
+ public function listAction()
22
+ {
23
+ if (!Mage::helper('searchanise/ApiSe')->checkSearchaniseResult(true)) {
24
+ return parent::listAction();
25
+ }
26
+
27
+ $tagId = $this->getRequest()->getParam('tagId');
28
+ $tag = Mage::getModel('tag/tag')->load($tagId);
29
+
30
+ if ($tag->getId() && $tag->isAvailableInStore()) {
31
+ if (Mage::helper('searchanise')->checkEnabled()) {
32
+ $block_toolbar = $this->getLayout()->createBlock($this->_defaultToolbarBlock, microtime());
33
+
34
+ Mage::helper('searchanise')->execute(Simtech_Searchanise_Helper_Data::VIEW_TAG, $this, $block_toolbar, $tag);
35
+ }
36
+ }
37
+
38
+ return parent::listAction();
39
+ }
40
+ }
app/code/community/Simtech/Searchanise/controllers/ResultController.php ADDED
@@ -0,0 +1,45 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ require_once("Mage/CatalogSearch/controllers/ResultController.php");
15
+
16
+ class Simtech_Searchanise_ResultController extends Mage_CatalogSearch_ResultController
17
+ {
18
+ protected $_defaultToolbarBlock = 'catalog/product_list_toolbar';
19
+ protected $_defaultListBlock = 'catalog/product_list';
20
+
21
+ /**
22
+ * Display search result
23
+ */
24
+ public function indexAction()
25
+ {
26
+ if (!Mage::helper('searchanise/ApiSe')->checkSearchaniseResult(true)) {
27
+ return parent::indexAction();
28
+ }
29
+
30
+ $query = Mage::helper('catalogsearch')->getQuery();
31
+ /* @var $query Mage_CatalogSearch_Model_Query */
32
+
33
+ $query->setStoreId(Mage::app()->getStore()->getId());
34
+
35
+ if ($query->getQueryText()) {
36
+ if (Mage::helper('searchanise')->checkEnabled()) {
37
+ $block_toolbar = $this->getLayout()->createBlock($this->_defaultToolbarBlock, microtime());
38
+
39
+ Mage::helper('searchanise')->execute(Simtech_Searchanise_Helper_Data::TEXT_FIND, $this, $block_toolbar, $query);
40
+ }
41
+ }
42
+
43
+ return parent::indexAction();
44
+ }
45
+ }
app/code/community/Simtech/Searchanise/controllers/ResyncController.php ADDED
@@ -0,0 +1,34 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_ResyncController extends Mage_Adminhtml_Controller_Action
16
+ {
17
+ /*
18
+ * resync
19
+ */
20
+ public function indexAction()
21
+ {
22
+ if (Mage::helper('searchanise/ApiSe')->getStatusModule() == 'Y') {
23
+ if (Mage::helper('searchanise/ApiSe')->signup() != true) {
24
+
25
+ $this->_redirect(Mage::helper('searchanise/ApiSe')->getSearchaniseLink());
26
+ }
27
+ Mage::helper('searchanise/ApiSe')->queueImport();
28
+
29
+ $this->_redirect(Mage::helper('searchanise/ApiSe')->getSearchaniseLink());
30
+ }
31
+
32
+ return $this;
33
+ }
34
+ }
app/code/community/Simtech/Searchanise/controllers/SignupController.php ADDED
@@ -0,0 +1,32 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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_SignupController extends Mage_Adminhtml_Controller_Action
16
+ {
17
+ /*
18
+ * Signup
19
+ */
20
+ public function indexAction()
21
+ {
22
+ if (Mage::helper('searchanise/ApiSe')->getStatusModule() == 'Y') {
23
+ if (Mage::helper('searchanise/ApiSe')->signup() == true) {
24
+ Mage::helper('searchanise/ApiSe')->queueImport();
25
+ }
26
+
27
+ $this->_redirect(Mage::helper('searchanise/ApiSe')->getSearchaniseLink());
28
+ }
29
+
30
+ return $this;
31
+ }
32
+ }
app/code/community/Simtech/Searchanise/etc/config.xml ADDED
@@ -0,0 +1,483 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /***************************************************************************
4
+ * *
5
+ * (c) 2004 Vladimir V. Kalynyak, Alexey V. Vinokurov, Ilya M. Shalnev *
6
+ * *
7
+ * This is commercial software, only users who have purchased a valid *
8
+ * license and accept to the terms of the License Agreement can install *
9
+ * and use this program. *
10
+ * *
11
+ ****************************************************************************
12
+ * PLEASE READ THE FULL TEXT OF THE SOFTWARE LICENSE AGREEMENT IN THE *
13
+ * "copyright.txt" FILE PROVIDED WITH THIS DISTRIBUTION PACKAGE. *
14
+ ****************************************************************************/ -->
15
+ <config>
16
+ <modules>
17
+ <Simtech_Searchanise>
18
+ <version>0.1.3</version>
19
+ </Simtech_Searchanise>
20
+ </modules>
21
+ <frontend>
22
+ <routers>
23
+ <!-- OVERRIDE CATALOG CONTOLLERS -->
24
+ <catalog>
25
+ <args>
26
+ <modules>
27
+ <Simtech_Searchanise before="Mage_Catalog">Simtech_Searchanise</Simtech_Searchanise>
28
+ </modules>
29
+ </args>
30
+ </catalog>
31
+ <!-- OVERRIDE CATALOGSEARCH CONTOLLERS -->
32
+ <catalogsearch>
33
+ <args>
34
+ <modules>
35
+ <Simtech_Searchanise before="Mage_CatalogSearch">Simtech_Searchanise</Simtech_Searchanise>
36
+ </modules>
37
+ </args>
38
+ </catalogsearch>
39
+ <!-- OVERRIDE TAG CONTOLLERS -->
40
+ <tag>
41
+ <args>
42
+ <modules>
43
+ <Simtech_Searchanise before="Mage_Tag">Simtech_Searchanise</Simtech_Searchanise>
44
+ </modules>
45
+ </args>
46
+ </tag>
47
+ <!-- END -->
48
+ <searchanise>
49
+ <use>standard</use>
50
+ <args>
51
+ <module>Simtech_Searchanise</module>
52
+ <frontName>searchanise</frontName>
53
+ </args>
54
+ </searchanise>
55
+ </routers>
56
+ <translate>
57
+ <modules>
58
+ <Simtech_Searchanise>
59
+ <files>
60
+ <default>Simtech_Searchanise.csv</default>
61
+ </files>
62
+ </Simtech_Searchanise>
63
+ </modules>
64
+ </translate>
65
+ <layout>
66
+ <updates>
67
+ <searchanise>
68
+ <file>searchanise.xml</file>
69
+ </searchanise>
70
+ </updates>
71
+ </layout>
72
+ </frontend>
73
+ <adminhtml>
74
+ <menu>
75
+ <catalog>
76
+ <children>
77
+ <searchanise module="searchanise">
78
+ <title>Searchanise</title>
79
+ <action>searchanise/index/index</action>
80
+ </searchanise>
81
+ </children>
82
+ </catalog>
83
+ </menu>
84
+ <acl>
85
+ <resources>
86
+ <all>
87
+ <title>Allow Everything</title>
88
+ </all>
89
+ <admin>
90
+ <children>
91
+ <Simtech_Searchanise>
92
+ <title>Searchanise Module</title>
93
+ <sort_order>10</sort_order>
94
+ </Simtech_Searchanise>
95
+ <system>
96
+ <children>
97
+ <config>
98
+ <children>
99
+ <searchanise translate="title" module="searchanise">
100
+ <title>Searchanise Settings</title>
101
+ </searchanise>
102
+ </children>
103
+ </config>
104
+ </children>
105
+ </system>
106
+ </children>
107
+ </admin>
108
+ </resources>
109
+ </acl>
110
+ <translate>
111
+ <modules>
112
+ <Simtech_Searchanise>
113
+ <files>
114
+ <default>Simtech_Searchanise.csv</default>
115
+ </files>
116
+ </Simtech_Searchanise>
117
+ </modules>
118
+ </translate>
119
+ <layout>
120
+ <updates>
121
+ <searchanise>
122
+ <file>searchanise.xml</file>
123
+ </searchanise>
124
+ </updates>
125
+ </layout>
126
+ </adminhtml>
127
+ <global>
128
+ <models>
129
+ <!-- OVERRIDE CATALOG MODEL -->
130
+ <catalog>
131
+ <rewrite>
132
+ <layer>Simtech_Searchanise_Model_Layer</layer>
133
+ <layer_filter_category>Simtech_Searchanise_Model_Layer_Filter_Category</layer_filter_category>
134
+ <layer_filter_price>Simtech_Searchanise_Model_Layer_Filter_Price</layer_filter_price>
135
+ </rewrite>
136
+ </catalog>
137
+ <!-- END -->
138
+ <!-- <OVERRIDE CATALOG RESOURCE> -->
139
+ <catalog_resource>
140
+ <rewrite>
141
+ <product_collection>Simtech_Searchanise_Model_Resource_Product_Collection</product_collection>
142
+ <layer_filter_attribute>Simtech_Searchanise_Model_Resource_Layer_Filter_Attribute</layer_filter_attribute>
143
+ <layer_filter_price>Simtech_Searchanise_Model_Resource_Layer_Filter_Price</layer_filter_price>
144
+ </rewrite>
145
+ </catalog_resource>
146
+ <!-- END -->
147
+ <!-- OVERRIDE CATALOGSEARCH MODEL -->
148
+ <catalogsearch>
149
+ <rewrite>
150
+ <layer>Simtech_Searchanise_Model_LayerCatalogSearch</layer>
151
+ <advanced>Simtech_Searchanise_Model_Advanced</advanced>
152
+ </rewrite>
153
+ </catalogsearch>
154
+ <!-- END -->
155
+ <!-- <OVERRIDE CATALOGSEARCH RESOURCE> -->
156
+ <catalogsearch_resource>
157
+ <rewrite>
158
+ <fulltext>Simtech_Searchanise_Model_Resource_Fulltext</fulltext>
159
+ <fulltext_collection>Simtech_Searchanise_Model_Resource_Fulltext_Collection</fulltext_collection>
160
+ <advanced_collection>Simtech_Searchanise_Model_Resource_Advanced_Collection</advanced_collection>
161
+ </rewrite>
162
+ </catalogsearch_resource>
163
+ <!-- END -->
164
+ <!-- OVERRIDE TAG MODEL -->
165
+ <tag>
166
+ <rewrite>
167
+ <tag_relation>Simtech_Searchanise_Model_Tag_Relation</tag_relation>
168
+ </rewrite>
169
+ </tag>
170
+ <!-- END -->
171
+ <!-- OVERRIDE CATALOGSEARCH MODEL -->
172
+ <tag_resource>
173
+ <rewrite>
174
+ <product_collection>Simtech_Searchanise_Model_Resource_Product_CollectionTag</product_collection>
175
+ </rewrite>
176
+ </tag_resource>
177
+ <!-- END -->
178
+ <!-- OVERRIDE IMPORTEXPORT MODEL -->
179
+ <importexport>
180
+ <rewrite>
181
+ <import_entity_product>Simtech_Searchanise_Model_Import_Entity_Product</import_entity_product>
182
+ </rewrite>
183
+ </importexport>
184
+ <!-- END -->
185
+ <!-- <OVERRIDE CORE RESOURCE> -->
186
+ <core_resource>
187
+ <rewrite>
188
+ <store>Simtech_Searchanise_Model_Resource_Store</store>
189
+ </rewrite>
190
+ </core_resource>
191
+ <!-- END -->
192
+ <!-- OVERRIDE ADMINHTML MODEL -->
193
+ <adminhtml>
194
+ <rewrite>
195
+ <config_data>Simtech_Searchanise_Model_Config_Data</config_data>
196
+ <layer_filter_category>Simtech_Searchanise_Model_Layer_Filter_Category</layer_filter_category>
197
+ </rewrite>
198
+ </adminhtml>
199
+ <!-- END -->
200
+ <searchanise>
201
+ <class>Simtech_Searchanise_Model</class>
202
+ <resourceModel>searchanise_mysql4</resourceModel>
203
+ </searchanise>
204
+ <searchanise_mysql4>
205
+ <class>Simtech_Searchanise_Model_Mysql4</class>
206
+ <entities>
207
+ <queue>
208
+ <table>searchanise_queue</table>
209
+ </queue>
210
+ <config>
211
+ <table>searchanise_config</table>
212
+ </config>
213
+ </entities>
214
+ </searchanise_mysql4>
215
+ </models>
216
+ <resources>
217
+ <searchanise_setup>
218
+ <setup>
219
+ <module>Simtech_Searchanise</module>
220
+ <!--<class>Simtech_Searchanise_Model_Entity_Setup</class>-->
221
+ </setup>
222
+ <connection>
223
+ <use>core_setup</use>
224
+ </connection>
225
+ </searchanise_setup>
226
+ <searchanise_write>
227
+ <connection>
228
+ <use>core_write</use>
229
+ </connection>
230
+ </searchanise_write>
231
+ <searchanise_read>
232
+ <connection>
233
+ <use>core_read</use>
234
+ </connection>
235
+ </searchanise_read>
236
+ </resources>
237
+ <helpers>
238
+ <searchanise>
239
+ <class>Simtech_Searchanise_Helper</class>
240
+ </searchanise>
241
+ </helpers>
242
+ <events>
243
+ <!-- CATALOG -->
244
+ <!-- products -->
245
+ <catalog_product_save_before>
246
+ <observers>
247
+ <rating>
248
+ <class>searchanise/observer</class>
249
+ <method>catalogProductSaveBefore</method>
250
+ </rating>
251
+ </observers>
252
+ </catalog_product_save_before>
253
+ <catalog_product_save_after>
254
+ <observers>
255
+ <rating>
256
+ <class>searchanise/observer</class>
257
+ <method>catalogProductSaveAfter</method>
258
+ </rating>
259
+ </observers>
260
+ </catalog_product_save_after>
261
+ <catalog_product_delete_before>
262
+ <observers>
263
+ <rating>
264
+ <class>searchanise/observer</class>
265
+ <method>catalogProductDeleteBefore</method>
266
+ </rating>
267
+ </observers>
268
+ </catalog_product_delete_before>
269
+ <catalog_product_attribute_update_before>
270
+ <observers>
271
+ <rating>
272
+ <class>searchanise/observer</class>
273
+ <method>catalogProductAttributeUpdateBefore</method>
274
+ </rating>
275
+ </observers>
276
+ </catalog_product_attribute_update_before>
277
+ <catalog_product_website_update_before>
278
+ <observers>
279
+ <rating>
280
+ <class>searchanise/observer</class>
281
+ <method>catalogProductWebsiteUpdateBefore</method>
282
+ </rating>
283
+ </observers>
284
+ </catalog_product_website_update_before>
285
+ <!-- facets-->
286
+ <catalog_entity_attribute_save_before>
287
+ <observers>
288
+ <rating>
289
+ <class>searchanise/observer</class>
290
+ <method>catalogEntityAttributeSaveBefore</method>
291
+ </rating>
292
+ </observers>
293
+ </catalog_entity_attribute_save_before>
294
+ <catalog_entity_attribute_save_after>
295
+ <observers>
296
+ <rating>
297
+ <class>searchanise/observer</class>
298
+ <method>catalogEntityAttributeSaveAfter</method>
299
+ </rating>
300
+ </observers>
301
+ </catalog_entity_attribute_save_after>
302
+ <catalog_entity_attribute_delete_after>
303
+ <observers>
304
+ <rating>
305
+ <class>searchanise/observer</class>
306
+ <method>catalogEntityAttributeDeleteAfter</method>
307
+ </rating>
308
+ </observers>
309
+ </catalog_entity_attribute_delete_after>
310
+ <!-- facet-categories -->
311
+ <catalog_category_save_before>
312
+ <observers>
313
+ <rating>
314
+ <class>searchanise/observer</class>
315
+ <method>catalogCategorySaveBefore</method>
316
+ </rating>
317
+ </observers>
318
+ </catalog_category_save_before>
319
+ <catalog_category_save_after>
320
+ <observers>
321
+ <rating>
322
+ <class>searchanise/observer</class>
323
+ <method>catalogCategorySaveAfter</method>
324
+ </rating>
325
+ </observers>
326
+ </catalog_category_save_after>
327
+ <!-- END CATALOG-->
328
+ <!-- SALES -->
329
+ <!-- products -->
330
+ <sales_order_save_after>
331
+ <observers>
332
+ <rating>
333
+ <class>searchanise/observer</class>
334
+ <method>salesOrderSaveAfter</method>
335
+ </rating>
336
+ </observers>
337
+ </sales_order_save_after>
338
+ <!-- END SALES -->
339
+ <!-- IMPORTEXPORT -->
340
+ <!-- products -->
341
+ <searchanise_import_save_product_entity_after>
342
+ <observers>
343
+ <rating>
344
+ <class>searchanise/observer</class>
345
+ <method>searchaniseImportSaveProductEntityAfter</method>
346
+ </rating>
347
+ </observers>
348
+ </searchanise_import_save_product_entity_after>
349
+ <searchanise_import_delete_product_entity_after>
350
+ <observers>
351
+ <rating>
352
+ <class>searchanise/observer</class>
353
+ <method>searchaniseImportDeleteProductEntityAfter</method>
354
+ </rating>
355
+ </observers>
356
+ </searchanise_import_delete_product_entity_after>
357
+ <!-- END IMPORTEXPORT -->
358
+ <!-- CORE -->
359
+ <!-- store -->
360
+ <searchanise_core_save_store_before>
361
+ <observers>
362
+ <rating>
363
+ <class>searchanise/observer</class>
364
+ <method>searchaniseCoreSaveStoreBefore</method>
365
+ </rating>
366
+ </observers>
367
+ </searchanise_core_save_store_before>
368
+ <searchanise_core_save_store_after>
369
+ <observers>
370
+ <rating>
371
+ <class>searchanise/observer</class>
372
+ <method>searchaniseCoreSaveStoreAfter</method>
373
+ </rating>
374
+ </observers>
375
+ </searchanise_core_save_store_after>
376
+ <searchanise_core_delete_store_after>
377
+ <observers>
378
+ <rating>
379
+ <class>searchanise/observer</class>
380
+ <method>searchaniseCoreDeleteStoreAfter</method>
381
+ </rating>
382
+ </observers>
383
+ </searchanise_core_delete_store_after>
384
+ <!-- ADMINHTML-->
385
+ <searchanise_adminhtml_config_data_save_before>
386
+ <observers>
387
+ <rating>
388
+ <class>searchanise/observer</class>
389
+ <method>searchaniseAdminhtmlConfigDataSaveBefore</method>
390
+ </rating>
391
+ </observers>
392
+ </searchanise_adminhtml_config_data_save_before>
393
+ <searchanise_adminhtml_config_data_save_after>
394
+ <observers>
395
+ <rating>
396
+ <class>searchanise/observer</class>
397
+ <method>searchaniseAdminhtmlConfigDataSaveAfter</method>
398
+ </rating>
399
+ </observers>
400
+ </searchanise_adminhtml_config_data_save_after>
401
+ <!-- END ADMINHTML -->
402
+ <!-- TAG -->
403
+ <!-- tag -->
404
+ <tag_save_after>
405
+ <observers>
406
+ <rating>
407
+ <class>searchanise/observer</class>
408
+ <method>tagSaveAfter</method>
409
+ </rating>
410
+ </observers>
411
+ </tag_save_after>
412
+ <tag_delete_before>
413
+ <observers>
414
+ <rating>
415
+ <class>searchanise/observer</class>
416
+ <method>tagDeleteBefore</method>
417
+ </rating>
418
+ </observers>
419
+ </tag_delete_before>
420
+ <!-- tag_relation -->
421
+ <searchanise_tag_relation_save_after>
422
+ <observers>
423
+ <rating>
424
+ <class>searchanise/observer</class>
425
+ <method>searchaniseTagRelationSaveAfter</method>
426
+ </rating>
427
+ </observers>
428
+ </searchanise_tag_relation_save_after>
429
+ <!-- END TAG -->
430
+ </events>
431
+ <blocks>
432
+ <!-- OVERRIDE BLOCK CATALOG -->
433
+ <catalog>
434
+ <rewrite>
435
+ <product_list_toolbar>Simtech_Searchanise_Block_Product_List_Toolbar</product_list_toolbar>
436
+ </rewrite>
437
+ </catalog>
438
+ <!-- END -->
439
+ <!-- OVERRIDE BLOCK CATALOGSEARCH -->
440
+ <catalogsearch>
441
+ <rewrite>
442
+ <result>Simtech_Searchanise_Block_Result</result>
443
+ </rewrite>
444
+ </catalogsearch>
445
+ <!-- END -->
446
+ <!-- OVERRIDE BLOCK TAG -->
447
+ <tag>
448
+ <rewrite>
449
+ <product_result>Simtech_Searchanise_Block_Product_Result</product_result>
450
+ </rewrite>
451
+ </tag>
452
+ <!-- END -->
453
+ </blocks>
454
+ </global>
455
+ <default>
456
+ <searchanise>
457
+ <config>
458
+ <version>1.2</version>
459
+ <search_timeout>3</search_timeout>
460
+ <request_timeout>15</request_timeout>
461
+ <ajax_async_timeout>1</ajax_async_timeout>
462
+ <products_per_pass>200</products_per_pass>
463
+ <max_error_count>25</max_error_count>
464
+ <max_processing_thread>3</max_processing_thread>
465
+ <max_processing_time>720</max_processing_time>
466
+ <max_search_request_length>8000</max_search_request_length>
467
+ <service_url>http://www.searchanise.com</service_url>
468
+ <cron_enabled>1</cron_enabled>
469
+ <input_id_search>search</input_id_search>
470
+ <type_async>2</type_async>
471
+ </config>
472
+ </searchanise>
473
+ </default>
474
+ <crontab>
475
+ <jobs>
476
+ <cronjob_name>
477
+ <!-- runs every 1 minutes as below. Change to (0 1 * * *) to run every night at 1am -->
478
+ <schedule><cron_expr>*/1 * * * *</cron_expr></schedule>
479
+ <run><model>searchanise/observer::autoSync</model></run>
480
+ </cronjob_name>
481
+ </jobs>
482
+ </crontab>
483
+ </config>
app/code/community/Simtech/Searchanise/etc/system.xml ADDED
@@ -0,0 +1,67 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /***************************************************************************
4
+ * *
5
+ * (c) 2004 Vladimir V. Kalynyak, Alexey V. Vinokurov, Ilya M. Shalnev *
6
+ * *
7
+ * This is commercial software, only users who have purchased a valid *
8
+ * license and accept to the terms of the License Agreement can install *
9
+ * and use this program. *
10
+ * *
11
+ ****************************************************************************
12
+ * PLEASE READ THE FULL TEXT OF THE SOFTWARE LICENSE AGREEMENT IN THE *
13
+ * "copyright.txt" FILE PROVIDED WITH THIS DISTRIBUTION PACKAGE. *
14
+ ****************************************************************************/ -->
15
+ <config>
16
+ <tabs>
17
+ <simtech translate="label" module="searchanise">
18
+ <label>searchanise</label>
19
+ <sort_order>200</sort_order>
20
+ </simtech>
21
+ </tabs>
22
+ <sections>
23
+ <searchanise translate="label" module="searchanise">
24
+ <label>Settings</label>
25
+ <tab>simtech</tab>
26
+ <sort_order>990</sort_order>
27
+ <show_in_default>1</show_in_default>
28
+ <show_in_website>1</show_in_website>
29
+ <show_in_store>1</show_in_store>
30
+ <groups>
31
+ <config translate="label" module="searchanise">
32
+ <label>Configuration Settings</label>
33
+ <frontend_type>text</frontend_type>
34
+ <sort_order>1</sort_order>
35
+ <show_in_default>1</show_in_default>
36
+ <show_in_website>1</show_in_website>
37
+ <show_in_store>1</show_in_store>
38
+ <fields>
39
+ <input_id_search translate="label">
40
+ <label><![CDATA[Search field ID]]></label>
41
+ <comment><![CDATA[ID of the search field in the customer area]]></comment>
42
+ <frontend_type>text</frontend_type>
43
+ <validate></validate>
44
+ <sort_order>1</sort_order>
45
+ <show_in_default>1</show_in_default>
46
+ <show_in_website>1</show_in_website>
47
+ <show_in_store>1</show_in_store>
48
+ </input_id_search>
49
+ <type_async translate="label comment">
50
+ <label><![CDATA[Initialize database synchronization with Cron/AJAX]]></label>
51
+ <comment><![CDATA[<strong>Cron</strong>. If cron service is set up and running, it is recommended to use this option. Database synchronization will be initialized according to the cron schedule.<br>
52
+ <strong>AJAX</strong>. Select this option if you want the database synchronization to be initialized everytime a page is visited in the customer area.
53
+ ]]></comment>
54
+ <frontend_type>select</frontend_type>
55
+ <source_model>searchanise/system_config_source_searchanise_typeAsync</source_model>
56
+ <!-- <source_model>searchanise/system_config_source_searchanise_typeasync</source_model> -->
57
+ <sort_order>6</sort_order>
58
+ <show_in_default>1</show_in_default>
59
+ <show_in_website>0</show_in_website>
60
+ <show_in_store>0</show_in_store>
61
+ </type_async>
62
+ </fields>
63
+ </config>
64
+ </groups>
65
+ </searchanise>
66
+ </sections>
67
+ </config>
app/code/community/Simtech/Searchanise/sql/searchanise_setup/mysql4-install-0.1.0.php ADDED
@@ -0,0 +1,46 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ $installer = $this;
15
+
16
+ $installer->startSetup();
17
+
18
+ $installer->run(
19
+ "
20
+ DROP TABLE IF EXISTS {$this->getTable('searchanise_config')};
21
+ CREATE TABLE IF NOT EXISTS {$this->getTable('searchanise_config')} (
22
+ `config_id` int(10) unsigned NOT NULL AUTO_INCREMENT COMMENT 'Config Id',
23
+ `scope` varchar(8) NOT NULL DEFAULT 'default' COMMENT 'Config Scope',
24
+ `scope_id` int(11) NOT NULL DEFAULT '0' COMMENT 'Config Scope Id',
25
+ `path` varchar(255) NOT NULL DEFAULT 'general' COMMENT 'Config Path',
26
+ `value` text COMMENT 'Config Value',
27
+ PRIMARY KEY (`config_id`),
28
+ UNIQUE KEY `UNQ_CORE_CONFIG_DATA_SCOPE_SCOPE_ID_PATH` (`scope`,`scope_id`,`path`)
29
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8 COMMENT='Config Data' AUTO_INCREMENT=94;
30
+
31
+ DROP TABLE IF EXISTS {$this->getTable('searchanise_queue')};
32
+ CREATE TABLE IF NOT EXISTS {$this->getTable('searchanise_queue')} (
33
+ `queue_id` mediumint(9) NOT NULL AUTO_INCREMENT,
34
+ `data` text NOT NULL,
35
+ `action` varchar(32) NOT NULL DEFAULT '',
36
+ `store_id` smallint(5) unsigned NOT NULL DEFAULT '0' COMMENT 'Store Id',
37
+ `started` int(11) NOT NULL DEFAULT '0',
38
+ `error_count` int(11) NOT NULL DEFAULT '0',
39
+ `status` enum('pending','processing') DEFAULT 'pending',
40
+ PRIMARY KEY (`queue_id`),
41
+ KEY `status` (`status`)
42
+ ) ENGINE=InnoDB DEFAULT CHARSET=utf8;
43
+ "
44
+ );
45
+
46
+ $installer->endSetup();
app/design/adminhtml/default/default/layout/searchanise.xml ADDED
@@ -0,0 +1,21 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /***************************************************************************
4
+ * *
5
+ * (c) 2004 Vladimir V. Kalynyak, Alexey V. Vinokurov, Ilya M. Shalnev *
6
+ * *
7
+ * This is commercial software, only users who have purchased a valid *
8
+ * license and accept to the terms of the License Agreement can install *
9
+ * and use this program. *
10
+ * *
11
+ ****************************************************************************
12
+ * PLEASE READ THE FULL TEXT OF THE SOFTWARE LICENSE AGREEMENT IN THE *
13
+ * "copyright.txt" FILE PROVIDED WITH THIS DISTRIBUTION PACKAGE. *
14
+ ****************************************************************************/-->
15
+ <layout version="0.1.0">
16
+ <default>
17
+ <reference name="before_body_end">
18
+ <block type="Simtech_Searchanise_Block_Async" name="searchanise_async"></block>
19
+ </reference>
20
+ </default>
21
+ </layout>
app/design/adminhtml/default/default/template/searchanise/dashboard.phtml ADDED
@@ -0,0 +1,83 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php /***************************************************************************
2
+ * *
3
+ * (c) 2004 Vladimir V. Kalynyak, Alexey V. Vinokurov, Ilya M. Shalnev *
4
+ * *
5
+ * This is commercial software, only users who have purchased a valid *
6
+ * license and accept to the terms of the License Agreement can install *
7
+ * and use this program. *
8
+ * *
9
+ ****************************************************************************
10
+ * PLEASE READ THE FULL TEXT OF THE SOFTWARE LICENSE AGREEMENT IN THE *
11
+ * "copyright.txt" FILE PROVIDED WITH THIS DISTRIBUTION PACKAGE. *
12
+ ****************************************************************************/ ?>
13
+
14
+ <div class="content-header">
15
+ <table cellspacing="0">
16
+ <tr>
17
+ <td><h3 class="head-dashboard">Searchanise (beta)</h3></td>
18
+ </tr>
19
+ </table>
20
+ </div>
21
+ <div class="snize" id="snize_container"></div>
22
+
23
+ <?php
24
+ Mage::helper('searchanise/ApiSe')->checkImportIsDone();
25
+ $searchanise_options = Mage::helper('searchanise/ApiSe')->getAddonOptions();
26
+
27
+ $searchanise_options['options_link'] = $this->getUrl(Mage::helper('searchanise/ApiSe')->getOptionsLink());
28
+ $searchanise_options['re_sync_link'] = $this->getUrl(Mage::helper('searchanise/ApiSe')->getReSyncLink());
29
+ $searchanise_options['connect_link'] = $this->getUrl(Mage::helper('searchanise/ApiSe')->getConnectLink());
30
+
31
+ $se_service_url = Mage::helper('searchanise/ApiSe')->getServiceUrl(false);
32
+ ?>
33
+
34
+ <script type="text/javascript">
35
+ //<![CDATA[
36
+ SearchaniseAdmin = {};
37
+
38
+ SearchaniseAdmin.host = '<?php echo $se_service_url;?>';
39
+ SearchaniseAdmin.PrivateKey = '<?php echo $searchanise_options['parent_private_key'];?>';
40
+ SearchaniseAdmin.OptionsLink = '<?php echo $searchanise_options['options_link'];?>';
41
+ SearchaniseAdmin.ReSyncLink = '<?php echo $searchanise_options['re_sync_link'];?>';
42
+ SearchaniseAdmin.LastRequest = '<?php echo $searchanise_options['last_request'];?>';
43
+ SearchaniseAdmin.LastResync = '<?php echo $searchanise_options['last_resync'];?>';
44
+ SearchaniseAdmin.ConnectLink = '<?php echo $searchanise_options['connect_link'];?>';
45
+ SearchaniseAdmin.AddonStatus = '<?php echo $searchanise_options['addon_status'];?>';
46
+
47
+ SearchaniseAdmin.Engines = [];
48
+
49
+ <?php
50
+ if(!empty($searchanise_options['parent_private_key'])) {
51
+ $stores = Mage::app()->getStores();
52
+
53
+ if(!empty($stores))
54
+ {
55
+ foreach($stores as $k_store => $store)
56
+ {
57
+ $price_format = Mage::helper('searchanise/ApiSe')->getPriceFormat($store);
58
+ $private_key = $searchanise_options['private_key'][$store->getId()];
59
+ $export_status = empty($searchanise_options['export_status'][$store->getId()]) ? 'none' : $searchanise_options['export_status'][$store->getId()];
60
+ $price_format['after'] = $price_format['after'] ? 'true' : 'false';
61
+
62
+ echo "SearchaniseAdmin.Engines.push({";
63
+ echo "PrivateKey: '{$private_key}',";
64
+ echo "LangCode: '{$store->getCode()}',";
65
+ echo "Name : '{$store->getName()}',";
66
+ echo "ExportStatus: '{$export_status}',";
67
+ echo "PriceFormat: {";
68
+ echo "rate : '{$price_format['rate']}',";
69
+ echo "decimals: '{$price_format['decimals']}',";
70
+ echo "decimals_separator: '{$price_format['decimals_separator']}',";
71
+ echo "thousands_separator: '{$price_format['thousands_separator']}',";
72
+ echo "symbol: '{$price_format['symbol']}',";
73
+ echo "after: {$price_format['after']}";
74
+ echo "}";
75
+ echo "});";
76
+ }
77
+ }
78
+ }
79
+ ?>
80
+ //]]>
81
+ </script>
82
+
83
+ <script type="text/javascript" src="<?php echo $se_service_url;?>/js/init.js"></script>
app/design/frontend/base/default/layout/searchanise.xml ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /***************************************************************************
4
+ * *
5
+ * (c) 2004 Vladimir V. Kalynyak, Alexey V. Vinokurov, Ilya M. Shalnev *
6
+ * *
7
+ * This is commercial software, only users who have purchased a valid *
8
+ * license and accept to the terms of the License Agreement can install *
9
+ * and use this program. *
10
+ * *
11
+ ****************************************************************************
12
+ * PLEASE READ THE FULL TEXT OF THE SOFTWARE LICENSE AGREEMENT IN THE *
13
+ * "copyright.txt" FILE PROVIDED WITH THIS DISTRIBUTION PACKAGE. *
14
+ ****************************************************************************/-->
15
+ <layout version="0.1.0">
16
+ <default>
17
+ <reference name="head">
18
+ <block type="Simtech_Searchanise_Block_Jsinit" name="searchanise_jsinit"></block>
19
+ </reference>
20
+ <reference name="before_body_end">
21
+ <block type="Simtech_Searchanise_Block_Async" name="searchanise_async"></block>
22
+ </reference>
23
+ </default>
24
+ </layout>
app/design/frontend/default/default/template/catalogsearch/form.mini.phtml ADDED
@@ -0,0 +1,33 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
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
+ <form id="search_mini_form" action="<?php echo $this->helper('catalogsearch')->getResultUrl() ?>" method="get">
15
+ <div class="form-search">
16
+ <label for="search"><?php echo $this->__('Search:') ?></label>
17
+ <input id="search" type="text" name="<?php echo $this->helper('catalogsearch')->getQueryParamName() ?>" value="<?php echo $this->helper('catalogsearch')->getEscapedQueryText() ?>" class="input-text" />
18
+ <button type="submit" title="<?php echo $this->__('Search') ?>" class="button"><span><span><?php echo $this->__('Search') ?></span></span></button>
19
+ <div id="search_autocomplete" class="search-autocomplete"></div>
20
+ <?php
21
+ if(Mage::getStoreConfigFlag('advanced/modules_disable_output/Simtech_Searchanise')) {
22
+ ?>
23
+ <script type="text/javascript">
24
+ //<![CDATA[
25
+ var searchForm = new Varien.searchForm('search_mini_form', 'search', '<?php echo $this->__('Search entire store here...') ?>');
26
+ searchForm.initAutocomplete('<?php echo $this->helper('catalogsearch')->getSuggestUrl() ?>', 'search_autocomplete');
27
+ //]]>
28
+ </script>
29
+ <?php
30
+ }
31
+ ?>
32
+ </div>
33
+ </form>
app/etc/modules/Simtech_Searchanise.xml ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <!--
3
+ /***************************************************************************
4
+ * *
5
+ * (c) 2004 Vladimir V. Kalynyak, Alexey V. Vinokurov, Ilya M. Shalnev *
6
+ * *
7
+ * This is commercial software, only users who have purchased a valid *
8
+ * license and accept to the terms of the License Agreement can install *
9
+ * and use this program. *
10
+ * *
11
+ ****************************************************************************
12
+ * PLEASE READ THE FULL TEXT OF THE SOFTWARE LICENSE AGREEMENT IN THE *
13
+ * "copyright.txt" FILE PROVIDED WITH THIS DISTRIBUTION PACKAGE. *
14
+ ****************************************************************************/-->
15
+ <config>
16
+ <modules>
17
+ <Simtech_Searchanise>
18
+ <active>true</active>
19
+ <codePool>community</codePool>
20
+ </Simtech_Searchanise>
21
+ </modules>
22
+ </config>
app/locale/en_US/Simtech_Searchanise.csv ADDED
@@ -0,0 +1,22 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ "Notice", "Notice"
2
+ "Warning", "Warning"
3
+ "Error", "Error"
4
+ "The product catalog is queued for syncing with Searchanise", "The product catalog is queued for syncing with Searchanise"
5
+ "Searchanise: New search engine for [language] created. Catalog import started", "Searchanise: New search engine for [language] created. Catalog import started"
6
+ "Searchanise: Catalog import for [language] started", "Searchanise: Catalog import for [language] started"
7
+ "If you have modified any SEO add-on settings, please <a href="[link]">Resync</a> product catalog with Searchanise to update product URLs.", "If you have modified any SEO add-on settings, please <a href="[link]">Resync</a> product catalog with Searchanise to update product URLs."
8
+ "An error occurred during Searchanise registration. Please try later", "An error occurred during Searchanise registration. Please try later"
9
+ "The product catalog syncing is in progress", "The product catalog syncing is in progress"
10
+ "The product catalog was synced successfully with Searchanise", "The product catalog was synced successfully with Searchanise"
11
+ "The product catalog is not synced with Searchanise yet. Please press "Sync" button to start", "The product catalog is not synced with Searchanise yet. Please press "Sync" button to start"
12
+ "Please note that data on Searchanise is updated with 2-3 minutes delay after you made changed in your store" , "Please note that data on Searchanise is updated with 2-3 minutes delay after you made changed in your store"
13
+ "Click the button below to connect to Searchanise", "Click the button below to connect to Searchanise"
14
+ "Congratulations, you've just connected to Searchanise", "Congratulations, you've just connected to Searchanise"
15
+ "You've connected to Searchanise", "You've connected to Searchanise"
16
+ "text_se_database_restore_notice", "You've just restored your data from the database dump file. If this dump contains products data, please <a href="[link]">Resync</a> them with Searchanise."
17
+ "Relevance", "Relevance"
18
+ "Products", "Products"
19
+ "Popular suggestions", "Popular suggestions"
20
+ "Sort by Relevance", "Sort by Relevance"
21
+ "API key", "API key"
22
+ "Private key", "Private key"
package.xml ADDED
@@ -0,0 +1,24 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?xml version="1.0"?>
2
+ <package>
3
+ <name>Simtech_Searchanise</name>
4
+ <version>1.0.3</version>
5
+ <stability>stable</stability>
6
+ <license uri="https://searchanise.atlassian.net/wiki/display/DD/LICENSE+AGREEMENT">Commercial license: https://searchanise.atlassian.net/wiki/display/DD/LICENSE+AGREEMENT</license>
7
+ <channel>community</channel>
8
+ <extends/>
9
+ <summary>Searchanise Connector Add-on allows you to easily integrate Searchanise rapid search service in your online store. The add-on provides both an admin panel and a customer area widgets.</summary>
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>[+] - AJAX-based synchronization initialization added. &#xD;
14
+ &#xD;
15
+ To change the synchronization initialization mode, go to System &#x2192; Configuration &#x2192; SEARCHANISE &#x2192; Settings. &#xD;
16
+ &#xD;
17
+ Setting the mode to AJAX should fix the issue with the synchronization process not starting.</notes>
18
+ <authors><author><name>Simbirsk Technologies, Ltd.</name><user>searchanise</user><email>sales@searchanise.com</email></author></authors>
19
+ <date>2013-03-05</date>
20
+ <time>08:02:53</time>
21
+ <contents><target name="magecommunity"><dir name="Simtech"><dir name="Searchanise"><dir name="Block"><file name="Async.php" hash="785f322f3558281a67fd7333ee3a2aa3"/><file name="Jsinit.php" hash="7892594f49549708a1ac54665724da26"/><dir name="Product"><dir name="List"><file name="Toolbar.php" hash="31f25d6f1cd0fd2bc674868452f24e8d"/></dir><file name="Result.php" hash="aadf2d90370706221e4ec81e6ca2230c"/></dir><file name="Result.php" hash="b517362678b2d58e0a0a672704f71e45"/></dir><dir name="Helper"><file name="ApiSe.php" hash="6b03725e97adcee10cd2cd25a23b046e"/><file name="ApiXML.php" hash="451af485fd6146c0154560b08aa1af7e"/><file name="Data.php" hash="0cd21dae3ff63fde0cde63c01c574bb0"/></dir><dir name="Model"><file name="Advanced.php" hash="2a22ebcf7ac75b54681ef8a27bad2e47"/><dir name="Config"><file name="Data.php" hash="6480db059eb8793ed852cbdda52104bf"/></dir><file name="Config.php" hash="bdd183c7191e5e1a6cce1136870ed7d8"/><dir name="Import"><dir name="Entity"><file name="Product.php" hash="10b5f619630e8e9dde2712f45dc96720"/></dir></dir><dir name="Layer"><dir name="Filter"><file name="Category.php" hash="46995073e2bee9e495e858c2abc48004"/><file name="Price.php" hash="743887b32bf012274ad8a371fff96411"/></dir></dir><file name="Layer.php" hash="5d0e4758496f418ac966ffddc7d71603"/><file name="LayerCatalogSearch.php" hash="d266fd19bc9ce67eb8d51b316a61e237"/><dir name="Mysql4"><dir name="Config"><file name="Collection.php" hash="bcdbd1b1f4a0d2bbe5274fb24f0e07fc"/></dir><file name="Config.php" hash="c95dc8ecd7ab4f955b6eaf4710ab960e"/><dir name="Queue"><file name="Collection.php" hash="0e4e96d850b2216743ae3b7121982e4f"/></dir><file name="Queue.php" hash="10980e1d42c6ecd7ec75a6c99939aed5"/></dir><file name="Observer.php" hash="d3e280696077f25220afcbcda2f6ee28"/><file name="Queue.php" hash="7087c8b4102bb7754e9c5e038b6c4734"/><file name="Request.php" hash="6a516d0aa27827ee4ed09d9c39afc59b"/><dir name="Resource"><dir name="Advanced"><file name="Collection.php" hash="8030ea455af831f8f2b8ee2082e1e279"/></dir><dir name="Fulltext"><file name="Collection.php" hash="2bf5ed879a58d031e00b151dbc8ce353"/></dir><file name="Fulltext.php" hash="75749316a96873ad93abe7b7a1a80f44"/><dir name="Layer"><dir name="Filter"><file name="Attribute.php" hash="441edc26dabf66ac8c54fec1017deb93"/><file name="Price.php" hash="ec59bb60d37da534f743d611ef29d23a"/></dir></dir><dir name="Product"><file name="Collection.php" hash="3d1c32935293993bae7b7bb3d3cbff0d"/><file name="CollectionTag.php" hash="c5da506f5a9a531db5ae7e86e0dbc4f2"/></dir><file name="Store.php" hash="a4bb5699cf0465527d770ef02b65153a"/></dir><dir name="System"><dir name="Config"><dir name="Source"><dir name="Searchanise"><file name="TypeAsync.php" hash="7fe496fcf3f7a1e8fb7f893c7df5f945"/></dir></dir></dir></dir><dir name="Tag"><file name="Relation.php" hash="b1e21c5ae54edc49733ef79444718ef8"/></dir></dir><dir name="controllers"><file name="AdvancedController.php" hash="b1e8e413e2ef091ba2a38646f4a41024"/><file name="AsyncController.php" hash="366acf6b073f2b6c8a62f40269dda27a"/><file name="CategoryController.php" hash="c0cca2e407b7f7030135e8ca28f72c48"/><file name="IndexController.php" hash="5a4d8fa9b6af7c30341e06908b31d0a0"/><file name="InfoController.php" hash="c5cfcf412c531e46a54815bafe10a62e"/><file name="OptionsController.php" hash="06ba71fb154553587f0232dbc621e0c7"/><file name="ProductController.php" hash="5a415866ea41579cd41e18a5ba6c31e3"/><file name="ResultController.php" hash="c0d16f0b842156452b0ed675cc231d94"/><file name="ResyncController.php" hash="0da7821921414f47e1a93a9add78f99d"/><file name="SignupController.php" hash="d92e9ee17048e6be0ef4eb51872a366e"/></dir><dir name="etc"><file name="config.xml" hash="40045ef6eed2a262fffc959f5a9e76a6"/><file name="system.xml" hash="3e509e7975ba66152706e936d5c6f0cf"/></dir><dir name="sql"><dir name="searchanise_setup"><file name="mysql4-install-0.1.0.php" hash="5501c71c8733da0d89709a5f2f038737"/></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="8353ca387c5f92fee5b04b9317c5545c"/></dir></dir><dir name="layout"><file name="searchanise.xml" hash="f74d4b327ea41e831e55d41436e231bc"/></dir></dir></dir></dir><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="searchanise.xml" hash="81ba53d645c928c56c81a32cb1b02cec"/></dir></dir></dir><dir name="default"><dir name="default"><dir name="template"><dir name="catalogsearch"><file name="form.mini.phtml" hash="079357f1281938a20399ae778ff8279c"/></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="Simtech_Searchanise.xml" hash="e216ff8182b9077b98ef7f80de4a3333"/></dir></target><target name="magelocale"><dir name="en_US"><file name="Simtech_Searchanise.csv" hash="1bdb7fddc596dac1460bc3054c425187"/></dir></target></contents>
22
+ <compatible/>
23
+ <dependencies><required><php><min>5.2.13</min><max>6.0.0</max></php></required></dependencies>
24
+ </package>