Version Notes
Initial Code
Download this release
Release Info
Developer | MineWhat Inc. |
Extension | choiceai |
Version | 1.0.9 |
Comparing to | |
See all releases |
Code changes from version 1.0.8 to 1.0.9
- app/code/community/ChoiceAI/Personalisation/controllers/ApiController.php +220 -16
- app/code/local/ChoiceAI/Search/Block/Catalog/Layer/Filter/Attribute.php +45 -0
- app/code/local/ChoiceAI/Search/Block/Catalog/Layer/Filter/Boolean.php +20 -0
- app/code/local/ChoiceAI/Search/Block/Catalog/Layer/Filter/Category.php +33 -0
- app/code/local/ChoiceAI/Search/Block/Catalog/Layer/Filter/Decimal.php +45 -0
- app/code/local/ChoiceAI/Search/Block/Catalog/Layer/Filter/Price.php +50 -0
- app/code/local/ChoiceAI/Search/Block/Catalog/Layer/View.php +120 -0
- app/code/local/ChoiceAI/Search/Block/Catalog/Product/List.php +52 -0
- app/code/local/ChoiceAI/Search/Block/Catalog/Product/List/Toolbar.php +34 -0
- app/code/local/ChoiceAI/Search/Block/Catalogsearch/Enterprise/Layer.php +115 -0
- app/code/local/ChoiceAI/Search/Block/Catalogsearch/Layer.php +115 -0
- app/code/local/ChoiceAI/Search/Block/Catalogsearch/Layer/Filter/Attribute.php +46 -0
- app/code/local/ChoiceAI/Search/Block/Catalogsearch/Result.php +36 -0
- app/code/local/ChoiceAI/Search/Helper/Catalogsearch.php +19 -0
- app/code/local/ChoiceAI/Search/Helper/Choiceaisearch.php +16 -0
- app/code/local/ChoiceAI/Search/Helper/Data.php +670 -0
- app/code/local/ChoiceAI/Search/Model/Catalog/Category.php +74 -0
- app/code/local/ChoiceAI/Search/Model/Catalog/Config.php +120 -0
- app/code/local/ChoiceAI/Search/Model/Catalog/Layer.php +37 -0
- app/code/local/ChoiceAI/Search/Model/Catalog/Layer/Filter/Attribute.php +168 -0
- app/code/local/ChoiceAI/Search/Model/Catalog/Layer/Filter/Boolean.php +41 -0
- app/code/local/ChoiceAI/Search/Model/Catalog/Layer/Filter/Category.php +132 -0
- app/code/local/ChoiceAI/Search/Model/Catalog/Layer/Filter/Decimal.php +190 -0
- app/code/local/ChoiceAI/Search/Model/Catalog/Layer/Filter/Price.php +154 -0
- app/code/local/ChoiceAI/Search/Model/Catalogsearch/Layer.php +31 -0
- app/code/local/ChoiceAI/Search/Model/Catalogsearch/Layer/Filter/Attribute.php +16 -0
- app/code/local/ChoiceAI/Search/Model/Resource/Catalog/Product/Collection.php +368 -0
- app/code/local/ChoiceAI/Search/Model/Resource/Engine/Abstract.php +453 -0
- app/code/local/ChoiceAI/Search/Model/Resource/Engine/Choiceaisearch.php +242 -0
- app/code/local/ChoiceAI/Search/Model/Resource/Engine/Choiceaisearch/Client.php +29 -0
- app/code/local/ChoiceAI/Search/etc/config.xml +101 -0
- app/code/local/ChoiceAI/Searchcore/Helper/Confighelper.php +472 -0
- app/code/local/ChoiceAI/Searchcore/Helper/Constants.php +195 -0
- app/code/local/ChoiceAI/Searchcore/Helper/Data.php +233 -0
- app/code/local/ChoiceAI/Searchcore/Helper/Feedhelper.php +288 -0
- app/code/local/ChoiceAI/Searchcore/Model/Api/Request.php +212 -0
- app/code/local/ChoiceAI/Searchcore/Model/Api/Response.php +165 -0
- app/code/local/ChoiceAI/Searchcore/Model/Api/Task.php +84 -0
- app/code/local/ChoiceAI/Searchcore/Model/Api/Task/Analyticsimpression.php +49 -0
- app/code/local/ChoiceAI/Searchcore/Model/Api/Task/Autosuggestindex.php +52 -0
- app/code/local/ChoiceAI/Searchcore/Model/Api/Task/Feeddetails.php +71 -0
- app/code/local/ChoiceAI/Searchcore/Model/Api/Task/Searchimpression.php +57 -0
- app/code/local/ChoiceAI/Searchcore/Model/Api/Task/Searchsetup.php +52 -0
- app/code/local/ChoiceAI/Searchcore/Model/Api/Task/Supportmail.php +48 -0
- app/code/local/ChoiceAI/Searchcore/Model/Api/Task/Trackcart.php +46 -0
- app/code/local/ChoiceAI/Searchcore/Model/Api/Task/Trackorder.php +46 -0
- app/code/local/ChoiceAI/Searchcore/Model/Api/Task/Triggerfeedupload.php +42 -0
- app/code/local/ChoiceAI/Searchcore/Model/Api/Task/Updatefeaturefields.php +83 -0
- app/code/local/ChoiceAI/Searchcore/Model/Api/Task/Validatekeys.php +73 -0
- app/code/local/ChoiceAI/Searchcore/Model/Config.php +47 -0
- app/code/local/ChoiceAI/Searchcore/Model/Field.php +342 -0
- app/code/local/ChoiceAI/Searchcore/Model/Observer.php +201 -0
- app/code/local/ChoiceAI/Searchcore/Model/Resource/Attribute.php +27 -0
- app/code/local/ChoiceAI/Searchcore/Model/Resource/Config.php +213 -0
- app/code/local/ChoiceAI/Searchcore/Model/Resource/Config/Collection.php +21 -0
- app/code/local/ChoiceAI/Searchcore/Model/Resource/Field.php +146 -0
- app/code/local/ChoiceAI/Searchcore/Model/Resource/Field/Collection.php +66 -0
- app/code/local/ChoiceAI/Searchcore/Model/Resource/Product/Collection.php +110 -0
- app/code/local/ChoiceAI/Searchcore/etc/config.xml +133 -0
- app/code/local/ChoiceAI/Searchcore/sql/choiceai_searchcore_setup/mysql4-install-1.0.0.php +91 -0
- app/code/local/ChoiceAI/Searchcore/sql/choiceai_searchcore_setup/upgrade-1.0.21-1.0.22.php +46 -0
- app/design/frontend/base/default/template/choiceai/personalisation/base/script.phtml +1 -0
- app/design/frontend/base/default/template/choiceai/personalisation/event/checkout/onepage/success.phtml +0 -21
- app/design/frontend/default/default/template/choiceai/personalisation/base/script.phtml +5 -0
- app/design/frontend/default/default/template/choiceai/personalisation/event/catalog/product/view.phtml +0 -61
- app/design/frontend/default/default/template/choiceai/personalisation/event/checkout/cart/index.phtml +0 -17
- app/design/frontend/default/default/template/choiceai/personalisation/event/checkout/onepage/success.phtml +0 -20
- app/etc/modules/ChoiceAI_Personalisation.xml +8 -0
- lib/ChoiceAI/Client.php +304 -0
- lib/ChoiceAI/Response.php +45 -0
- lib/ChoiceAI/Result.php +65 -0
- lib/ChoiceAI/ResultSet.php +229 -0
- lib/ChoiceAI/Service.php +190 -0
- lib/ChoiceAI/test.php +53 -0
- package.xml +5 -5
app/code/community/ChoiceAI/Personalisation/controllers/ApiController.php
CHANGED
@@ -10,6 +10,8 @@
|
|
10 |
class ChoiceAI_Personalisation_ApiController extends Mage_Core_Controller_Front_Action {
|
11 |
|
12 |
const CONFIG_API_KEY = 'choiceai_personalisation/settings/api_key';
|
|
|
|
|
13 |
|
14 |
public function _authorise() {
|
15 |
|
@@ -19,7 +21,7 @@ class ChoiceAI_Personalisation_ApiController extends Mage_Core_Controller_Front_
|
|
19 |
if(!$API_KEY && strlen($API_KEY) === 0) {
|
20 |
// Api access disabled
|
21 |
$this->getResponse()
|
22 |
-
->setBody(json_encode(array('status' => 'error', 'message' => 'API access disabled', 'version' =>
|
23 |
->setHttpResponseCode(403)
|
24 |
->setHeader('Content-type', 'application/json', true);
|
25 |
return false;
|
@@ -36,7 +38,7 @@ class ChoiceAI_Personalisation_ApiController extends Mage_Core_Controller_Front_
|
|
36 |
Mage::log('Unable to extract authorization header from request', null, 'choiceai.log');
|
37 |
// Internal server error
|
38 |
$this->getResponse()
|
39 |
-
->setBody(json_encode(array('status' => 'error', 'message' => 'Internal server error, Authorization header not found', 'version' =>
|
40 |
->setHttpResponseCode(500)
|
41 |
->setHeader('Content-type', 'application/json', true);
|
42 |
return false;
|
@@ -45,7 +47,7 @@ class ChoiceAI_Personalisation_ApiController extends Mage_Core_Controller_Front_
|
|
45 |
if(trim($authHeader) !== trim($API_KEY)) {
|
46 |
// Api access denied
|
47 |
$this->getResponse()
|
48 |
-
->setBody(json_encode(array('status' => 'error', 'message' => 'Api access denied', 'version' =>
|
49 |
->setHttpResponseCode(401)
|
50 |
->setHeader('Content-type', 'application/json', true);
|
51 |
return false;
|
@@ -55,6 +57,56 @@ class ChoiceAI_Personalisation_ApiController extends Mage_Core_Controller_Front_
|
|
55 |
|
56 |
}
|
57 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
58 |
public function ordersAction() {
|
59 |
|
60 |
try {
|
@@ -109,7 +161,7 @@ class ChoiceAI_Personalisation_ApiController extends Mage_Core_Controller_Front_
|
|
109 |
}
|
110 |
}
|
111 |
|
112 |
-
$responseObj['version'] =
|
113 |
$this->getResponse()
|
114 |
->setBody(json_encode($responseObj))
|
115 |
->setHttpResponseCode(200)
|
@@ -141,7 +193,7 @@ class ChoiceAI_Personalisation_ApiController extends Mage_Core_Controller_Front_
|
|
141 |
}
|
142 |
|
143 |
$this->getResponse()
|
144 |
-
->setBody(json_encode(array('orders' => $orders, 'fromDate' => $fromDate, 'toDate' => $toDate, 'version' =>
|
145 |
->setHttpResponseCode(200)
|
146 |
->setHeader('Content-type', 'application/json', true);
|
147 |
|
@@ -149,7 +201,7 @@ class ChoiceAI_Personalisation_ApiController extends Mage_Core_Controller_Front_
|
|
149 |
|
150 |
} catch(Exception $e) {
|
151 |
$this->getResponse()
|
152 |
-
->setBody(json_encode(array('status' => 'error', 'message' => 'Internal server error', 'version' =>
|
153 |
->setHttpResponseCode(500)
|
154 |
->setHeader('Content-type', 'application/json', true);
|
155 |
}
|
@@ -158,6 +210,106 @@ class ChoiceAI_Personalisation_ApiController extends Mage_Core_Controller_Front_
|
|
158 |
|
159 |
}
|
160 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
161 |
public function productsAction() {
|
162 |
|
163 |
try {
|
@@ -225,14 +377,14 @@ class ChoiceAI_Personalisation_ApiController extends Mage_Core_Controller_Front_
|
|
225 |
$currency = Mage::app()->getStore()->getCurrentCurrencyCode();
|
226 |
|
227 |
$this->getResponse()
|
228 |
-
->setBody(json_encode(array('products' => $products, 'currency' => $currency, 'version' =>
|
229 |
->setHttpResponseCode(200)
|
230 |
->setHeader('Content-type', 'application/json', true);
|
231 |
|
232 |
|
233 |
} catch(Exception $e) {
|
234 |
$this->getResponse()
|
235 |
-
->setBody(json_encode(array('status' => 'error', 'message' => 'Internal server error', 'version' =>
|
236 |
->setHttpResponseCode(500)
|
237 |
->setHeader('Content-type', 'application/json', true);
|
238 |
}
|
@@ -318,14 +470,14 @@ class ChoiceAI_Personalisation_ApiController extends Mage_Core_Controller_Front_
|
|
318 |
}
|
319 |
|
320 |
$this->getResponse()
|
321 |
-
->setBody(json_encode(array('categories' => $categories, 'version' =>
|
322 |
->setHttpResponseCode(200)
|
323 |
->setHeader('Content-type', 'application/json', true);
|
324 |
|
325 |
|
326 |
} catch(Exception $e) {
|
327 |
$this->getResponse()
|
328 |
-
->setBody(json_encode(array('status' => 'error', 'message' => 'Internal server error', 'version' =>
|
329 |
->setHttpResponseCode(500)
|
330 |
->setHeader('Content-type', 'application/json', true);
|
331 |
}
|
@@ -398,13 +550,13 @@ class ChoiceAI_Personalisation_ApiController extends Mage_Core_Controller_Front_
|
|
398 |
|
399 |
|
400 |
$this->getResponse()
|
401 |
-
->setBody(json_encode(array('users' => $users, 'version' =>
|
402 |
->setHttpResponseCode(200)
|
403 |
->setHeader('Content-type', 'application/json', true);
|
404 |
|
405 |
} catch(Exception $e) {
|
406 |
$this->getResponse()
|
407 |
-
->setBody(json_encode(array('status' => 'error', 'message' => 'Internal server error', 'version' =>
|
408 |
->setHttpResponseCode(500)
|
409 |
->setHeader('Content-type', 'application/json', true);
|
410 |
}
|
@@ -429,7 +581,7 @@ class ChoiceAI_Personalisation_ApiController extends Mage_Core_Controller_Front_
|
|
429 |
if(!$productId || strlen($productId) <= 0) {
|
430 |
|
431 |
$this->getResponse()
|
432 |
-
->setBody(json_encode(array('status' => 'error', 'message' => 'product id required', 'version' =>
|
433 |
->setHttpResponseCode(500)
|
434 |
->setHeader('Content-type', 'application/json', true);
|
435 |
|
@@ -440,7 +592,7 @@ class ChoiceAI_Personalisation_ApiController extends Mage_Core_Controller_Front_
|
|
440 |
$product = Mage::getModel('catalog/product')->loadByAttribute('sku', $productId);
|
441 |
if($product == null) {
|
442 |
$this->getResponse()
|
443 |
-
->setBody(json_encode(array('status' => 'error', 'message' => 'invalid sku', 'version' =>
|
444 |
->setHttpResponseCode(500)
|
445 |
->setHeader('Content-type', 'application/json', true);
|
446 |
return $this;
|
@@ -454,7 +606,7 @@ class ChoiceAI_Personalisation_ApiController extends Mage_Core_Controller_Front_
|
|
454 |
$stock = $stockObj->getQty();
|
455 |
|
456 |
$this->getResponse()
|
457 |
-
->setBody(json_encode(array('id' => $productId, 'stock' => $stock, 'version' =>
|
458 |
->setHttpResponseCode(200)
|
459 |
->setHeader('Content-type', 'application/json', true);
|
460 |
|
@@ -462,7 +614,7 @@ class ChoiceAI_Personalisation_ApiController extends Mage_Core_Controller_Front_
|
|
462 |
|
463 |
} catch(Exception $e) {
|
464 |
$this->getResponse()
|
465 |
-
->setBody(json_encode(array('status' => 'error', 'message' => 'Internal server error', 'version' =>
|
466 |
->setHttpResponseCode(500)
|
467 |
->setHeader('Content-type', 'application/json', true);
|
468 |
}
|
@@ -563,4 +715,56 @@ class ChoiceAI_Personalisation_ApiController extends Mage_Core_Controller_Front_
|
|
563 |
|
564 |
}
|
565 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
566 |
}
|
10 |
class ChoiceAI_Personalisation_ApiController extends Mage_Core_Controller_Front_Action {
|
11 |
|
12 |
const CONFIG_API_KEY = 'choiceai_personalisation/settings/api_key';
|
13 |
+
const CONFIG_KEY = 'choiceai_personalisation/settings/config';
|
14 |
+
const API_VERSION = 3;
|
15 |
|
16 |
public function _authorise() {
|
17 |
|
21 |
if(!$API_KEY && strlen($API_KEY) === 0) {
|
22 |
// Api access disabled
|
23 |
$this->getResponse()
|
24 |
+
->setBody(json_encode(array('status' => 'error', 'message' => 'API access disabled', 'version' => self::API_VERSION)))
|
25 |
->setHttpResponseCode(403)
|
26 |
->setHeader('Content-type', 'application/json', true);
|
27 |
return false;
|
38 |
Mage::log('Unable to extract authorization header from request', null, 'choiceai.log');
|
39 |
// Internal server error
|
40 |
$this->getResponse()
|
41 |
+
->setBody(json_encode(array('status' => 'error', 'message' => 'Internal server error, Authorization header not found', 'version' => self::API_VERSION)))
|
42 |
->setHttpResponseCode(500)
|
43 |
->setHeader('Content-type', 'application/json', true);
|
44 |
return false;
|
47 |
if(trim($authHeader) !== trim($API_KEY)) {
|
48 |
// Api access denied
|
49 |
$this->getResponse()
|
50 |
+
->setBody(json_encode(array('status' => 'error', 'message' => 'Api access denied', 'version' => self::API_VERSION)))
|
51 |
->setHttpResponseCode(401)
|
52 |
->setHeader('Content-type', 'application/json', true);
|
53 |
return false;
|
57 |
|
58 |
}
|
59 |
|
60 |
+
public function configAction() {
|
61 |
+
|
62 |
+
try {
|
63 |
+
|
64 |
+
if(!$this->_authorise()) {
|
65 |
+
return $this;
|
66 |
+
}
|
67 |
+
|
68 |
+
$responseObj = array();
|
69 |
+
|
70 |
+
if ($_SERVER["REQUEST_METHOD"] == "GET") {
|
71 |
+
$STORE_CONFIG = Mage::getStoreConfig(self::CONFIG_KEY);
|
72 |
+
$responseObj["status"] = "ok";
|
73 |
+
$responseObj["config"] = json_decode($STORE_CONFIG);
|
74 |
+
} else if ($_SERVER["REQUEST_METHOD"] == "PUT") {
|
75 |
+
$store_config = $this->getRequest()->getParam('config');
|
76 |
+
if($store_config ==""){
|
77 |
+
$input = file_get_contents('php://input');
|
78 |
+
$input = utf8_encode($input);
|
79 |
+
$store_config = json_encode(json_decode($input)->config);
|
80 |
+
}
|
81 |
+
$store_config_json = json_decode($store_config);
|
82 |
+
if ($store_config_json == NULL) {
|
83 |
+
throw new Exception();
|
84 |
+
}
|
85 |
+
Mage::getModel('core/config')->saveConfig(self::CONFIG_KEY, $store_config);
|
86 |
+
Mage::app()->getStore()->resetConfig();
|
87 |
+
$responseObj["status"] = "ok";
|
88 |
+
} else {
|
89 |
+
$responseObj['status'] = 'error';
|
90 |
+
$responseObj['message'] = 'Invalid request';
|
91 |
+
}
|
92 |
+
|
93 |
+
$responseObj['version'] = self::API_VERSION;
|
94 |
+
$this->getResponse()
|
95 |
+
->setBody(json_encode($responseObj))
|
96 |
+
->setHttpResponseCode(200)
|
97 |
+
->setHeader('Content-type', 'application/json', true);
|
98 |
+
|
99 |
+
} catch(Exception $e) {
|
100 |
+
$this->getResponse()
|
101 |
+
->setBody(json_encode(array('status' => 'error', 'message' => 'Internal server error', 'version' => self::API_VERSION)))
|
102 |
+
->setHttpResponseCode(500)
|
103 |
+
->setHeader('Content-type', 'application/json', true);
|
104 |
+
}
|
105 |
+
|
106 |
+
return this;
|
107 |
+
|
108 |
+
}
|
109 |
+
|
110 |
public function ordersAction() {
|
111 |
|
112 |
try {
|
161 |
}
|
162 |
}
|
163 |
|
164 |
+
$responseObj['version'] = self::API_VERSION;
|
165 |
$this->getResponse()
|
166 |
->setBody(json_encode($responseObj))
|
167 |
->setHttpResponseCode(200)
|
193 |
}
|
194 |
|
195 |
$this->getResponse()
|
196 |
+
->setBody(json_encode(array('orders' => $orders, 'fromDate' => $fromDate, 'toDate' => $toDate, 'version' => self::API_VERSION)))
|
197 |
->setHttpResponseCode(200)
|
198 |
->setHeader('Content-type', 'application/json', true);
|
199 |
|
201 |
|
202 |
} catch(Exception $e) {
|
203 |
$this->getResponse()
|
204 |
+
->setBody(json_encode(array('status' => 'error', 'message' => 'Internal server error', 'version' => self::API_VERSION)))
|
205 |
->setHttpResponseCode(500)
|
206 |
->setHeader('Content-type', 'application/json', true);
|
207 |
}
|
210 |
|
211 |
}
|
212 |
|
213 |
+
public function productattributesAction() {
|
214 |
+
|
215 |
+
try {
|
216 |
+
|
217 |
+
if(!$this->_authorise()) {
|
218 |
+
return $this;
|
219 |
+
}
|
220 |
+
|
221 |
+
$sections = explode('/', trim($this->getRequest()->getPathInfo(), '/'));
|
222 |
+
|
223 |
+
if(!isset($sections[3])) {
|
224 |
+
|
225 |
+
throw new Exception();
|
226 |
+
|
227 |
+
}
|
228 |
+
|
229 |
+
$productId = $sections[3];
|
230 |
+
|
231 |
+
$product = Mage::getModel('catalog/product')->load($productId);
|
232 |
+
|
233 |
+
$product_info = array();
|
234 |
+
|
235 |
+
$product_info["is_available"] = $product->isAvailable();
|
236 |
+
$product_info["name"] = $product->getName();
|
237 |
+
$product_info["id"] = $product->getId();
|
238 |
+
$product_info["sku"] = $product->getSku();
|
239 |
+
$product_info["price"] = $product->getPrice();
|
240 |
+
$product_info["final_price"] = $product->getFinalPrice();
|
241 |
+
$product_info["special_price"] = $product->getSpecialPrice();
|
242 |
+
$product_info["type"] = $product->getTypeId();
|
243 |
+
|
244 |
+
$variants = array();
|
245 |
+
$options = array();
|
246 |
+
|
247 |
+
if ($product->getTypeId() == "configurable") {
|
248 |
+
|
249 |
+
$productAttributeOptions = $product->getTypeInstance(true)->getConfigurableAttributesAsArray($product);
|
250 |
+
$attributeTypes = array();
|
251 |
+
|
252 |
+
foreach ($productAttributeOptions as $productAttribute) {
|
253 |
+
|
254 |
+
$attributes = array();
|
255 |
+
foreach ($productAttribute['values'] as $attribute) {
|
256 |
+
$attributes[] = array(
|
257 |
+
"id" => $attribute["value_index"],
|
258 |
+
"name" => $attribute["store_label"]
|
259 |
+
);
|
260 |
+
}
|
261 |
+
|
262 |
+
$attributeType = $productAttribute["attribute_code"];
|
263 |
+
$options[] = array(
|
264 |
+
"id" => $productAttribute["id"],
|
265 |
+
"key" => $attributeType,
|
266 |
+
"name" => $productAttribute["store_label"],
|
267 |
+
"values" => $attributes,
|
268 |
+
"position" => $productAttribute["position"]
|
269 |
+
);
|
270 |
+
|
271 |
+
$attributeTypes[] = $attributeType;
|
272 |
+
|
273 |
+
}
|
274 |
+
|
275 |
+
$associatedProducts = $product->getTypeInstance()->getUsedProducts();
|
276 |
+
foreach ($associatedProducts as $associatedProduct) {
|
277 |
+
|
278 |
+
$variant = array();
|
279 |
+
$variant["is_available"] = $associatedProduct->isAvailable();
|
280 |
+
$variant["id"] = $associatedProduct->getId();
|
281 |
+
$variant["sku"] = $associatedProduct->getSku();
|
282 |
+
$variant["price"] = $associatedProduct->getPrice();
|
283 |
+
$variant["final_price"] = $associatedProduct->getFinalPrice();
|
284 |
+
$variant["special_price"] = $associatedProduct->getSpecialPrice();
|
285 |
+
|
286 |
+
$associatedProductData = $associatedProduct->getData();
|
287 |
+
foreach ($attributeTypes as $attributeType) {
|
288 |
+
$variant[$attributeType] = $associatedProductData[$attributeType];
|
289 |
+
}
|
290 |
+
|
291 |
+
$variants[] = $variant;
|
292 |
+
|
293 |
+
}
|
294 |
+
|
295 |
+
}
|
296 |
+
|
297 |
+
$this->getResponse()
|
298 |
+
->setBody(json_encode(array('product' => $product_info, 'variants' => $variants, 'options' => $options, 'version' => self::API_VERSION)))
|
299 |
+
->setHttpResponseCode(200)
|
300 |
+
->setHeader('Content-type', 'application/json', true);
|
301 |
+
|
302 |
+
} catch(Exception $e) {
|
303 |
+
$this->getResponse()
|
304 |
+
->setBody(json_encode(array('status' => 'error', 'message' => 'Internal server error', 'version' => self::API_VERSION)))
|
305 |
+
->setHttpResponseCode(500)
|
306 |
+
->setHeader('Content-type', 'application/json', true);
|
307 |
+
}
|
308 |
+
|
309 |
+
return $this;
|
310 |
+
|
311 |
+
}
|
312 |
+
|
313 |
public function productsAction() {
|
314 |
|
315 |
try {
|
377 |
$currency = Mage::app()->getStore()->getCurrentCurrencyCode();
|
378 |
|
379 |
$this->getResponse()
|
380 |
+
->setBody(json_encode(array('products' => $products, 'currency' => $currency, 'version' => self::API_VERSION)))
|
381 |
->setHttpResponseCode(200)
|
382 |
->setHeader('Content-type', 'application/json', true);
|
383 |
|
384 |
|
385 |
} catch(Exception $e) {
|
386 |
$this->getResponse()
|
387 |
+
->setBody(json_encode(array('status' => 'error', 'message' => 'Internal server error', 'version' => self::API_VERSION)))
|
388 |
->setHttpResponseCode(500)
|
389 |
->setHeader('Content-type', 'application/json', true);
|
390 |
}
|
470 |
}
|
471 |
|
472 |
$this->getResponse()
|
473 |
+
->setBody(json_encode(array('categories' => $categories, 'version' => self::API_VERSION)))
|
474 |
->setHttpResponseCode(200)
|
475 |
->setHeader('Content-type', 'application/json', true);
|
476 |
|
477 |
|
478 |
} catch(Exception $e) {
|
479 |
$this->getResponse()
|
480 |
+
->setBody(json_encode(array('status' => 'error', 'message' => 'Internal server error', 'version' => self::API_VERSION)))
|
481 |
->setHttpResponseCode(500)
|
482 |
->setHeader('Content-type', 'application/json', true);
|
483 |
}
|
550 |
|
551 |
|
552 |
$this->getResponse()
|
553 |
+
->setBody(json_encode(array('users' => $users, 'version' => self::API_VERSION)))
|
554 |
->setHttpResponseCode(200)
|
555 |
->setHeader('Content-type', 'application/json', true);
|
556 |
|
557 |
} catch(Exception $e) {
|
558 |
$this->getResponse()
|
559 |
+
->setBody(json_encode(array('status' => 'error', 'message' => 'Internal server error', 'version' => self::API_VERSION)))
|
560 |
->setHttpResponseCode(500)
|
561 |
->setHeader('Content-type', 'application/json', true);
|
562 |
}
|
581 |
if(!$productId || strlen($productId) <= 0) {
|
582 |
|
583 |
$this->getResponse()
|
584 |
+
->setBody(json_encode(array('status' => 'error', 'message' => 'product id required', 'version' => self::API_VERSION)))
|
585 |
->setHttpResponseCode(500)
|
586 |
->setHeader('Content-type', 'application/json', true);
|
587 |
|
592 |
$product = Mage::getModel('catalog/product')->loadByAttribute('sku', $productId);
|
593 |
if($product == null) {
|
594 |
$this->getResponse()
|
595 |
+
->setBody(json_encode(array('status' => 'error', 'message' => 'invalid sku', 'version' => self::API_VERSION)))
|
596 |
->setHttpResponseCode(500)
|
597 |
->setHeader('Content-type', 'application/json', true);
|
598 |
return $this;
|
606 |
$stock = $stockObj->getQty();
|
607 |
|
608 |
$this->getResponse()
|
609 |
+
->setBody(json_encode(array('id' => $productId, 'stock' => $stock, 'version' => self::API_VERSION)))
|
610 |
->setHttpResponseCode(200)
|
611 |
->setHeader('Content-type', 'application/json', true);
|
612 |
|
614 |
|
615 |
} catch(Exception $e) {
|
616 |
$this->getResponse()
|
617 |
+
->setBody(json_encode(array('status' => 'error', 'message' => 'Internal server error', 'version' => self::API_VERSION)))
|
618 |
->setHttpResponseCode(500)
|
619 |
->setHeader('Content-type', 'application/json', true);
|
620 |
}
|
715 |
|
716 |
}
|
717 |
|
718 |
+
public function sortbyAction() {
|
719 |
+
|
720 |
+
try {
|
721 |
+
|
722 |
+
if(!$this->_authorise()) {
|
723 |
+
return $this;
|
724 |
+
}
|
725 |
+
|
726 |
+
$sortByOptions = array();
|
727 |
+
// $attributesData = Mage::getResourceModel('catalog/config')->getAttributesUsedForSortBy();
|
728 |
+
|
729 |
+
// foreach ($attributesData as $attributeData) {
|
730 |
+
// $sortByOptions[$attributeData['attribute_code']] = array(
|
731 |
+
// "attribute_id"=> $attributeData['attribute_id'],
|
732 |
+
// "attribute_code"=> $attributeData['attribute_code'],
|
733 |
+
// "frontend_label"=> $attributeData['frontend_label'],
|
734 |
+
// "store_label"=> $attributeData['store_label']
|
735 |
+
// );
|
736 |
+
// }
|
737 |
+
|
738 |
+
$category = Mage::getModel('catalog/category');
|
739 |
+
|
740 |
+
$attributesData = $category->getAvailableSortByOptions();
|
741 |
+
$defaultSort = $category->getDefaultSortBy();
|
742 |
+
|
743 |
+
$i = 1;
|
744 |
+
|
745 |
+
foreach ($attributesData as $key => $attributeData) {
|
746 |
+
$sortByOptions[] = array(
|
747 |
+
"_id"=> $key,
|
748 |
+
"name"=> $attributeData,
|
749 |
+
"default"=> $key==$defaultSort ? true:false,
|
750 |
+
"order"=> $i
|
751 |
+
);
|
752 |
+
$i++;
|
753 |
+
}
|
754 |
+
|
755 |
+
$this->getResponse()
|
756 |
+
->setBody(json_encode(array('status' => "ok", 'options' => $sortByOptions, 'version' => self::API_VERSION)))
|
757 |
+
->setHttpResponseCode(200)
|
758 |
+
->setHeader('Content-type', 'application/json', true);
|
759 |
+
|
760 |
+
} catch(Exception $e) {
|
761 |
+
$this->getResponse()
|
762 |
+
->setBody(json_encode(array('status' => 'error', 'message' => 'Internal server error', 'version' => self::API_VERSION)))
|
763 |
+
->setHttpResponseCode(500)
|
764 |
+
->setHeader('Content-type', 'application/json', true);
|
765 |
+
}
|
766 |
+
|
767 |
+
return $this;
|
768 |
+
}
|
769 |
+
|
770 |
}
|
app/code/local/ChoiceAI/Search/Block/Catalog/Layer/Filter/Attribute.php
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
*
|
4 |
+
* @package ChoiceAI_Search
|
5 |
+
* @copyright Copyright (c) MineWhat
|
6 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
7 |
+
*/
|
8 |
+
class ChoiceAI_Search_Block_Catalog_Layer_Filter_Attribute extends Mage_Catalog_Block_Layer_Filter_Abstract
|
9 |
+
{
|
10 |
+
/**
|
11 |
+
* Defines specific filter model name.
|
12 |
+
*
|
13 |
+
* @see ChoiceAI_Search_Model_Catalog_Layer_Filter_Attribute
|
14 |
+
*/
|
15 |
+
public function __construct()
|
16 |
+
{
|
17 |
+
parent::__construct();
|
18 |
+
$this->_filterModelName = 'choiceai_search/catalog_layer_filter_attribute';
|
19 |
+
}
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Prepares filter model.
|
23 |
+
*
|
24 |
+
* @return ChoiceAI_Search_Block_Catalog_Layer_Filter_Attribute
|
25 |
+
*/
|
26 |
+
protected function _prepareFilter()
|
27 |
+
{
|
28 |
+
$this->_filter->setAttributeModel($this->getAttributeModel());
|
29 |
+
|
30 |
+
return $this;
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Adds facet condition to filter.
|
35 |
+
*
|
36 |
+
* @see ChoiceAI_Search_Model_Catalog_Layer_Filter_Attribute::addFacetCondition()
|
37 |
+
* @return ChoiceAI_Search_Block_Catalog_Layer_Filter_Attribute
|
38 |
+
*/
|
39 |
+
public function addFacetCondition()
|
40 |
+
{
|
41 |
+
$this->_filter->addFacetCondition();
|
42 |
+
|
43 |
+
return $this;
|
44 |
+
}
|
45 |
+
}
|
app/code/local/ChoiceAI/Search/Block/Catalog/Layer/Filter/Boolean.php
ADDED
@@ -0,0 +1,20 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
*
|
4 |
+
* @package ChoiceAI_Search
|
5 |
+
* @copyright Copyright (c) MineWhat
|
6 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
7 |
+
*/
|
8 |
+
class ChoiceAI_Search_Block_Catalog_Layer_Filter_Boolean extends ChoiceAI_Search_Block_Catalog_Layer_Filter_Attribute
|
9 |
+
{
|
10 |
+
/**
|
11 |
+
* Defines specific filter model name.
|
12 |
+
*
|
13 |
+
* @see ChoiceAI_Search_Model_Catalog_Layer_Filter_Boolean
|
14 |
+
*/
|
15 |
+
public function __construct()
|
16 |
+
{
|
17 |
+
parent::__construct();
|
18 |
+
$this->_filterModelName = 'choiceai_search/catalog_layer_filter_boolean';
|
19 |
+
}
|
20 |
+
}
|
app/code/local/ChoiceAI/Search/Block/Catalog/Layer/Filter/Category.php
ADDED
@@ -0,0 +1,33 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
*
|
4 |
+
* @package ChoiceAI_Search
|
5 |
+
* @copyright Copyright (c) MineWhat
|
6 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
7 |
+
*/
|
8 |
+
class ChoiceAI_Search_Block_Catalog_Layer_Filter_Category extends Mage_Catalog_Block_Layer_Filter_Abstract
|
9 |
+
{
|
10 |
+
/**
|
11 |
+
* Defines specific filter model name.
|
12 |
+
*
|
13 |
+
* @see ChoiceAI_Search_Model_Catalog_Layer_Filter_Category
|
14 |
+
*/
|
15 |
+
public function __construct()
|
16 |
+
{
|
17 |
+
parent::__construct();
|
18 |
+
$this->_filterModelName = 'choiceai_search/catalog_layer_filter_category';
|
19 |
+
}
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Adds facet condition to filter.
|
23 |
+
*
|
24 |
+
* @see ChoiceAI_Search_Model_Catalog_Layer_Filter_Category::addFacetCondition()
|
25 |
+
* @return ChoiceAI_Search_Block_Catalog_Layer_Filter_Attribute
|
26 |
+
*/
|
27 |
+
public function addFacetCondition()
|
28 |
+
{
|
29 |
+
$this->_filter->addFacetCondition();
|
30 |
+
|
31 |
+
return $this;
|
32 |
+
}
|
33 |
+
}
|
app/code/local/ChoiceAI/Search/Block/Catalog/Layer/Filter/Decimal.php
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
*
|
4 |
+
* @package ChoiceAI_Search
|
5 |
+
* @copyright Copyright (c) MineWhat
|
6 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
7 |
+
*/
|
8 |
+
class ChoiceAI_Search_Block_Catalog_Layer_Filter_Decimal extends Mage_Catalog_Block_Layer_Filter_Abstract
|
9 |
+
{
|
10 |
+
/**
|
11 |
+
* Defines specific filter model name.
|
12 |
+
*
|
13 |
+
* @see ChoiceAI_Search_Model_Catalog_Layer_Filter_Decimal
|
14 |
+
*/
|
15 |
+
public function __construct()
|
16 |
+
{
|
17 |
+
parent::__construct();
|
18 |
+
$this->_filterModelName = 'choiceai_search/catalog_layer_filter_decimal';
|
19 |
+
}
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Prepares filter model.
|
23 |
+
*
|
24 |
+
* @return ChoiceAI_Search_Block_Catalog_Layer_Filter_Decimal
|
25 |
+
*/
|
26 |
+
protected function _prepareFilter()
|
27 |
+
{
|
28 |
+
$this->_filter->setAttributeModel($this->getAttributeModel());
|
29 |
+
|
30 |
+
return $this;
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Adds facet condition to filter.
|
35 |
+
*
|
36 |
+
* @see ChoiceAI_Search_Model_Catalog_Layer_Filter_Decimal::addFacetCondition()
|
37 |
+
* @return ChoiceAI_Search_Block_Catalog_Layer_Filter_Decimal
|
38 |
+
*/
|
39 |
+
public function addFacetCondition()
|
40 |
+
{
|
41 |
+
$this->_filter->addFacetCondition();
|
42 |
+
|
43 |
+
return $this;
|
44 |
+
}
|
45 |
+
}
|
app/code/local/ChoiceAI/Search/Block/Catalog/Layer/Filter/Price.php
ADDED
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
*
|
4 |
+
* @package ChoiceAI_Search
|
5 |
+
* @copyright Copyright (c) MineWhat
|
6 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
7 |
+
*/
|
8 |
+
class ChoiceAI_Search_Block_Catalog_Layer_Filter_Price extends Mage_Catalog_Block_Layer_Filter_Abstract
|
9 |
+
{
|
10 |
+
/**
|
11 |
+
* Defines specific filter model name.
|
12 |
+
*
|
13 |
+
* @see ChoiceAI_Search_Model_Catalog_Layer_Filter_Price
|
14 |
+
*/
|
15 |
+
public function __construct()
|
16 |
+
{
|
17 |
+
parent::__construct();
|
18 |
+
$this->_filterModelName = 'choiceai_search/catalog_layer_filter_price';
|
19 |
+
}
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Prepares filter model.
|
23 |
+
*
|
24 |
+
* @return ChoiceAI_Search_Block_Catalog_Layer_Filter_Price
|
25 |
+
*/
|
26 |
+
protected function _prepareFilter()
|
27 |
+
{
|
28 |
+
$this->_filter->setAttributeModel($this->getAttributeModel());
|
29 |
+
|
30 |
+
return $this;
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Adds facet condition to filter.
|
35 |
+
*
|
36 |
+
* @see ChoiceAI_Search_Model_Catalog_Layer_Filter_Price::addFacetCondition()
|
37 |
+
* @return ChoiceAI_Search_Block_Catalog_Layer_Filter_Price
|
38 |
+
*/
|
39 |
+
public function addFacetCondition()
|
40 |
+
{
|
41 |
+
if (!$this->getRequest()->getParam('price')) {
|
42 |
+
$this->_filter->addFacetCondition();
|
43 |
+
}
|
44 |
+
|
45 |
+
return $this;
|
46 |
+
}
|
47 |
+
|
48 |
+
|
49 |
+
|
50 |
+
}
|
app/code/local/ChoiceAI/Search/Block/Catalog/Layer/View.php
ADDED
@@ -0,0 +1,120 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Overrides default layer view process to define custom filter blocks.
|
4 |
+
*
|
5 |
+
* @package ChoiceAI_Search
|
6 |
+
* @copyright Copyright (c) MineWhat
|
7 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
*/
|
9 |
+
class ChoiceAI_Search_Block_Catalog_Layer_View extends Mage_Catalog_Block_Layer_View
|
10 |
+
{
|
11 |
+
/**
|
12 |
+
* Boolean block name.
|
13 |
+
*
|
14 |
+
* @var string
|
15 |
+
*/
|
16 |
+
protected $_booleanFilterBlockName;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Registers current layer in registry.
|
20 |
+
*
|
21 |
+
* @see Mage_Catalog_Block_Product_List::getLayer()
|
22 |
+
*/
|
23 |
+
protected function _construct()
|
24 |
+
{
|
25 |
+
parent::_construct();
|
26 |
+
Mage::unregister('current_layer');
|
27 |
+
Mage::register('current_layer', $this->getLayer());
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Modifies default block names to specific ones if engine is active.
|
32 |
+
*/
|
33 |
+
protected function _initBlocks()
|
34 |
+
{
|
35 |
+
parent::_initBlocks();
|
36 |
+
if (Mage::helper('choiceai_search')->isActiveEngine()) {
|
37 |
+
$this->_categoryBlockName = 'choiceai_search/catalog_layer_filter_category';
|
38 |
+
$this->_attributeFilterBlockName = 'choiceai_search/catalog_layer_filter_attribute';
|
39 |
+
$this->_priceFilterBlockName = 'choiceai_search/catalog_layer_filter_price';
|
40 |
+
$this->_decimalFilterBlockName = 'choiceai_search/catalog_layer_filter_decimal';
|
41 |
+
$this->_booleanFilterBlockName = 'choiceai_search/catalog_layer_filter_boolean';
|
42 |
+
}
|
43 |
+
}
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Prepares layout if engine is active.
|
47 |
+
* Difference between parent method is addFacetCondition() call on each created block.
|
48 |
+
*
|
49 |
+
* @return ChoiceAI_Search_Block_Catalog_Layer_View
|
50 |
+
*/
|
51 |
+
protected function _prepareLayout()
|
52 |
+
{
|
53 |
+
if (Mage::helper('choiceai_search')->isActiveEngine()) {
|
54 |
+
$stateBlock = $this->getLayout()->createBlock($this->_stateBlockName)
|
55 |
+
->setLayer($this->getLayer());
|
56 |
+
|
57 |
+
$categoryBlock = $this->getLayout()->createBlock($this->_categoryBlockName)
|
58 |
+
->setLayer($this->getLayer())
|
59 |
+
->init();
|
60 |
+
|
61 |
+
$this->setChild('layer_state', $stateBlock);
|
62 |
+
$this->setChild('category_filter', $categoryBlock->addFacetCondition());
|
63 |
+
|
64 |
+
$filterableAttributes = $this->_getFilterableAttributes();
|
65 |
+
$filters = array();
|
66 |
+
foreach ($filterableAttributes as $attribute) {
|
67 |
+
if ($attribute->getAttributeCode() == 'price') {
|
68 |
+
$filterBlockName = $this->_priceFilterBlockName;
|
69 |
+
} elseif ($attribute->getBackendType() == 'decimal') {
|
70 |
+
$filterBlockName = $this->_decimalFilterBlockName;
|
71 |
+
} elseif ($attribute->getSourceModel() == 'eav/entity_attribute_source_boolean') {
|
72 |
+
$filterBlockName = $this->_booleanFilterBlockName;
|
73 |
+
} else {
|
74 |
+
$filterBlockName = $this->_attributeFilterBlockName;
|
75 |
+
}
|
76 |
+
|
77 |
+
$filters[$attribute->getAttributeCode() . '_filter'] = $this->getLayout()->createBlock($filterBlockName)
|
78 |
+
->setLayer($this->getLayer())
|
79 |
+
->setAttributeModel($attribute)
|
80 |
+
->init();
|
81 |
+
}
|
82 |
+
|
83 |
+
foreach ($filters as $filterName => $block) {
|
84 |
+
$this->setChild($filterName, $block->addFacetCondition());
|
85 |
+
}
|
86 |
+
|
87 |
+
$this->getLayer()->apply();
|
88 |
+
$this->getLayer()->getProductCollection()->load();
|
89 |
+
} else {
|
90 |
+
parent::_prepareLayout();
|
91 |
+
|
92 |
+
}
|
93 |
+
|
94 |
+
return $this;
|
95 |
+
}
|
96 |
+
|
97 |
+
|
98 |
+
public function getRequest(){
|
99 |
+
$controller = Mage::app()->getFrontController();
|
100 |
+
if ($controller) {
|
101 |
+
$this->_request = $controller->getRequest();
|
102 |
+
} else {
|
103 |
+
throw new Exception(Mage::helper('core')->__("Can't retrieve request object"));
|
104 |
+
}
|
105 |
+
return $this->_request;
|
106 |
+
}
|
107 |
+
|
108 |
+
/**
|
109 |
+
* Returns current catalog layer.
|
110 |
+
*
|
111 |
+
* @return ChoiceAI_Search_Model_Catalog_Layer|Mage_Catalog_Model_Layer
|
112 |
+
*/
|
113 |
+
public function getLayer()
|
114 |
+
{
|
115 |
+
if (Mage::helper('choiceai_search')->isActiveEngine()) {
|
116 |
+
return Mage::getSingleton('choiceai_search/catalog_layer');
|
117 |
+
}
|
118 |
+
return parent::getLayer();
|
119 |
+
}
|
120 |
+
}
|
app/code/local/ChoiceAI/Search/Block/Catalog/Product/List.php
ADDED
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Magento
|
4 |
+
*
|
5 |
+
* NOTICE OF LICENSE
|
6 |
+
*
|
7 |
+
* This source file is subject to the Open Software License (OSL 3.0)
|
8 |
+
* that is bundled with this package in the file LICENSE.txt.
|
9 |
+
* It is also available through the world-wide-web at this URL:
|
10 |
+
* http://opensource.org/licenses/osl-3.0.php
|
11 |
+
* If you did not receive a copy of the license and are unable to
|
12 |
+
* obtain it through the world-wide-web, please send an email
|
13 |
+
* to license@magento.com so we can send you a copy immediately.
|
14 |
+
*
|
15 |
+
* DISCLAIMER
|
16 |
+
*
|
17 |
+
* Do not edit or add to this file if you wish to upgrade Magento to newer
|
18 |
+
* versions in the future. If you wish to customize Magento for your
|
19 |
+
* needs please refer to http://www.magento.com for more information.
|
20 |
+
*
|
21 |
+
* @category Mage
|
22 |
+
* @package Mage_Catalog
|
23 |
+
* @copyright Copyright (c) 2006-2017 X.commerce, Inc. and affiliates (http://www.magento.com)
|
24 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
25 |
+
*/
|
26 |
+
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Product list
|
30 |
+
*
|
31 |
+
* @category Mage
|
32 |
+
* @package Mage_Catalog
|
33 |
+
* @author Magento Core Team <core@magentocommerce.com>
|
34 |
+
*/
|
35 |
+
class ChoiceAI_Search_Block_Catalog_Product_List extends Mage_Catalog_Block_Product_List
|
36 |
+
{
|
37 |
+
/**
|
38 |
+
* Get catalog layer model
|
39 |
+
*
|
40 |
+
* @return Mage_Catalog_Model_Layer
|
41 |
+
*/
|
42 |
+
public function getLayer()
|
43 |
+
{
|
44 |
+
/** @var $helper ChoiceAI_Search_Helper_Data */
|
45 |
+
$helper = Mage::helper('choiceai_search');
|
46 |
+
if ($helper->isActiveEngine()) {
|
47 |
+
return Mage::getSingleton('choiceai_search/catalogsearch_layer');
|
48 |
+
}
|
49 |
+
return parent::getLayer();
|
50 |
+
}
|
51 |
+
|
52 |
+
}
|
app/code/local/ChoiceAI/Search/Block/Catalog/Product/List/Toolbar.php
ADDED
@@ -0,0 +1,34 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Created by PhpStorm.
|
4 |
+
* User: harkirat
|
5 |
+
* Date: 16/5/17
|
6 |
+
* Time: 6:04 PM
|
7 |
+
*/
|
8 |
+
|
9 |
+
class ChoiceAI_Search_Block_Catalog_Product_List_Toolbar extends Mage_Catalog_Block_Product_List_Toolbar {
|
10 |
+
|
11 |
+
const IS_ACTIVE = 'choiceai_personalisation/settings/active';
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Set default Order field
|
15 |
+
*
|
16 |
+
* @param string $field
|
17 |
+
* @return Mage_Catalog_Block_Product_List_Toolbar
|
18 |
+
*/
|
19 |
+
public function getCurrentOrder()
|
20 |
+
{
|
21 |
+
// To set currently selected sort by option to extended/overridden one, in case of search/productlist
|
22 |
+
if(Mage::getStoreConfig(self::IS_ACTIVE)=='1') {
|
23 |
+
if (is_null($_REQUEST['order']) && isset($_SESSION['plist_sort_by'])) {
|
24 |
+
return $_SESSION['plist_sort_by'];
|
25 |
+
} else if ($_REQUEST['order'] == $_SESSION['plist_sort_by']) {
|
26 |
+
return $_SESSION['plist_sort_by'];
|
27 |
+
} else{
|
28 |
+
return parent::getCurrentOrder();
|
29 |
+
}
|
30 |
+
} else {
|
31 |
+
return parent::getCurrentOrder();
|
32 |
+
}
|
33 |
+
}
|
34 |
+
}
|
app/code/local/ChoiceAI/Search/Block/Catalogsearch/Enterprise/Layer.php
ADDED
@@ -0,0 +1,115 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Overrides default layer view process to define custom filter blocks.
|
4 |
+
*
|
5 |
+
* @package ChoiceAI_Search
|
6 |
+
* @copyright Copyright (c) MineWhat
|
7 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
*/
|
9 |
+
class ChoiceAI_Search_Block_Catalogsearch_Enterprise_Layer extends Enterprise_Search_Block_Catalogsearch_Layer
|
10 |
+
{
|
11 |
+
/**
|
12 |
+
* Boolean block name.
|
13 |
+
*
|
14 |
+
* @var string
|
15 |
+
*/
|
16 |
+
protected $_booleanFilterBlockName;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Modifies default block names to specific ones if engine is active.
|
20 |
+
*/
|
21 |
+
protected function _initBlocks()
|
22 |
+
{
|
23 |
+
parent::_initBlocks();
|
24 |
+
|
25 |
+
if (Mage::helper('choiceai_search')->isActiveEngine()) {
|
26 |
+
Mage::unregister('current_layer');
|
27 |
+
Mage::register('current_layer', $this->getLayer());
|
28 |
+
$this->_categoryBlockName = 'choiceai_search/catalog_layer_filter_category';
|
29 |
+
$this->_attributeFilterBlockName = 'choiceai_search/catalogsearch_layer_filter_attribute';
|
30 |
+
$this->_priceFilterBlockName = 'choiceai_search/catalog_layer_filter_price';
|
31 |
+
$this->_decimalFilterBlockName = 'choiceai_search/catalog_layer_filter_decimal';
|
32 |
+
$this->_booleanFilterBlockName = 'choiceai_search/catalog_layer_filter_boolean';
|
33 |
+
}
|
34 |
+
}
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Prepares layout if engine is active.
|
38 |
+
* Difference between parent method is addFacetCondition() call on each created block.
|
39 |
+
*
|
40 |
+
* @return ChoiceAI_Search_Block_Catalogsearch_Layer
|
41 |
+
*/
|
42 |
+
protected function _prepareLayout()
|
43 |
+
{
|
44 |
+
/** @var $helper ChoiceAI_Search_Helper_Data */
|
45 |
+
$helper = Mage::helper('choiceai_search');
|
46 |
+
if ($helper->isActiveEngine()) {
|
47 |
+
|
48 |
+
$stateBlock = $this->getLayout()->createBlock($this->_stateBlockName)
|
49 |
+
->setLayer($this->getLayer());
|
50 |
+
|
51 |
+
$categoryBlock = $this->getLayout()->createBlock($this->_categoryBlockName)
|
52 |
+
->setLayer($this->getLayer())
|
53 |
+
->init();
|
54 |
+
|
55 |
+
$this->setChild('layer_state', $stateBlock);
|
56 |
+
$this->setChild('category_filter', $categoryBlock->addFacetCondition());
|
57 |
+
|
58 |
+
$filterableAttributes = $this->_getFilterableAttributes();
|
59 |
+
$filters = array();
|
60 |
+
foreach ($filterableAttributes as $attribute) {
|
61 |
+
if ($attribute->getAttributeCode() == 'price') {
|
62 |
+
$filterBlockName = $this->_priceFilterBlockName;
|
63 |
+
} elseif ($attribute->getSourceModel() == 'eav/entity_attribute_source_boolean') {
|
64 |
+
$filterBlockName = $this->_booleanFilterBlockName;
|
65 |
+
} elseif ($attribute->getBackendType() == 'decimal') {
|
66 |
+
$filterBlockName = $this->_decimalFilterBlockName;
|
67 |
+
} else {
|
68 |
+
$filterBlockName = $this->_attributeFilterBlockName;
|
69 |
+
}
|
70 |
+
|
71 |
+
$filters[$attribute->getAttributeCode() . '_filter'] = $this->getLayout()->createBlock($filterBlockName)
|
72 |
+
->setLayer($this->getLayer())
|
73 |
+
->setAttributeModel($attribute)
|
74 |
+
->init();
|
75 |
+
}
|
76 |
+
|
77 |
+
foreach ($filters as $filterName => $block) {
|
78 |
+
$this->setChild($filterName, $block->addFacetCondition());
|
79 |
+
}
|
80 |
+
|
81 |
+
$this->getLayer()->apply();
|
82 |
+
$this->getLayer()->getProductCollection()->load();
|
83 |
+
}else{
|
84 |
+
parent::_prepareLayout();
|
85 |
+
}
|
86 |
+
|
87 |
+
return $this;
|
88 |
+
}
|
89 |
+
|
90 |
+
/**
|
91 |
+
* Checks display availability of layer block.
|
92 |
+
*
|
93 |
+
* @return bool
|
94 |
+
*/
|
95 |
+
public function canShowBlock()
|
96 |
+
{
|
97 |
+
$this->getLayer()->getProductCollection();
|
98 |
+
return ($this->canShowOptions() || count($this->getLayer()->getState()->getFilters()));
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Returns current catalog layer.
|
103 |
+
*
|
104 |
+
* @return ChoiceAI_Search_Model_Catalogsearch_Layer|Mage_Catalog_Model_Layer
|
105 |
+
*/
|
106 |
+
public function getLayer()
|
107 |
+
{
|
108 |
+
/** @var $helper ChoiceAI_Search_Helper_Data */
|
109 |
+
$helper = Mage::helper('choiceai_search');
|
110 |
+
if ($helper->isActiveEngine()) {
|
111 |
+
return Mage::getSingleton('choiceai_search/catalogsearch_layer');
|
112 |
+
}
|
113 |
+
return parent::getLayer();
|
114 |
+
}
|
115 |
+
}
|
app/code/local/ChoiceAI/Search/Block/Catalogsearch/Layer.php
ADDED
@@ -0,0 +1,115 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Overrides default layer view process to define custom filter blocks.
|
4 |
+
*
|
5 |
+
* @package ChoiceAI_Search
|
6 |
+
* @copyright Copyright (c) MineWhat
|
7 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
*/
|
9 |
+
class ChoiceAI_Search_Block_Catalogsearch_Layer extends Mage_CatalogSearch_Block_Layer
|
10 |
+
{
|
11 |
+
/**
|
12 |
+
* Boolean block name.
|
13 |
+
*
|
14 |
+
* @var string
|
15 |
+
*/
|
16 |
+
protected $_booleanFilterBlockName;
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Modifies default block names to specific ones if engine is active.
|
20 |
+
*/
|
21 |
+
protected function _initBlocks()
|
22 |
+
{
|
23 |
+
parent::_initBlocks();
|
24 |
+
|
25 |
+
if (Mage::helper('choiceai_search')->isActiveEngine()) {
|
26 |
+
Mage::unregister('current_layer');
|
27 |
+
Mage::register('current_layer', $this->getLayer());
|
28 |
+
$this->_categoryBlockName = 'choiceai_search/catalog_layer_filter_category';
|
29 |
+
$this->_attributeFilterBlockName = 'choiceai_search/catalogsearch_layer_filter_attribute';
|
30 |
+
$this->_priceFilterBlockName = 'choiceai_search/catalog_layer_filter_price';
|
31 |
+
$this->_decimalFilterBlockName = 'choiceai_search/catalog_layer_filter_decimal';
|
32 |
+
$this->_booleanFilterBlockName = 'choiceai_search/catalog_layer_filter_boolean';
|
33 |
+
}
|
34 |
+
}
|
35 |
+
|
36 |
+
/**
|
37 |
+
* Prepares layout if engine is active.
|
38 |
+
* Difference between parent method is addFacetCondition() call on each created block.
|
39 |
+
*
|
40 |
+
* @return ChoiceAI_Search_Block_Catalogsearch_Layer
|
41 |
+
*/
|
42 |
+
protected function _prepareLayout()
|
43 |
+
{
|
44 |
+
/** @var $helper ChoiceAI_Search_Helper_Data */
|
45 |
+
$helper = Mage::helper('choiceai_search');
|
46 |
+
if ($helper->isActiveEngine()) {
|
47 |
+
|
48 |
+
$stateBlock = $this->getLayout()->createBlock($this->_stateBlockName)
|
49 |
+
->setLayer($this->getLayer());
|
50 |
+
|
51 |
+
$categoryBlock = $this->getLayout()->createBlock($this->_categoryBlockName)
|
52 |
+
->setLayer($this->getLayer())
|
53 |
+
->init();
|
54 |
+
|
55 |
+
$this->setChild('layer_state', $stateBlock);
|
56 |
+
$this->setChild('category_filter', $categoryBlock->addFacetCondition());
|
57 |
+
|
58 |
+
$filterableAttributes = $this->_getFilterableAttributes();
|
59 |
+
$filters = array();
|
60 |
+
foreach ($filterableAttributes as $attribute) {
|
61 |
+
if ($attribute->getAttributeCode() == 'price') {
|
62 |
+
$filterBlockName = $this->_priceFilterBlockName;
|
63 |
+
} elseif ($attribute->getSourceModel() == 'eav/entity_attribute_source_boolean') {
|
64 |
+
$filterBlockName = $this->_booleanFilterBlockName;
|
65 |
+
} elseif ($attribute->getBackendType() == 'decimal') {
|
66 |
+
$filterBlockName = $this->_decimalFilterBlockName;
|
67 |
+
} else {
|
68 |
+
$filterBlockName = $this->_attributeFilterBlockName;
|
69 |
+
}
|
70 |
+
|
71 |
+
$filters[$attribute->getAttributeCode() . '_filter'] = $this->getLayout()->createBlock($filterBlockName)
|
72 |
+
->setLayer($this->getLayer())
|
73 |
+
->setAttributeModel($attribute)
|
74 |
+
->init();
|
75 |
+
}
|
76 |
+
|
77 |
+
foreach ($filters as $filterName => $block) {
|
78 |
+
$this->setChild($filterName, $block->addFacetCondition());
|
79 |
+
}
|
80 |
+
|
81 |
+
$this->getLayer()->apply();
|
82 |
+
$this->getLayer()->getProductCollection()->load();
|
83 |
+
}else{
|
84 |
+
parent::_prepareLayout();
|
85 |
+
}
|
86 |
+
|
87 |
+
return $this;
|
88 |
+
}
|
89 |
+
|
90 |
+
/**
|
91 |
+
* Checks display availability of layer block.
|
92 |
+
*
|
93 |
+
* @return bool
|
94 |
+
*/
|
95 |
+
public function canShowBlock()
|
96 |
+
{
|
97 |
+
$this->getLayer()->getProductCollection();
|
98 |
+
return ($this->canShowOptions() || count($this->getLayer()->getState()->getFilters()));
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Returns current catalog layer.
|
103 |
+
*
|
104 |
+
* @return ChoiceAI_Search_Model_Catalogsearch_Layer|Mage_Catalog_Model_Layer
|
105 |
+
*/
|
106 |
+
public function getLayer()
|
107 |
+
{
|
108 |
+
/** @var $helper ChoiceAI_Search_Helper_Data */
|
109 |
+
$helper = Mage::helper('choiceai_search');
|
110 |
+
if ($helper->isActiveEngine()) {
|
111 |
+
return Mage::getSingleton('choiceai_search/catalogsearch_layer');
|
112 |
+
}
|
113 |
+
return parent::getLayer();
|
114 |
+
}
|
115 |
+
}
|
app/code/local/ChoiceAI/Search/Block/Catalogsearch/Layer/Filter/Attribute.php
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Handles attribute filtering in layered navigation in a query search context.
|
4 |
+
*
|
5 |
+
* @package ChoiceAI_Search
|
6 |
+
* @copyright Copyright (c) MineWhat
|
7 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
*/
|
9 |
+
class ChoiceAI_Search_Block_Catalogsearch_Layer_Filter_Attribute extends Mage_Catalog_Block_Layer_Filter_Abstract
|
10 |
+
{
|
11 |
+
/**
|
12 |
+
* Defines specific filter model name.
|
13 |
+
*
|
14 |
+
* @see ChoiceAI_Search_Model_Catalogsearch_Layer_Filter_Attribute
|
15 |
+
*/
|
16 |
+
public function __construct()
|
17 |
+
{
|
18 |
+
parent::__construct();
|
19 |
+
$this->_filterModelName = 'choiceai_search/catalogsearch_layer_filter_attribute';
|
20 |
+
}
|
21 |
+
|
22 |
+
/**
|
23 |
+
* Prepares filter model.
|
24 |
+
*
|
25 |
+
* @return ChoiceAI_Search_Block_Catalogsearch_Layer_Filter_Attribute
|
26 |
+
*/
|
27 |
+
protected function _prepareFilter()
|
28 |
+
{
|
29 |
+
$this->_filter->setAttributeModel($this->getAttributeModel());
|
30 |
+
|
31 |
+
return $this;
|
32 |
+
}
|
33 |
+
|
34 |
+
/**
|
35 |
+
* Adds facet condition to filter.
|
36 |
+
*
|
37 |
+
* @see ChoiceAI_Search_Model_Catalog_Layer_Filter_Attribute::addFacetCondition()
|
38 |
+
* @return ChoiceAI_Search_Block_Catalogsearch_Layer_Filter_Attribute
|
39 |
+
*/
|
40 |
+
public function addFacetCondition()
|
41 |
+
{
|
42 |
+
$this->_filter->addFacetCondition();
|
43 |
+
|
44 |
+
return $this;
|
45 |
+
}
|
46 |
+
}
|
app/code/local/ChoiceAI/Search/Block/Catalogsearch/Result.php
ADDED
@@ -0,0 +1,36 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Created by PhpStorm.
|
4 |
+
* User: Harkirat
|
5 |
+
* Date: 12/5/17
|
6 |
+
* Time: 12:47 PM
|
7 |
+
*/
|
8 |
+
|
9 |
+
class ChoiceAI_Search_Block_Catalogsearch_Result extends Mage_CatalogSearch_Block_Result {
|
10 |
+
const IS_ACTIVE = 'choiceai_personalisation/settings/active';
|
11 |
+
/**
|
12 |
+
* Set search available list orders
|
13 |
+
*
|
14 |
+
* @return Mage_CatalogSearch_Block_Result
|
15 |
+
*/
|
16 |
+
public function setListOrders()
|
17 |
+
{
|
18 |
+
if(Mage::getStoreConfig(self::IS_ACTIVE)=='1') {
|
19 |
+
$category = Mage::getSingleton('catalog/layer')
|
20 |
+
->getCurrentCategory();
|
21 |
+
/* @var $category Mage_Catalog_Model_Category */
|
22 |
+
$availableOrders = $category->getAvailableSortByOptions();
|
23 |
+
unset($availableOrders['position']);
|
24 |
+
|
25 |
+
// Removed addition of 'Relevance' option here, which is in core functionality
|
26 |
+
$this->getListBlock()
|
27 |
+
->setAvailableOrders($availableOrders)
|
28 |
+
->setDefaultDirection('desc');
|
29 |
+
// ->setSortBy('relevance');
|
30 |
+
}else{
|
31 |
+
return parent::setListOrders();
|
32 |
+
}
|
33 |
+
|
34 |
+
return $this;
|
35 |
+
}
|
36 |
+
}
|
app/code/local/ChoiceAI/Search/Helper/Catalogsearch.php
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @category ChoiceAI
|
5 |
+
* @package ChoiceAI_Recommendation
|
6 |
+
* @copyright Copyright (c) MineWhat
|
7 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
*/
|
9 |
+
class ChoiceAI_Search_Helper_Catalogsearch extends Mage_CatalogSearch_Helper_Data {
|
10 |
+
|
11 |
+
public function getResultUrl($query = null) {
|
12 |
+
if(Mage::helper('choiceai_search')->isHostedSearchActive()) {
|
13 |
+
$redirectUrl = Mage::helper('choiceai_search')->getHostedRedirectUrl();
|
14 |
+
return $redirectUrl . ((!is_null($query) && $query != "")?($this->getQueryParamName()."=".$query):"");
|
15 |
+
}
|
16 |
+
return parent::getResultUrl($query);
|
17 |
+
}
|
18 |
+
|
19 |
+
}
|
app/code/local/ChoiceAI/Search/Helper/Choiceaisearch.php
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
*
|
4 |
+
* @package ChoiceAI_Search
|
5 |
+
* @copyright Copyright (c) MineWhat
|
6 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
7 |
+
*/
|
8 |
+
class ChoiceAI_Search_Helper_ChoiceAIsearch extends ChoiceAI_Search_Helper_Data
|
9 |
+
{
|
10 |
+
|
11 |
+
public function getEngineConfigData($prefix = '', $website = null)
|
12 |
+
{
|
13 |
+
return Mage::helper('choiceai_searchcore')->getEngineConfigData($prefix, $website);
|
14 |
+
|
15 |
+
}
|
16 |
+
}
|
app/code/local/ChoiceAI/Search/Helper/Data.php
ADDED
@@ -0,0 +1,670 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
*
|
4 |
+
* @package ChoiceAI_Search
|
5 |
+
* @copyright Copyright (c) MineWhat
|
6 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
7 |
+
*/
|
8 |
+
class ChoiceAI_Search_Helper_Data extends Mage_Core_Helper_Abstract
|
9 |
+
{
|
10 |
+
/**
|
11 |
+
* Allowed languages.
|
12 |
+
* Example: array('en_US' => 'en', 'fr_FR' => 'fr')
|
13 |
+
*
|
14 |
+
* @var array
|
15 |
+
*/
|
16 |
+
protected $_languageCodes = array();
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Searchable attributes.
|
20 |
+
*
|
21 |
+
* @var array
|
22 |
+
*/
|
23 |
+
protected $_searchableAttributes;
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Sortable attributes.
|
27 |
+
*
|
28 |
+
* @var array
|
29 |
+
*/
|
30 |
+
protected $_sortableAttributes;
|
31 |
+
|
32 |
+
/**
|
33 |
+
* Text field types.
|
34 |
+
*
|
35 |
+
* @var array
|
36 |
+
*/
|
37 |
+
protected $_textFieldTypes = array(
|
38 |
+
'text',
|
39 |
+
'varchar',
|
40 |
+
);
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Unlocalized field types.
|
44 |
+
*
|
45 |
+
* @var array
|
46 |
+
*/
|
47 |
+
protected $_unlocalizedFieldTypes = array(
|
48 |
+
'datetime',
|
49 |
+
'decimal',
|
50 |
+
);
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Boolean field which stores choiceai active or not
|
54 |
+
*
|
55 |
+
* @var boolean
|
56 |
+
*/
|
57 |
+
public $is_active = NULL;
|
58 |
+
|
59 |
+
|
60 |
+
const IS_ACTIVE = 'choiceai_personalisation/settings/active';
|
61 |
+
const CONFIG_KEY = 'choiceai_personalisation/settings/config';
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Returns attribute field name (localized if needed).
|
65 |
+
*
|
66 |
+
* @param Mage_Catalog_Model_Resource_Eav_Attribute $attribute
|
67 |
+
* @param string $localeCode
|
68 |
+
* @return string
|
69 |
+
*/
|
70 |
+
public function getAttributeFieldName($attribute, $localeCode = null)
|
71 |
+
{
|
72 |
+
if (is_string($attribute)) {
|
73 |
+
$this->getSearchableAttributes(); // populate searchable attributes if not already set
|
74 |
+
if (!isset($this->_searchableAttributes[$attribute])) {
|
75 |
+
return $attribute;
|
76 |
+
}
|
77 |
+
$attribute = $this->_searchableAttributes[$attribute];
|
78 |
+
}
|
79 |
+
$attributeCode = $attribute->getAttributeCode();
|
80 |
+
$backendType = $attribute->getBackendType();
|
81 |
+
|
82 |
+
if ($attributeCode != 'score' && in_array($backendType, $this->_textFieldTypes)) {
|
83 |
+
if (null === $localeCode) {
|
84 |
+
$localeCode = $this->getLocaleCode();
|
85 |
+
}
|
86 |
+
// $languageCode = $this->getLanguageCodeByLocaleCode($localeCode);
|
87 |
+
// $languageSuffix = "_fq";
|
88 |
+
//$attributeCode .= $languageSuffix;
|
89 |
+
}
|
90 |
+
|
91 |
+
return $attributeCode;
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* Returns cache lifetime in seconds.
|
96 |
+
*
|
97 |
+
* @return int
|
98 |
+
*/
|
99 |
+
public function getCacheLifetime()
|
100 |
+
{
|
101 |
+
return Mage::getStoreConfig('core/cache/lifetime');
|
102 |
+
}
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Returns search engine config data.
|
106 |
+
*
|
107 |
+
* @param string $prefix
|
108 |
+
* @param mixed $store
|
109 |
+
* @return array
|
110 |
+
*/
|
111 |
+
public function getEngineConfigData($prefix = '', $website = null)
|
112 |
+
{
|
113 |
+
return Mage::helper('choiceai_searchcore')->getEngineConfigData($prefix, $website);
|
114 |
+
}
|
115 |
+
|
116 |
+
/**
|
117 |
+
* Returns EAV config singleton.
|
118 |
+
*
|
119 |
+
* @return Mage_Eav_Model_Config
|
120 |
+
*/
|
121 |
+
public function getEavConfig()
|
122 |
+
{
|
123 |
+
return Mage::getSingleton('eav/config');
|
124 |
+
}
|
125 |
+
|
126 |
+
/**
|
127 |
+
* Returns language code of specified locale code.
|
128 |
+
*
|
129 |
+
* @param string $localeCode
|
130 |
+
* @return bool
|
131 |
+
*/
|
132 |
+
public function getLanguageCodeByLocaleCode($localeCode)
|
133 |
+
{
|
134 |
+
$localeCode = (string) $localeCode;
|
135 |
+
if (!$localeCode) {
|
136 |
+
return false;
|
137 |
+
}
|
138 |
+
|
139 |
+
if (!isset($this->_languageCodes[$localeCode])) {
|
140 |
+
$languages = $this->getSupportedLanguages();
|
141 |
+
$this->_languageCodes[$localeCode] = false;
|
142 |
+
foreach ($languages as $code => $locales) {
|
143 |
+
if (is_array($locales)) {
|
144 |
+
if (in_array($localeCode, $locales)) {
|
145 |
+
$this->_languageCodes[$localeCode] = $code;
|
146 |
+
}
|
147 |
+
} elseif ($localeCode == $locales) {
|
148 |
+
$this->_languageCodes[$localeCode] = $code;
|
149 |
+
}
|
150 |
+
}
|
151 |
+
}
|
152 |
+
|
153 |
+
return $this->_languageCodes[$localeCode];
|
154 |
+
}
|
155 |
+
|
156 |
+
/**
|
157 |
+
* Returns store language code.
|
158 |
+
*
|
159 |
+
* @param mixed $store
|
160 |
+
* @return bool
|
161 |
+
*/
|
162 |
+
public function getLanguageCodeByStore($store = null)
|
163 |
+
{
|
164 |
+
return $this->getLanguageCodeByLocaleCode($this->getLocaleCode($store));
|
165 |
+
}
|
166 |
+
|
167 |
+
/**
|
168 |
+
* Returns store locale code.
|
169 |
+
*
|
170 |
+
* @param null $store
|
171 |
+
* @return string
|
172 |
+
*/
|
173 |
+
public function getLocaleCode($store = null)
|
174 |
+
{
|
175 |
+
return Mage::getStoreConfig(Mage_Core_Model_Locale::XML_PATH_DEFAULT_LOCALE, $store);
|
176 |
+
}
|
177 |
+
|
178 |
+
/**
|
179 |
+
* Retrieves all searchable product attributes.
|
180 |
+
* Possibility to filter attributes by backend type.
|
181 |
+
*
|
182 |
+
* @param array $backendType
|
183 |
+
* @return array
|
184 |
+
*/
|
185 |
+
public function getSearchableAttributes($backendType = null)
|
186 |
+
{
|
187 |
+
if (null === $this->_searchableAttributes) {
|
188 |
+
$this->_searchableAttributes = array();
|
189 |
+
$entityType = $this->getEavConfig()->getEntityType('catalog_product');
|
190 |
+
$entity = $entityType->getEntity();
|
191 |
+
|
192 |
+
/* @var $productAttributeCollection Mage_Catalog_Model_Resource_Product_Attribute_Collection */
|
193 |
+
$productAttributeCollection = Mage::getResourceModel('catalog/product_attribute_collection')
|
194 |
+
->setEntityTypeFilter($entityType->getEntityTypeId())
|
195 |
+
->addVisibleFilter()
|
196 |
+
->addToIndexFilter(true);
|
197 |
+
|
198 |
+
$attributes = $productAttributeCollection->getItems();
|
199 |
+
foreach ($attributes as $attribute) {
|
200 |
+
/** @var $attribute Mage_Catalog_Model_Resource_Eav_Attribute */
|
201 |
+
$attribute->setEntity($entity);
|
202 |
+
$this->_searchableAttributes[$attribute->getAttributeCode()] = $attribute;
|
203 |
+
}
|
204 |
+
}
|
205 |
+
|
206 |
+
if (null !== $backendType) {
|
207 |
+
$backendType = (array) $backendType;
|
208 |
+
$attributes = array();
|
209 |
+
foreach ($this->_searchableAttributes as $attribute) {
|
210 |
+
/** @var $attribute Mage_Catalog_Model_Resource_Eav_Attribute */
|
211 |
+
if (in_array($attribute->getBackendType(), $backendType)) {
|
212 |
+
$attributes[$attribute->getAttributeCode()] = $attribute;
|
213 |
+
}
|
214 |
+
}
|
215 |
+
|
216 |
+
return $attributes;
|
217 |
+
}
|
218 |
+
|
219 |
+
return $this->_searchableAttributes;
|
220 |
+
}
|
221 |
+
|
222 |
+
/**
|
223 |
+
* Returns seach config data.
|
224 |
+
*
|
225 |
+
* @param string $field
|
226 |
+
* @param mixed $store
|
227 |
+
* @return array
|
228 |
+
*/
|
229 |
+
public function getSearchConfigData($field, $store = null)
|
230 |
+
{
|
231 |
+
$path = 'catalog/search/' . $field;
|
232 |
+
|
233 |
+
return Mage::getStoreConfig($path, $store);
|
234 |
+
}
|
235 |
+
|
236 |
+
|
237 |
+
/**
|
238 |
+
* Returns searched parameter as array.
|
239 |
+
*
|
240 |
+
* @param Mage_Catalog_Model_Resource_Eav_Attribute $attribute
|
241 |
+
* @param mixed $value
|
242 |
+
* @return array
|
243 |
+
*/
|
244 |
+
public function getSearchParam($attribute, $value)
|
245 |
+
{
|
246 |
+
if (empty($value) ||
|
247 |
+
(isset($value['from']) && empty($value['from']) &&
|
248 |
+
isset($value['to']) && empty($value['to']))) {
|
249 |
+
return false;
|
250 |
+
}
|
251 |
+
|
252 |
+
$field = $this->getAttributeFieldName($attribute);
|
253 |
+
$backendType = $attribute->getBackendType();
|
254 |
+
if ($backendType == 'datetime') {
|
255 |
+
$format = Mage::app()->getLocale()->getDateFormat(Mage_Core_Model_Locale::FORMAT_TYPE_SHORT);
|
256 |
+
if (is_array($value)) {
|
257 |
+
foreach ($value as &$val) {
|
258 |
+
if (!is_empty_date($val)) {
|
259 |
+
$date = new Zend_Date($val, $format);
|
260 |
+
$val = $date->toString(Zend_Date::ISO_8601) . 'Z';
|
261 |
+
}
|
262 |
+
}
|
263 |
+
unset($val);
|
264 |
+
} else {
|
265 |
+
if (!is_empty_date($value)) {
|
266 |
+
$date = new Zend_Date($value, $format);
|
267 |
+
$value = $date->toString(Zend_Date::ISO_8601) . 'Z';
|
268 |
+
}
|
269 |
+
}
|
270 |
+
}
|
271 |
+
|
272 |
+
if ($attribute->usesSource()) {
|
273 |
+
$attribute->setStoreId(Mage::app()->getStore()->getId());
|
274 |
+
}
|
275 |
+
|
276 |
+
return array($field => $value);
|
277 |
+
}
|
278 |
+
|
279 |
+
/**
|
280 |
+
* Returns sortable attribute field name (localized if needed).
|
281 |
+
*
|
282 |
+
* @param Mage_Catalog_Model_Resource_Eav_Attribute $attribute
|
283 |
+
* @param string $locale
|
284 |
+
* @return string
|
285 |
+
*/
|
286 |
+
public function getSortableAttributeFieldName($attribute, $locale = null)
|
287 |
+
{
|
288 |
+
if (is_string($attribute)) {
|
289 |
+
$this->getSortableAttributes(); // populate sortable attributes if not already set
|
290 |
+
if (!isset($this->_sortableAttributes[$attribute])) {
|
291 |
+
return $attribute;
|
292 |
+
}
|
293 |
+
$attribute = $this->_sortableAttributes[$attribute];
|
294 |
+
}
|
295 |
+
|
296 |
+
$attributeCode = $attribute->getAttributeCode();
|
297 |
+
|
298 |
+
if ($attributeCode != 'score' && !in_array($attribute->getBackendType(), $this->_unlocalizedFieldTypes)) {
|
299 |
+
if (null === $locale) {
|
300 |
+
$locale = $this->getLocaleCode();
|
301 |
+
}
|
302 |
+
$languageCode = $this->getLanguageCodeByLocaleCode($locale);
|
303 |
+
$languageSuffix = $languageCode ? '_' . $languageCode : '';
|
304 |
+
$attributeCode .= $languageSuffix;
|
305 |
+
}
|
306 |
+
|
307 |
+
return 'sort_by_' . $attributeCode;
|
308 |
+
}
|
309 |
+
|
310 |
+
/**
|
311 |
+
* Retrieves all sortable product attributes.
|
312 |
+
*
|
313 |
+
* @return array
|
314 |
+
*/
|
315 |
+
public function getSortableAttributes()
|
316 |
+
{
|
317 |
+
if (null === $this->_sortableAttributes) {
|
318 |
+
$this->_sortableAttributes = Mage::getSingleton('catalog/config')->getAttributesUsedForSortBy();
|
319 |
+
if (array_key_exists('price', $this->_sortableAttributes)) {
|
320 |
+
unset($this->_sortableAttributes['price']); // Price sorting is handled with searchable attribute.
|
321 |
+
}
|
322 |
+
}
|
323 |
+
|
324 |
+
return $this->_sortableAttributes;
|
325 |
+
}
|
326 |
+
|
327 |
+
/**
|
328 |
+
* Defines supported languages for snowball filter.
|
329 |
+
*
|
330 |
+
* @return array
|
331 |
+
*/
|
332 |
+
public function getSupportedLanguages()
|
333 |
+
{
|
334 |
+
$default = array(
|
335 |
+
/**
|
336 |
+
* SnowBall filter based
|
337 |
+
*/
|
338 |
+
// Danish
|
339 |
+
'da' => 'da_DK',
|
340 |
+
// Dutch
|
341 |
+
'nl' => 'nl_NL',
|
342 |
+
// English
|
343 |
+
'en' => array('en_AU', 'en_CA', 'en_NZ', 'en_GB', 'en_US'),
|
344 |
+
// Finnish
|
345 |
+
'fi' => 'fi_FI',
|
346 |
+
// French
|
347 |
+
'fr' => array('fr_CA', 'fr_FR'),
|
348 |
+
// German
|
349 |
+
'de' => array('de_DE','de_DE','de_AT'),
|
350 |
+
// Italian
|
351 |
+
'it' => array('it_IT','it_CH'),
|
352 |
+
// Norwegian
|
353 |
+
'nb' => array('nb_NO', 'nn_NO'),
|
354 |
+
// Portuguese
|
355 |
+
'pt' => array('pt_BR', 'pt_PT'),
|
356 |
+
// Romanian
|
357 |
+
'ro' => 'ro_RO',
|
358 |
+
// Russian
|
359 |
+
'ru' => 'ru_RU',
|
360 |
+
// Spanish
|
361 |
+
'es' => array('es_AR', 'es_CL', 'es_CO', 'es_CR', 'es_ES', 'es_MX', 'es_PA', 'es_PE', 'es_VE'),
|
362 |
+
// Swedish
|
363 |
+
'sv' => 'sv_SE',
|
364 |
+
// Turkish
|
365 |
+
'tr' => 'tr_TR',
|
366 |
+
|
367 |
+
/**
|
368 |
+
* Lucene class based
|
369 |
+
*/
|
370 |
+
// Czech
|
371 |
+
'cs' => 'cs_CZ',
|
372 |
+
// Greek
|
373 |
+
'el' => 'el_GR',
|
374 |
+
// Thai
|
375 |
+
'th' => 'th_TH',
|
376 |
+
// Chinese
|
377 |
+
'zh' => array('zh_CN', 'zh_HK', 'zh_TW'),
|
378 |
+
// Japanese
|
379 |
+
'ja' => 'ja_JP',
|
380 |
+
// Korean
|
381 |
+
'ko' => 'ko_KR'
|
382 |
+
);
|
383 |
+
|
384 |
+
return $default;
|
385 |
+
}
|
386 |
+
|
387 |
+
/**
|
388 |
+
* Checks if configured engine is active.
|
389 |
+
*
|
390 |
+
* @return bool
|
391 |
+
*/
|
392 |
+
public function isActiveEngine() {
|
393 |
+
|
394 |
+
if(is_null($this->is_active)) {
|
395 |
+
$storeConfig = json_decode(Mage::getStoreConfig(self::CONFIG_KEY));
|
396 |
+
$sortbyObjs = $storeConfig->sortby;
|
397 |
+
|
398 |
+
// Getting URL Path
|
399 |
+
$currentReqPath = explode("?", $_SERVER['REQUEST_URI'])[0];
|
400 |
+
$currentReqPath = rtrim($currentReqPath, "/");
|
401 |
+
|
402 |
+
// Getting param keys in array var $paramPairs
|
403 |
+
parse_str($_SERVER['QUERY_STRING'], $paramPairs);
|
404 |
+
// Getting query keys
|
405 |
+
$currentReqParams = array();
|
406 |
+
if (count($paramPairs)) {
|
407 |
+
foreach ($paramPairs as $key => $paramPair)
|
408 |
+
$currentReqParams[] = $key;
|
409 |
+
}
|
410 |
+
|
411 |
+
// Refining URL path
|
412 |
+
// My own local installation case: localhost/magento/
|
413 |
+
if (strpos($currentReqPath, "/magento/") !== false)
|
414 |
+
$currentReqPath = str_replace("/magento/", "/", $currentReqPath);
|
415 |
+
|
416 |
+
// Making www.store.com/index.php/abcd => www.store.com/abcd
|
417 |
+
if (strpos($currentReqPath, "/index.php/") !== false)
|
418 |
+
$currentReqPath = str_replace("/index.php/", "/", $currentReqPath);
|
419 |
+
|
420 |
+
$isPluginActive = Mage::getStoreConfig(self::IS_ACTIVE) == '1';
|
421 |
+
|
422 |
+
if ($isPluginActive) {
|
423 |
+
foreach ($sortbyObjs as $sortbyObj) {
|
424 |
+
if (isset($sortbyObj->rule->paths)) {
|
425 |
+
if (in_array($currentReqPath, $sortbyObj->rule->paths)) {
|
426 |
+
$choiceOptions = $this->_getOptionsAddedByChoice($sortbyObj);
|
427 |
+
|
428 |
+
if (is_null($_REQUEST["order"]))
|
429 |
+
$this->_setDefaultSortOption($sortbyObj, $storeConfig);
|
430 |
+
break;
|
431 |
+
}
|
432 |
+
}
|
433 |
+
|
434 |
+
if (isset($sortbyObj->rule->params)) {
|
435 |
+
if (!empty(array_intersect($currentReqParams, $sortbyObj->rule->params))) {
|
436 |
+
$choiceOptions = $this->_getOptionsAddedByChoice($sortbyObj);
|
437 |
+
|
438 |
+
//
|
439 |
+
if (is_null($_REQUEST["order"]))
|
440 |
+
$this->_setDefaultSortOption($sortbyObj, $storeConfig);
|
441 |
+
break;
|
442 |
+
}
|
443 |
+
}
|
444 |
+
}
|
445 |
+
|
446 |
+
if (count($choiceOptions) && in_array($_REQUEST["order"], $choiceOptions)) {
|
447 |
+
$this->is_active = true;
|
448 |
+
}
|
449 |
+
}
|
450 |
+
}
|
451 |
+
|
452 |
+
return $this->is_active;
|
453 |
+
}
|
454 |
+
|
455 |
+
// If sort order is default, $_REQUEST["order"] will not exist
|
456 |
+
// This adds a default value in it
|
457 |
+
private function _setDefaultSortOption($sortbyObj, $STORE_CONFIG){
|
458 |
+
if(isset($sortbyObj->extend)){
|
459 |
+
foreach ($sortbyObj->extend as $optionKey => $optionValue) {
|
460 |
+
$_REQUEST['order'] = $optionKey;
|
461 |
+
break;
|
462 |
+
}
|
463 |
+
} else if(isset($sortbyObj->override)) {
|
464 |
+
$_REQUEST["order"] = $STORE_CONFIG->default_search_sort;
|
465 |
+
} else if(isset($_SESSION['catalog']) && isset($_SESSION['catalog']['sort_order'])){
|
466 |
+
// If prod list page, use the session value
|
467 |
+
// This case although seems useless
|
468 |
+
$_REQUEST["order"] = $_SESSION['catalog']['sort_order'];
|
469 |
+
}
|
470 |
+
}
|
471 |
+
|
472 |
+
/**
|
473 |
+
* @param $sortbyObj
|
474 |
+
* @return array
|
475 |
+
*/
|
476 |
+
private function _getOptionsAddedByChoice($sortbyObj){
|
477 |
+
$options = array();
|
478 |
+
|
479 |
+
if(isset($sortbyObj->override)){
|
480 |
+
// Search case, override all system options with choice
|
481 |
+
$caiOptions = $sortbyObj->override;
|
482 |
+
|
483 |
+
foreach ($caiOptions as $key => $caiOption)
|
484 |
+
$options[] = $key;
|
485 |
+
} elseif(isset($sortbyObj->extend)) {
|
486 |
+
foreach ($sortbyObj->extend as $key=>$option)
|
487 |
+
$options[] = $key;
|
488 |
+
}
|
489 |
+
|
490 |
+
return $options;
|
491 |
+
}
|
492 |
+
|
493 |
+
/**
|
494 |
+
* Checks whether request is a navigation
|
495 |
+
*
|
496 |
+
* @param Mage_Catalog_Model_Resource_Eav_Attribute $attribute
|
497 |
+
* @return bool
|
498 |
+
*/
|
499 |
+
public function isNavigation() {
|
500 |
+
if($this->_getRequest()->getControllerName() == "category") {
|
501 |
+
return true;
|
502 |
+
}
|
503 |
+
return false;
|
504 |
+
}
|
505 |
+
|
506 |
+
/**
|
507 |
+
* Checks whether request is a resultPage
|
508 |
+
*
|
509 |
+
* @param Mage_Catalog_Model_Resource_Eav_Attribute $attribute
|
510 |
+
* @return bool
|
511 |
+
*/
|
512 |
+
public function isSearch() {
|
513 |
+
if($this->_getRequest()->getControllerName() == "result") {
|
514 |
+
return true;
|
515 |
+
}
|
516 |
+
return false;
|
517 |
+
}
|
518 |
+
|
519 |
+
/**
|
520 |
+
* Checks if specified attribute is indexable by search engine.
|
521 |
+
*
|
522 |
+
* @param Mage_Catalog_Model_Resource_Eav_Attribute $attribute
|
523 |
+
* @return bool
|
524 |
+
*/
|
525 |
+
public function isAttributeIndexable($attribute)
|
526 |
+
{
|
527 |
+
if ($attribute->getBackendType() == 'varchar' && !$attribute->getBackendModel()) {
|
528 |
+
return true;
|
529 |
+
}
|
530 |
+
|
531 |
+
if ($attribute->getBackendType() == 'int'
|
532 |
+
&& $attribute->getSourceModel() != 'eav/entity_attribute_source_boolean'
|
533 |
+
&& ($attribute->getIsSearchable() || $attribute->getIsFilterable() || $attribute->getIsFilterableInSearch())
|
534 |
+
) {
|
535 |
+
return true;
|
536 |
+
}
|
537 |
+
|
538 |
+
if ($attribute->getIsSearchable() || $attribute->getIsFilterable() || $attribute->getIsFilterableInSearch()) {
|
539 |
+
return true;
|
540 |
+
}
|
541 |
+
|
542 |
+
return false;
|
543 |
+
}
|
544 |
+
|
545 |
+
/**
|
546 |
+
* Checks if debug mode is enabled.
|
547 |
+
*
|
548 |
+
* @return bool
|
549 |
+
*/
|
550 |
+
public function isDebugEnabled()
|
551 |
+
{
|
552 |
+
$config = $this->getEngineConfigData();
|
553 |
+
|
554 |
+
return array_key_exists('enable_debug_mode', $config) && $config['enable_debug_mode'];
|
555 |
+
}
|
556 |
+
|
557 |
+
/**
|
558 |
+
* Method that can be overriden for customing product data indexation.
|
559 |
+
*
|
560 |
+
* @param array $index
|
561 |
+
* @param string $separator
|
562 |
+
* @return array
|
563 |
+
*/
|
564 |
+
public function prepareIndexData($index, $separator = null)
|
565 |
+
{
|
566 |
+
return $index;
|
567 |
+
}
|
568 |
+
|
569 |
+
/**
|
570 |
+
* Forces error display.
|
571 |
+
*
|
572 |
+
* @param string $error
|
573 |
+
*/
|
574 |
+
public function showError($error)
|
575 |
+
{
|
576 |
+
echo Mage::app()->getLayout()->createBlock('core/messages')
|
577 |
+
->addError($error)->getGroupedHtml();
|
578 |
+
}
|
579 |
+
|
580 |
+
/*
|
581 |
+
* returns the choiceai site name
|
582 |
+
*
|
583 |
+
* @return String
|
584 |
+
*/
|
585 |
+
public function getSiteName(){
|
586 |
+
$siteKeyLabel = ChoiceAI_Searchcore_Helper_Constants::SITE_KEY;
|
587 |
+
$config = $this->getEngineConfigData($siteKeyLabel);
|
588 |
+
if(array_key_exists($siteKeyLabel, $config) && $config[$siteKeyLabel] != "")
|
589 |
+
return $config[$siteKeyLabel];
|
590 |
+
else {
|
591 |
+
$siteKey = Mage::getResourceModel('choiceai_searchcore/config')
|
592 |
+
->getValue(Mage::app()->getWebsite()->getWebsiteId(),
|
593 |
+
$siteKeyLabel);
|
594 |
+
if(isset($siteKey) && $siteKey != ''){
|
595 |
+
Mage::helper('choiceai_searchcore')->saveConfig(Mage::app()->getWebsite(),
|
596 |
+
array($siteKeyLabel => $siteKey));
|
597 |
+
return $siteKey;
|
598 |
+
} else {
|
599 |
+
if(Mage::getIsDeveloperMode()) {
|
600 |
+
Mage::throwException("ChoiceAI site key is empty");
|
601 |
+
} else {
|
602 |
+
Mage::helper('choiceai_searchcore')->log(Zend_Log::ERR, 'ChoiceAI site key is not set');
|
603 |
+
return null;
|
604 |
+
}
|
605 |
+
}
|
606 |
+
}
|
607 |
+
}
|
608 |
+
|
609 |
+
/*
|
610 |
+
* returns the choiceai api Key
|
611 |
+
*
|
612 |
+
* @return String
|
613 |
+
*/
|
614 |
+
public function getApiKey(){
|
615 |
+
$apiKeyLabel = ChoiceAI_Searchcore_Helper_Constants::API_KEY;
|
616 |
+
$config = $this->getEngineConfigData($apiKeyLabel);
|
617 |
+
if(array_key_exists($apiKeyLabel, $config) && $config[$apiKeyLabel] != "")
|
618 |
+
return $config[$apiKeyLabel];
|
619 |
+
else {
|
620 |
+
$apiKey = Mage::getResourceModel('choiceai_searchcore/config')
|
621 |
+
->getValue(Mage::app()->getWebsite()->getWebsiteId(), $apiKeyLabel);
|
622 |
+
if(isset($apiKey) && $apiKey != ''){
|
623 |
+
Mage::helper('choiceai_searchcore')->saveConfig(Mage::app()->getWebsite(),
|
624 |
+
array($apiKeyLabel => $apiKey));
|
625 |
+
return $apiKey;
|
626 |
+
} else {
|
627 |
+
if(Mage::getIsDeveloperMode()) {
|
628 |
+
Mage::throwException("ChoiceAI api key is empty");
|
629 |
+
} else {
|
630 |
+
Mage::helper('choiceai_searchcore')->log(Zend_Log::ERR, 'ChoiceAI Api key is not set');
|
631 |
+
return null;
|
632 |
+
}
|
633 |
+
}
|
634 |
+
}
|
635 |
+
}
|
636 |
+
|
637 |
+
/**
|
638 |
+
* This method checks whether hosted search is active or not
|
639 |
+
* @return boolean
|
640 |
+
*/
|
641 |
+
public function isHostedSearchActive()
|
642 |
+
{
|
643 |
+
$siteKey = null;
|
644 |
+
$apiKey = null;
|
645 |
+
try {
|
646 |
+
$siteKey = $this->getSiteName();
|
647 |
+
$apiKey = $this->getApiKey();
|
648 |
+
} catch(Exception $e) {
|
649 |
+
//ignoring the exception
|
650 |
+
}
|
651 |
+
$searchConf = $this->getEngineConfigData('search');
|
652 |
+
$hostedSearchConf = Mage::helper('choiceai_searchcore')->isConfigTrue(Mage::app()->getWebsite(),ChoiceAI_Searchcore_Helper_Constants::SEARCH_HOSTED_STATUS);
|
653 |
+
$searchModConf = Mage::helper('choiceai_searchcore')->isConfigTrue(Mage::app()->getWebsite(), ChoiceAI_Searchcore_Helper_Constants::SEARCH_MOD_STATUS);
|
654 |
+
$hostedIntStatus = $searchConf[ChoiceAI_Searchcore_Helper_Constants::SEARCH_HOSTED_INT_STATUS];
|
655 |
+
$hostedSearchRedirectUrl = $searchConf[ChoiceAI_Searchcore_Helper_Constants::SEARCH_HOSTED_REDIRECT_URL];
|
656 |
+
return !is_null($siteKey) && !is_null($apiKey) &&
|
657 |
+
$hostedSearchConf && !$searchModConf &&
|
658 |
+
$hostedIntStatus == ChoiceAI_Searchcore_Helper_Constants::SEARCH_HOSTED_INT_COMPLETE &&
|
659 |
+
sizeof($hostedSearchRedirectUrl) > 0;
|
660 |
+
}
|
661 |
+
|
662 |
+
/**
|
663 |
+
* Method to get the hosted redirection url
|
664 |
+
* @return mixed
|
665 |
+
*/
|
666 |
+
public function getHostedRedirectUrl() {
|
667 |
+
$config = $this->getEngineConfigData(ChoiceAI_Searchcore_Helper_Constants::SEARCH_HOSTED_REDIRECT_URL);
|
668 |
+
return $config[ChoiceAI_Searchcore_Helper_Constants::SEARCH_HOSTED_REDIRECT_URL];
|
669 |
+
}
|
670 |
+
}
|
app/code/local/ChoiceAI/Search/Model/Catalog/Category.php
ADDED
@@ -0,0 +1,74 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Created by PhpStorm.
|
4 |
+
* User: harkirat
|
5 |
+
* Date: 12/5/17
|
6 |
+
* Time: 11:25 PM
|
7 |
+
*/
|
8 |
+
|
9 |
+
class ChoiceAI_Search_Model_Catalog_Category extends Mage_Catalog_Model_Category
|
10 |
+
{
|
11 |
+
const IS_ACTIVE = 'choiceai_personalisation/settings/active';
|
12 |
+
const CONFIG_KEY = 'choiceai_personalisation/settings/config';
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Retrieve Available Product Listing Sort By
|
16 |
+
* code as key, value - name
|
17 |
+
*
|
18 |
+
* @return array
|
19 |
+
*/
|
20 |
+
public function getAvailableSortByOptions()
|
21 |
+
{
|
22 |
+
$overtakeFlag = false;
|
23 |
+
|
24 |
+
// Check if URL in takeover list
|
25 |
+
$STORE_CONFIG = json_decode(Mage::getStoreConfig(self::CONFIG_KEY));
|
26 |
+
$sortbyObjs = $STORE_CONFIG->sortby;
|
27 |
+
|
28 |
+
// Getting URL Path
|
29 |
+
$currentReqPath = explode("?", $_SERVER['REQUEST_URI'])[0];
|
30 |
+
|
31 |
+
// Getting param keys in array var $paramPairs
|
32 |
+
parse_str($_SERVER['QUERY_STRING'], $paramPairs);
|
33 |
+
// Getting query keys
|
34 |
+
$currentReqParams = array();
|
35 |
+
if (count($paramPairs)) {
|
36 |
+
foreach ($paramPairs as $key => $paramPair)
|
37 |
+
$currentReqParams[] = $key;
|
38 |
+
}
|
39 |
+
|
40 |
+
// Refining URL path
|
41 |
+
// My own local installation case: localhost/magento/
|
42 |
+
if (strpos($currentReqPath, "/magento/") !== false)
|
43 |
+
$currentReqPath = str_replace("/magento/", "/", $currentReqPath);
|
44 |
+
|
45 |
+
// Making www.store.com/index.php/abcd => www.store.com/abcd
|
46 |
+
if (strpos($currentReqPath, "/index.php/") !== false)
|
47 |
+
$currentReqPath = str_replace("/index.php/", "/", $currentReqPath);
|
48 |
+
|
49 |
+
$isPluginActive = Mage::getStoreConfig(self::IS_ACTIVE)=='1';
|
50 |
+
// $isPluginActive = true;
|
51 |
+
|
52 |
+
if($isPluginActive) {
|
53 |
+
foreach ($sortbyObjs as $sortbyObj) {
|
54 |
+
if (isset($sortbyObj->rule->paths)) {
|
55 |
+
if (in_array($currentReqPath, $sortbyObj->rule->paths)) {
|
56 |
+
$overtakeFlag = true;
|
57 |
+
}
|
58 |
+
}
|
59 |
+
|
60 |
+
if (isset($sortbyObj->rule->params)) {
|
61 |
+
if (!empty(array_intersect($currentReqParams, $sortbyObj->rule->params))) {
|
62 |
+
$overtakeFlag = true;
|
63 |
+
}
|
64 |
+
}
|
65 |
+
}
|
66 |
+
}
|
67 |
+
|
68 |
+
if($overtakeFlag)
|
69 |
+
return Mage::getSingleton('catalog/config')->getAttributeUsedForSortByArray();
|
70 |
+
else
|
71 |
+
return parent::getAvailableSortByOptions();
|
72 |
+
|
73 |
+
}
|
74 |
+
}
|
app/code/local/ChoiceAI/Search/Model/Catalog/Config.php
ADDED
@@ -0,0 +1,120 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Overrides default layer model to handle custom product collection filtering.
|
4 |
+
*
|
5 |
+
* @package ChoiceAI_Search
|
6 |
+
* @copyright Copyright (c) MineWhat
|
7 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
*/
|
9 |
+
class ChoiceAI_Search_Model_Catalog_Config extends Mage_Catalog_Model_Config
|
10 |
+
{
|
11 |
+
const IS_ACTIVE = 'choiceai_personalisation/settings/active';
|
12 |
+
const CONFIG_KEY = 'choiceai_personalisation/settings/config';
|
13 |
+
|
14 |
+
public $options = NULL;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Retrieve Attributes Used for Sort by as array
|
18 |
+
* key = code, value = name
|
19 |
+
*
|
20 |
+
* Note by Harkirat: This function is called in both cases: product list and search.
|
21 |
+
*
|
22 |
+
* @return array
|
23 |
+
*/
|
24 |
+
public function getAttributeUsedForSortByArray()
|
25 |
+
{
|
26 |
+
try {
|
27 |
+
if(is_null($this->options)) {
|
28 |
+
// Check if URL in takeover list
|
29 |
+
$STORE_CONFIG = json_decode(Mage::getStoreConfig(self::CONFIG_KEY));
|
30 |
+
$sortbyObjs = $STORE_CONFIG->sortby;
|
31 |
+
|
32 |
+
// Getting URL Path
|
33 |
+
$currentReqPath = explode("?", $_SERVER['REQUEST_URI'])[0];
|
34 |
+
|
35 |
+
// Getting param keys in array var $paramPairs
|
36 |
+
parse_str($_SERVER['QUERY_STRING'], $paramPairs);
|
37 |
+
// Getting query keys
|
38 |
+
$currentReqParams = array();
|
39 |
+
if (count($paramPairs)) {
|
40 |
+
foreach ($paramPairs as $key => $paramPair)
|
41 |
+
$currentReqParams[] = $key;
|
42 |
+
}
|
43 |
+
|
44 |
+
// Refining URL path
|
45 |
+
// My own local installation case: localhost/magento/
|
46 |
+
if (strpos($currentReqPath, "/magento/") !== false)
|
47 |
+
$currentReqPath = str_replace("/magento/", "/", $currentReqPath);
|
48 |
+
|
49 |
+
// Making www.store.com/index.php/abcd => www.store.com/abcd
|
50 |
+
if (strpos($currentReqPath, "/index.php/") !== false)
|
51 |
+
$currentReqPath = str_replace("/index.php/", "/", $currentReqPath);
|
52 |
+
|
53 |
+
$isPluginActive = Mage::getStoreConfig(self::IS_ACTIVE) == '1';
|
54 |
+
// $isPluginActive = true;
|
55 |
+
|
56 |
+
if ($isPluginActive) {
|
57 |
+
foreach ($sortbyObjs as $sortbyObj) {
|
58 |
+
if (isset($sortbyObj->rule)) {
|
59 |
+
if (isset($sortbyObj->rule->paths)) {
|
60 |
+
if (in_array($currentReqPath, $sortbyObj->rule->paths)) {
|
61 |
+
$this->options = $this->getOptions($sortbyObj);
|
62 |
+
|
63 |
+
if (empty($this->options)) {
|
64 |
+
return parent::getAttributeUsedForSortByArray();
|
65 |
+
}
|
66 |
+
return $this->options;
|
67 |
+
}
|
68 |
+
}
|
69 |
+
|
70 |
+
if (isset($sortbyObj->rule->params)) {
|
71 |
+
if (!empty(array_intersect($currentReqParams, $sortbyObj->rule->params))) {
|
72 |
+
$this->options = $this->getOptions($sortbyObj);
|
73 |
+
|
74 |
+
if (empty($this->options)) {
|
75 |
+
return parent::getAttributeUsedForSortByArray();
|
76 |
+
}
|
77 |
+
return $this->options;
|
78 |
+
}
|
79 |
+
}
|
80 |
+
}
|
81 |
+
}
|
82 |
+
}
|
83 |
+
} else{
|
84 |
+
return $this->options;
|
85 |
+
}
|
86 |
+
|
87 |
+
$this->options = parent::getAttributeUsedForSortByArray();
|
88 |
+
return $this->options;
|
89 |
+
} catch (Exception $e){
|
90 |
+
return parent::getAttributeUsedForSortByArray();
|
91 |
+
}
|
92 |
+
}
|
93 |
+
|
94 |
+
private function getOptions($sortbyObj){
|
95 |
+
$options = array();
|
96 |
+
|
97 |
+
if(isset($sortbyObj->override)){
|
98 |
+
// Search case, override all system options with choice
|
99 |
+
$caiOptions = $sortbyObj->override;
|
100 |
+
|
101 |
+
foreach ($caiOptions as $key => $caiOption)
|
102 |
+
$options[$key] = Mage::helper('catalog')->__($caiOption);
|
103 |
+
} else if(isset($sortbyObj->extend)) {
|
104 |
+
// Product list page, add system options first, then add/replace ours
|
105 |
+
|
106 |
+
foreach ($this->getAttributesUsedForSortBy() as $attribute) {
|
107 |
+
/* @var $attribute Mage_Eav_Model_Entity_Attribute_Abstract */
|
108 |
+
$options[$attribute->getAttributeCode()] = $attribute->getStoreLabel();
|
109 |
+
}
|
110 |
+
|
111 |
+
// Default options added above, now adding our option/s, which can either override or be a new option
|
112 |
+
foreach ($sortbyObj->extend as $key=>$option)
|
113 |
+
$options[$key] = Mage::helper('catalog')->__($option);
|
114 |
+
|
115 |
+
$_SESSION['plist_sort_by'] = $key;
|
116 |
+
}
|
117 |
+
|
118 |
+
return $options;
|
119 |
+
}
|
120 |
+
}
|
app/code/local/ChoiceAI/Search/Model/Catalog/Layer.php
ADDED
@@ -0,0 +1,37 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Overrides default layer model to handle custom product collection filtering.
|
4 |
+
*
|
5 |
+
* @package ChoiceAI_Search
|
6 |
+
* @copyright Copyright (c) MineWhat
|
7 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
*/
|
9 |
+
class ChoiceAI_Search_Model_Catalog_Layer extends Mage_Catalog_Model_Layer
|
10 |
+
{
|
11 |
+
/**
|
12 |
+
* Returns product collection for current category.
|
13 |
+
*
|
14 |
+
* @return ChoiceAI_Search_Model_Resource_Catalog_Product_Collection
|
15 |
+
*/
|
16 |
+
public function getProductCollection()
|
17 |
+
{
|
18 |
+
/** @var $category Mage_Catalog_Model_Category */
|
19 |
+
$category = $this->getCurrentCategory();
|
20 |
+
/** @var $collection ChoiceAI_Search_Model_Resource_Catalog_Product_Collection */
|
21 |
+
if (isset($this->_productCollections[$category->getId()])) {
|
22 |
+
$collection = $this->_productCollections[$category->getId()];
|
23 |
+
} else {
|
24 |
+
$collection = Mage::getResourceModel('choiceai_search/engine_choiceaisearch')
|
25 |
+
->getResultCollection()
|
26 |
+
->setStoreId($category->getStoreId())
|
27 |
+
->addCategoryId($category->getId())
|
28 |
+
->setQueryType('browse')
|
29 |
+
->addFqFilter(array('store_id' => $category->getStoreId()));
|
30 |
+
|
31 |
+
$this->prepareProductCollection($collection);
|
32 |
+
$this->_productCollections[$category->getId()] = $collection;
|
33 |
+
}
|
34 |
+
|
35 |
+
return $collection;
|
36 |
+
}
|
37 |
+
}
|
app/code/local/ChoiceAI/Search/Model/Catalog/Layer/Filter/Attribute.php
ADDED
@@ -0,0 +1,168 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Handles attribute filtering in layered navigation.
|
4 |
+
*
|
5 |
+
* @package ChoiceAI_Search
|
6 |
+
* @copyright Copyright (c) MineWhat
|
7 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
*/
|
9 |
+
class ChoiceAI_Search_Model_Catalog_Layer_Filter_Attribute extends Mage_Catalog_Model_Layer_Filter_Attribute
|
10 |
+
{
|
11 |
+
const MULTI_SELECT_FACET_SPLIT = '_';
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Adds facet condition to product collection.
|
15 |
+
*
|
16 |
+
* @see ChoiceAI_Search_Model_Resource_Catalog_Product_Collection::addFacetCondition()
|
17 |
+
* @return ChoiceAI_Search_Model_Catalog_Layer_Filter_Attribute
|
18 |
+
*/
|
19 |
+
public function addFacetCondition()
|
20 |
+
{
|
21 |
+
$this->getLayer()
|
22 |
+
->getProductCollection()
|
23 |
+
->addFacetCondition($this->_getFilterField());
|
24 |
+
|
25 |
+
return $this;
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Retrieves request parameter and applies it to product collection.
|
30 |
+
*
|
31 |
+
* @param Zend_Controller_Request_Abstract $request
|
32 |
+
* @param Mage_Core_Block_Abstract $filterBlock
|
33 |
+
* @return ChoiceAI_Search_Model_Catalog_Layer_Filter_Attribute
|
34 |
+
*/
|
35 |
+
public function apply(Zend_Controller_Request_Abstract $request, $filterBlock)
|
36 |
+
{
|
37 |
+
$filter = $request->getParam($this->_requestVar);
|
38 |
+
if (is_array($filter) || null === $filter || strlen($filter) == 0) {
|
39 |
+
return $this;
|
40 |
+
}
|
41 |
+
$filterValues = explode(self::MULTI_SELECT_FACET_SPLIT, $filter);
|
42 |
+
$this->applyFilterToCollection($this, $filterValues);
|
43 |
+
foreach($filterValues as $eachFilterValue) {
|
44 |
+
$this->getLayer()->getState()->addFilter($this->_createItem($eachFilterValue, $eachFilterValue));
|
45 |
+
}
|
46 |
+
|
47 |
+
$this->_items = null;
|
48 |
+
|
49 |
+
return $this;
|
50 |
+
}
|
51 |
+
|
52 |
+
/**
|
53 |
+
* Applies filter to product collection.
|
54 |
+
*
|
55 |
+
* @param $filter
|
56 |
+
* @param $value
|
57 |
+
* @return ChoiceAI_Search_Model_Catalog_Layer_Filter_Attribute
|
58 |
+
*/
|
59 |
+
public function applyFilterToCollection($filter, $value)
|
60 |
+
{
|
61 |
+
if(!is_array($value)) {
|
62 |
+
return $this;
|
63 |
+
}
|
64 |
+
$attribute = $filter->getAttributeModel();
|
65 |
+
$param = Mage::helper('choiceai_search')->getSearchParam($attribute, $value);
|
66 |
+
|
67 |
+
$this->getLayer()
|
68 |
+
->getProductCollection()
|
69 |
+
->addSearchQfFilter($param);
|
70 |
+
|
71 |
+
return $this;
|
72 |
+
}
|
73 |
+
|
74 |
+
/**
|
75 |
+
* Returns facets data of current attribute.
|
76 |
+
*
|
77 |
+
* @return array
|
78 |
+
*/
|
79 |
+
protected function _getFacets()
|
80 |
+
{
|
81 |
+
/** @var $productCollection ChoiceAI_Search_Model_Resource_Catalog_Product_Collection */
|
82 |
+
$productCollection = $this->getLayer()->getProductCollection();
|
83 |
+
$fieldName = $this->_getFilterField();
|
84 |
+
$facets = $productCollection->getFacetedData($fieldName);
|
85 |
+
return $facets;
|
86 |
+
}
|
87 |
+
|
88 |
+
|
89 |
+
public function getMaxPriceInt()
|
90 |
+
{
|
91 |
+
$priceStat = Mage::getSingleton('choiceai_search/catalog_layer')->getProductCollection()->getStats('price');
|
92 |
+
$productCollection = $this->getLayer()->getProductCollection();
|
93 |
+
return isset($priceStat["max"])?$priceStat["max"]:0;
|
94 |
+
}
|
95 |
+
|
96 |
+
|
97 |
+
/**
|
98 |
+
* Returns attribute field name.
|
99 |
+
*
|
100 |
+
* @return string
|
101 |
+
*/
|
102 |
+
protected function _getFilterField()
|
103 |
+
{
|
104 |
+
/** @var $attribute Mage_Catalog_Model_Resource_Eav_Attribute */
|
105 |
+
$attribute = $this->getAttributeModel();
|
106 |
+
$fieldName = Mage::helper('choiceai_search')->getAttributeFieldName($attribute);
|
107 |
+
|
108 |
+
return $fieldName;
|
109 |
+
}
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Retrieves current items data.
|
113 |
+
*
|
114 |
+
* @return array
|
115 |
+
*/
|
116 |
+
protected function _getItemsData()
|
117 |
+
{
|
118 |
+
$filter = array_key_exists($this->_requestVar, $_REQUEST)?$_REQUEST[$this->_requestVar]: '';
|
119 |
+
$filterValues = explode(self::MULTI_SELECT_FACET_SPLIT, $filter);
|
120 |
+
/** @var $attribute Mage_Catalog_Model_Resource_Eav_Attribute */
|
121 |
+
$attribute = $this->getAttributeModel();
|
122 |
+
$this->_requestVar = $attribute->getAttributeCode();
|
123 |
+
$facets = $this->_getFacets();
|
124 |
+
$data = array();
|
125 |
+
|
126 |
+
if (array_sum($facets) > 0) {
|
127 |
+
foreach ($facets as $label => $count) {
|
128 |
+
$isSelected = in_array($label, $filterValues);
|
129 |
+
if (!$count && $this->_getIsFilterableAttribute($attribute) == self::OPTIONS_ONLY_WITH_RESULTS) {
|
130 |
+
continue;
|
131 |
+
}
|
132 |
+
$data[] = array(
|
133 |
+
'label' => $label,
|
134 |
+
'value' => $label,
|
135 |
+
'count' => $count,
|
136 |
+
);
|
137 |
+
}
|
138 |
+
}
|
139 |
+
|
140 |
+
return $data;
|
141 |
+
}
|
142 |
+
|
143 |
+
/**
|
144 |
+
* Returns option label if attribute uses options.
|
145 |
+
*
|
146 |
+
* @param int $optionId
|
147 |
+
* @return bool|int|string
|
148 |
+
*/
|
149 |
+
protected function _getOptionText($optionId)
|
150 |
+
{
|
151 |
+
if ($this->getAttributeModel()->getFrontendInput() == 'text') {
|
152 |
+
return $optionId; // not an option id
|
153 |
+
}
|
154 |
+
|
155 |
+
return parent::_getOptionText($optionId);
|
156 |
+
}
|
157 |
+
|
158 |
+
/**
|
159 |
+
* Checks if given filter is valid before being applied to product collection.
|
160 |
+
*
|
161 |
+
* @param string $filter
|
162 |
+
* @return bool
|
163 |
+
*/
|
164 |
+
protected function _isValidFilter($filter)
|
165 |
+
{
|
166 |
+
return !empty($filter);
|
167 |
+
}
|
168 |
+
}
|
app/code/local/ChoiceAI/Search/Model/Catalog/Layer/Filter/Boolean.php
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Handles boolean attribute filtering in layered navigation.
|
4 |
+
*
|
5 |
+
* @package ChoiceAI_Search
|
6 |
+
* @copyright Copyright (c) MineWhat
|
7 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
*/
|
9 |
+
class ChoiceAI_Search_Model_Catalog_Layer_Filter_Boolean extends ChoiceAI_Search_Model_Catalog_Layer_Filter_Attribute
|
10 |
+
{
|
11 |
+
/**
|
12 |
+
* Returns facets data of current attribute.
|
13 |
+
*
|
14 |
+
* @return array
|
15 |
+
*/
|
16 |
+
protected function _getFacets()
|
17 |
+
{
|
18 |
+
$facets = parent::_getFacets();
|
19 |
+
$result = array();
|
20 |
+
foreach ($facets as $value => $count) {
|
21 |
+
$key = 0; // false by default
|
22 |
+
if ($value === 'true' || $value === 'T' || $value === '1' || $value === 1 || $value === true) {
|
23 |
+
$key = 1;
|
24 |
+
}
|
25 |
+
$result[$key] = $count;
|
26 |
+
}
|
27 |
+
|
28 |
+
return $result;
|
29 |
+
}
|
30 |
+
|
31 |
+
/**
|
32 |
+
* Checks if given filter is valid before being applied to product collection.
|
33 |
+
*
|
34 |
+
* @param string $filter
|
35 |
+
* @return bool
|
36 |
+
*/
|
37 |
+
protected function _isValidFilter($filter)
|
38 |
+
{
|
39 |
+
return $filter === '0' || $filter === '1' || false === $filter || true === $filter;
|
40 |
+
}
|
41 |
+
}
|
app/code/local/ChoiceAI/Search/Model/Catalog/Layer/Filter/Category.php
ADDED
@@ -0,0 +1,132 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Handles category filtering in layered navigation.
|
4 |
+
*
|
5 |
+
* @package ChoiceAI_Search
|
6 |
+
* @copyright Copyright (c) MineWhat
|
7 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
*/
|
9 |
+
class ChoiceAI_Search_Model_Catalog_Layer_Filter_Category extends Mage_Catalog_Model_Layer_Filter_Category
|
10 |
+
{
|
11 |
+
/**
|
12 |
+
* Adds category filter to product collection.
|
13 |
+
*
|
14 |
+
* @param Mage_Catalog_Model_Category $category
|
15 |
+
* @return ChoiceAI_Search_Model_Catalog_Layer_Filter_Category
|
16 |
+
*/
|
17 |
+
public function addCategoryFilter($category)
|
18 |
+
{
|
19 |
+
$value = array(
|
20 |
+
'categories' => $category->getId()
|
21 |
+
);
|
22 |
+
$this->getLayer()->getProductCollection()
|
23 |
+
->addFqFilter($value);
|
24 |
+
|
25 |
+
return $this;
|
26 |
+
}
|
27 |
+
|
28 |
+
/**
|
29 |
+
* Adds facet condition to product collection.
|
30 |
+
*
|
31 |
+
* @see ChoiceAI_Search_Model_Resource_Catalog_Product_Collection::addFacetCondition()
|
32 |
+
* @return ChoiceAI_Search_Model_Catalog_Layer_Filter_Category
|
33 |
+
*/
|
34 |
+
public function addFacetCondition()
|
35 |
+
{
|
36 |
+
/** @var $category Mage_Catalog_Model_Category */
|
37 |
+
$category = $this->getCategory();
|
38 |
+
$childrenCategories = $category->getChildrenCategories();
|
39 |
+
|
40 |
+
$useFlat = (bool) Mage::getStoreConfig('catalog/frontend/flat_catalog_category');
|
41 |
+
$categories = ($useFlat)
|
42 |
+
? array_keys($childrenCategories)
|
43 |
+
: array_keys($childrenCategories->toArray());
|
44 |
+
|
45 |
+
$this->getLayer()->getProductCollection()->addFacetCondition('categories', $categories);
|
46 |
+
|
47 |
+
return $this;
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* Applies filter to product collection.
|
52 |
+
*
|
53 |
+
* @param $filter
|
54 |
+
* @param $value
|
55 |
+
* @return ChoiceAI_Search_Model_Catalog_Layer_Filter_Attribute
|
56 |
+
*/
|
57 |
+
public function applyFilterToCollection($filter, $value)
|
58 |
+
{
|
59 |
+
|
60 |
+
$param = array("category" => array($value));
|
61 |
+
$this->getLayer()
|
62 |
+
->getProductCollection()
|
63 |
+
->addSearchQfFilter($param);
|
64 |
+
|
65 |
+
return $this;
|
66 |
+
}
|
67 |
+
|
68 |
+
/**
|
69 |
+
* Retrieves request parameter and applies it to product collection.
|
70 |
+
*
|
71 |
+
* @param Zend_Controller_Request_Abstract $request
|
72 |
+
* @param Mage_Core_Block_Abstract $filterBlock
|
73 |
+
* @return ChoiceAI_Search_Model_Catalog_Layer_Filter_Category
|
74 |
+
*/
|
75 |
+
public function apply(Zend_Controller_Request_Abstract $request, $filterBlock)
|
76 |
+
{
|
77 |
+
$filter = $request->getParam($this->getRequestVar());
|
78 |
+
if (is_null($filter) || $filter == "") {
|
79 |
+
return $this;
|
80 |
+
}
|
81 |
+
$this->applyFilterToCollection($this, $filter);
|
82 |
+
$this->getLayer()->getState()->addFilter($this->_createItem($filter, $filter));
|
83 |
+
$this->_items = null;
|
84 |
+
return $this;
|
85 |
+
}
|
86 |
+
|
87 |
+
/**
|
88 |
+
* Retrieves current items data.
|
89 |
+
*
|
90 |
+
* @return array
|
91 |
+
*/
|
92 |
+
protected function _getItemsData()
|
93 |
+
{
|
94 |
+
$layer = $this->getLayer();
|
95 |
+
/** @var $productCollection ChoiceAI_Search_Model_Resource_Catalog_Product_Collection */
|
96 |
+
$productCollection = $layer->getProductCollection();
|
97 |
+
$facets = $productCollection->getFacetedData('category');
|
98 |
+
$data = array();
|
99 |
+
if (array_sum($facets) > 0) {
|
100 |
+
$options = array();
|
101 |
+
foreach ($facets as $label => $count) {
|
102 |
+
$options[] = array(
|
103 |
+
'label' => $label,
|
104 |
+
'value' => $label,
|
105 |
+
'count' => $count,
|
106 |
+
);
|
107 |
+
}
|
108 |
+
// }
|
109 |
+
foreach ($options as $option) {
|
110 |
+
if (is_array($option['value']) || !Mage::helper('core/string')->strlen($option['value'])) {
|
111 |
+
continue;
|
112 |
+
}
|
113 |
+
$count = 0;
|
114 |
+
$label = $option['label'];
|
115 |
+
if (isset($facets[$option['value']])) {
|
116 |
+
$count = (int) $facets[$option['value']];
|
117 |
+
}
|
118 |
+
if (!$count && $this->_getIsFilterableAttribute($attribute) == self::OPTIONS_ONLY_WITH_RESULTS) {
|
119 |
+
continue;
|
120 |
+
}
|
121 |
+
$data[] = array(
|
122 |
+
'label' => $label,
|
123 |
+
'value' => $option['value'],
|
124 |
+
'count' => (int) $count,
|
125 |
+
);
|
126 |
+
}
|
127 |
+
|
128 |
+
}
|
129 |
+
|
130 |
+
return $data;
|
131 |
+
}
|
132 |
+
}
|
app/code/local/ChoiceAI/Search/Model/Catalog/Layer/Filter/Decimal.php
ADDED
@@ -0,0 +1,190 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Handles decimal attribute filtering in layered navigation.
|
4 |
+
*
|
5 |
+
* @package ChoiceAI_Search
|
6 |
+
* @copyright Copyright (c) MineWhat
|
7 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
*/
|
9 |
+
class ChoiceAI_Search_Model_Catalog_Layer_Filter_Decimal extends Mage_Catalog_Model_Layer_Filter_Decimal
|
10 |
+
{
|
11 |
+
const CACHE_TAG = 'MAXVALUE';
|
12 |
+
|
13 |
+
/**
|
14 |
+
* Adds facet condition to product collection.
|
15 |
+
*
|
16 |
+
* @see ChoiceAI_Search_Model_Resource_Catalog_Product_Collection::addFacetCondition()
|
17 |
+
* @return ChoiceAI_Search_Model_Catalog_Layer_Filter_Decimal
|
18 |
+
*/
|
19 |
+
public function addFacetCondition()
|
20 |
+
{
|
21 |
+
$range = $this->getRange();
|
22 |
+
$maxValue = $this->getMaxValue();
|
23 |
+
if ($maxValue > 0) {
|
24 |
+
$facets = array();
|
25 |
+
$facetCount = (int) ceil($maxValue / $range);
|
26 |
+
|
27 |
+
for ($i = 0; $i < $facetCount + 1; $i++) {
|
28 |
+
$facets[] = array(
|
29 |
+
'from' => $i * $range,
|
30 |
+
'to' => ($i + 1) * $range,
|
31 |
+
'include_upper' => !($i < $facetCount)
|
32 |
+
);
|
33 |
+
}
|
34 |
+
|
35 |
+
$fieldName = $this->_getFilterField();
|
36 |
+
$this->getLayer()->getProductCollection()->addFacetCondition($fieldName, $facets);
|
37 |
+
}
|
38 |
+
|
39 |
+
return $this;
|
40 |
+
}
|
41 |
+
|
42 |
+
/**
|
43 |
+
* Retrieves request parameter and applies it to product collection.
|
44 |
+
*
|
45 |
+
* @param Zend_Controller_Request_Abstract $request
|
46 |
+
* @param Mage_Core_Block_Abstract $filterBlock
|
47 |
+
* @return ChoiceAI_Search_Model_Catalog_Layer_Filter_Decimal
|
48 |
+
*/
|
49 |
+
public function apply(Zend_Controller_Request_Abstract $request, $filterBlock)
|
50 |
+
{
|
51 |
+
$filter = $request->getParam($this->getRequestVar());
|
52 |
+
if (!$filter) {
|
53 |
+
return $this;
|
54 |
+
}
|
55 |
+
|
56 |
+
$filter = explode(',', $filter);
|
57 |
+
if (count($filter) != 2) {
|
58 |
+
return $this;
|
59 |
+
}
|
60 |
+
|
61 |
+
list($index, $range) = $filter;
|
62 |
+
|
63 |
+
if ((int) $index && (int) $range) {
|
64 |
+
$this->setRange((int) $range);
|
65 |
+
|
66 |
+
$this->applyFilterToCollection($this, $range, $index);
|
67 |
+
$this->getLayer()->getState()->addFilter(
|
68 |
+
$this->_createItem($this->_renderItemLabel($range, $index), $filter)
|
69 |
+
);
|
70 |
+
|
71 |
+
$this->_items = array();
|
72 |
+
}
|
73 |
+
|
74 |
+
return $this;
|
75 |
+
}
|
76 |
+
|
77 |
+
/**
|
78 |
+
* Apply decimal filter range to product collection.
|
79 |
+
*
|
80 |
+
* @param ChoiceAI_Search_Model_Catalog_Layer_Filter_Decimal $filter
|
81 |
+
* @param int $range
|
82 |
+
* @param int $index
|
83 |
+
* @return ChoiceAI_Search_Model_Catalog_Layer_Filter_Decimal
|
84 |
+
*/
|
85 |
+
public function applyFilterToCollection($filter, $range, $index)
|
86 |
+
{
|
87 |
+
$value = array(
|
88 |
+
$this->_getFilterField() => array(
|
89 |
+
'from' => ($range * ($index - 1)),
|
90 |
+
'to' => $range * $index,
|
91 |
+
)
|
92 |
+
);
|
93 |
+
$filter->getLayer()->getProductCollection()->addFqFilter($value);
|
94 |
+
|
95 |
+
return $this;
|
96 |
+
}
|
97 |
+
|
98 |
+
public function getMaxValue()
|
99 |
+
{
|
100 |
+
$searchParams = $this->getLayer()->getProductCollection()->getExtendedSearchParams();
|
101 |
+
$uniquePart = strtoupper(md5(serialize($searchParams)));
|
102 |
+
$cacheKey = 'MAXVALUE_' . $this->getLayer()->getStateKey() . '_' . $uniquePart;
|
103 |
+
|
104 |
+
$cachedData = Mage::app()->loadCache($cacheKey);
|
105 |
+
if (!$cachedData) {
|
106 |
+
$stats = $this->getLayer()->getProductCollection()->getStats($this->_getFilterField());
|
107 |
+
|
108 |
+
$max = $stats[$this->_getFilterField()]['max'];
|
109 |
+
if (!is_numeric($max)) {
|
110 |
+
$max = parent::getMaxValue();
|
111 |
+
}
|
112 |
+
|
113 |
+
$cachedData = (float) $max;
|
114 |
+
$tags = $this->getLayer()->getStateTags();
|
115 |
+
$tags[] = self::CACHE_TAG;
|
116 |
+
Mage::app()->saveCache($cachedData, $cacheKey, $tags);
|
117 |
+
}
|
118 |
+
|
119 |
+
return $cachedData;
|
120 |
+
}
|
121 |
+
|
122 |
+
/**
|
123 |
+
* Returns decimal field name.
|
124 |
+
*
|
125 |
+
* @return string
|
126 |
+
*/
|
127 |
+
protected function _getFilterField()
|
128 |
+
{
|
129 |
+
$fieldName = Mage::helper('choiceai_search')->getAttributeFieldName($this->getAttributeModel());
|
130 |
+
|
131 |
+
return $fieldName;
|
132 |
+
}
|
133 |
+
|
134 |
+
/**
|
135 |
+
* Retrieves current items data.
|
136 |
+
*
|
137 |
+
* @return array
|
138 |
+
*/
|
139 |
+
protected function _getItemsData()
|
140 |
+
{
|
141 |
+
$range = $this->getRange();
|
142 |
+
$fieldName = $this->_getFilterField();
|
143 |
+
$facets = $this->getLayer()->getProductCollection()->getFacetedData($fieldName);
|
144 |
+
|
145 |
+
$data = array();
|
146 |
+
if (!empty($facets)) {
|
147 |
+
foreach ($facets as $key => $count) {
|
148 |
+
if ($count > 0) {
|
149 |
+
preg_match('/TO ([\d\.]+)\]$/', $key, $rangeKey);
|
150 |
+
$rangeKey = round($rangeKey[1] / $range);
|
151 |
+
$data[] = array(
|
152 |
+
'label' => $this->_renderItemLabel($range, $rangeKey),
|
153 |
+
'value' => $rangeKey . ',' . $range,
|
154 |
+
'count' => $count,
|
155 |
+
);
|
156 |
+
}
|
157 |
+
}
|
158 |
+
}
|
159 |
+
|
160 |
+
return $data;
|
161 |
+
}
|
162 |
+
|
163 |
+
/**
|
164 |
+
* Renders decimal ranges.
|
165 |
+
*
|
166 |
+
* @param int $range
|
167 |
+
* @param float $value
|
168 |
+
* @return string
|
169 |
+
*/
|
170 |
+
protected function _renderItemLabel($range, $value)
|
171 |
+
{
|
172 |
+
/** @var $attribute Mage_Catalog_Model_Resource_Eav_Attribute */
|
173 |
+
$attribute = $this->getAttributeModel();
|
174 |
+
|
175 |
+
if ($attribute->getFrontendInput() == 'price') {
|
176 |
+
return parent::_renderItemLabel($range, $value);
|
177 |
+
}
|
178 |
+
|
179 |
+
$from = ($value - 1) * $range;
|
180 |
+
$to = $value * $range;
|
181 |
+
|
182 |
+
if ($from != $to) {
|
183 |
+
$to -= 0.01;
|
184 |
+
}
|
185 |
+
|
186 |
+
$to = Zend_Locale_Format::toFloat($to, array('locale' => Mage::helper('choiceai_search')->getLocaleCode()));
|
187 |
+
|
188 |
+
return Mage::helper('catalog')->__('%s - %s', $from, $to);
|
189 |
+
}
|
190 |
+
}
|
app/code/local/ChoiceAI/Search/Model/Catalog/Layer/Filter/Price.php
ADDED
@@ -0,0 +1,154 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Handles price filtering in layered navigation.
|
4 |
+
*
|
5 |
+
* @package ChoiceAI_Search
|
6 |
+
* @copyright Copyright (c) MineWhat
|
7 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
*/
|
9 |
+
class ChoiceAI_Search_Model_Catalog_Layer_Filter_Price extends Mage_Catalog_Model_Layer_Filter_Price
|
10 |
+
{
|
11 |
+
const CACHE_TAG = 'MAXPRICE';
|
12 |
+
|
13 |
+
const DELIMITER = '-';
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Returns cache tag.
|
17 |
+
*
|
18 |
+
* @return string
|
19 |
+
*/
|
20 |
+
public function getCacheTag()
|
21 |
+
{
|
22 |
+
return self::CACHE_TAG;
|
23 |
+
}
|
24 |
+
|
25 |
+
/**
|
26 |
+
* Retrieves max price for ranges definition.
|
27 |
+
*
|
28 |
+
* @return float
|
29 |
+
*/
|
30 |
+
public function getMaxPriceMod()
|
31 |
+
{
|
32 |
+
$priceStat = Mage::getSingleton('choiceai_search/catalog_layer')->getProductCollection()->getStats('price');
|
33 |
+
$productCollection = $this->getLayer()->getProductCollection();
|
34 |
+
return isset($priceStat["max"])?(int)$priceStat["max"]:0;
|
35 |
+
}
|
36 |
+
|
37 |
+
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Retrieves min price for ranges definition.
|
41 |
+
*
|
42 |
+
* @return float
|
43 |
+
*/
|
44 |
+
public function getMinPriceMod()
|
45 |
+
{
|
46 |
+
$priceStat = Mage::getSingleton('choiceai_search/catalog_layer')->getProductCollection()->getStats('price');
|
47 |
+
$productCollection = $this->getLayer()->getProductCollection();
|
48 |
+
return isset($priceStat["min"])?(int)$priceStat["min"]:0;
|
49 |
+
}
|
50 |
+
|
51 |
+
/**
|
52 |
+
* Returns price field according to current customer group and website.
|
53 |
+
*
|
54 |
+
* @return string
|
55 |
+
*/
|
56 |
+
protected function _getFilterField()
|
57 |
+
{
|
58 |
+
$websiteId = Mage::app()->getStore()->getWebsiteId();
|
59 |
+
$customerGroupId = Mage::getSingleton('customer/session')->getCustomerGroupId();
|
60 |
+
$priceField = 'price' ;
|
61 |
+
|
62 |
+
return $priceField;
|
63 |
+
}
|
64 |
+
|
65 |
+
/**
|
66 |
+
* Retrieves current items data.
|
67 |
+
*
|
68 |
+
* @return array
|
69 |
+
*/
|
70 |
+
protected function _getItemsData()
|
71 |
+
{
|
72 |
+
// if (Mage::app()->getStore()->getConfig(self::XML_PATH_RANGE_CALCULATION) == self::RANGE_CALCULATION_IMPROVED) {
|
73 |
+
// return $this->_getCalculatedItemsData();}
|
74 |
+
if ($this->getInterval()) {
|
75 |
+
return array();
|
76 |
+
}
|
77 |
+
|
78 |
+
$data = array();
|
79 |
+
$facets = $this->getLayer()->getProductCollection()->getFacetedData($this->_getFilterField());
|
80 |
+
if (!empty($facets)) {
|
81 |
+
foreach ($facets as $key => $count) {
|
82 |
+
if (!$count) {
|
83 |
+
unset($facets[$key]);
|
84 |
+
}
|
85 |
+
}
|
86 |
+
$i = 0;
|
87 |
+
foreach ($facets as $key => $count) {
|
88 |
+
$i++;
|
89 |
+
preg_match('/^\[(\d*) TO (\d*)\]$/', $key, $rangeKey);
|
90 |
+
$fromPrice = $rangeKey[1];
|
91 |
+
$toPrice = $rangeKey[2];
|
92 |
+
$data[] = array(
|
93 |
+
'label' => $this->_renderRangeLabel($fromPrice, $toPrice),
|
94 |
+
'value' => $fromPrice . self::DELIMITER . $toPrice,
|
95 |
+
'count' => $count
|
96 |
+
);
|
97 |
+
}
|
98 |
+
}
|
99 |
+
|
100 |
+
return $data;
|
101 |
+
}
|
102 |
+
|
103 |
+
|
104 |
+
/**
|
105 |
+
* Adds facet condition to product collection.
|
106 |
+
*
|
107 |
+
* @see ChoiceAI_Search_Model_Resource_Catalog_Product_Collection::addFacetCondition()
|
108 |
+
* @return ChoiceAI_Search_Model_Catalog_Layer_Filter_Attribute
|
109 |
+
*/
|
110 |
+
public function addFacetCondition()
|
111 |
+
{
|
112 |
+
$this->getLayer()
|
113 |
+
->getProductCollection()
|
114 |
+
->addFacetCondition($this->_getFilterField());
|
115 |
+
|
116 |
+
return $this;
|
117 |
+
}
|
118 |
+
|
119 |
+
|
120 |
+
public function apply(Zend_Controller_Request_Abstract $request, $filterBlock){
|
121 |
+
|
122 |
+
$filter = $request->getParam($this->_requestVar);
|
123 |
+
if(null == $filter){
|
124 |
+
return $this;
|
125 |
+
}
|
126 |
+
$filter =explode(self::DELIMITER, $filter);
|
127 |
+
if (!is_array($filter) || null === $filter || sizeof($filter)<2 ) {
|
128 |
+
return $this;
|
129 |
+
}
|
130 |
+
$this->applyFilterToCollection($this, $filter);
|
131 |
+
$this->_items = null;
|
132 |
+
return $this;
|
133 |
+
}
|
134 |
+
|
135 |
+
|
136 |
+
function applyFilterToCollection($filter,$filterValue){
|
137 |
+
$field = $this->_getFilterField();
|
138 |
+
$value = array(
|
139 |
+
$field => array(
|
140 |
+
'include_upper' => 0
|
141 |
+
)
|
142 |
+
);
|
143 |
+
|
144 |
+
if($filterValue[0]< $filterValue[1]){
|
145 |
+
$value[$field]['from'] = $filterValue[0];
|
146 |
+
$value[$field]['to'] = $filterValue[1];
|
147 |
+
}else{
|
148 |
+
$value[$field]['from'] = $filterValue[1];
|
149 |
+
$value[$field]['to'] = $filterValue[0];
|
150 |
+
}
|
151 |
+
$this->getLayer()->getProductCollection()->addSearchQfFilter($value);
|
152 |
+
return $this;
|
153 |
+
}
|
154 |
+
}
|
app/code/local/ChoiceAI/Search/Model/Catalogsearch/Layer.php
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
*
|
5 |
+
* @package ChoiceAI_Search
|
6 |
+
* @copyright Copyright (c) MineWhat
|
7 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
*/
|
9 |
+
|
10 |
+
class ChoiceAI_Search_Model_Catalogsearch_Layer extends Mage_CatalogSearch_Model_Layer
|
11 |
+
{
|
12 |
+
public function getProductCollection()
|
13 |
+
{
|
14 |
+
$category = $this->getCurrentCategory();
|
15 |
+
if (isset($this->_productCollections[$category->getId()])) {
|
16 |
+
$collection = $this->_productCollections[$category->getId()];
|
17 |
+
} else {
|
18 |
+
/** @var $collection ChoiceAI_Search_Model_Resource_Catalog_Product_Collection */
|
19 |
+
$collection = Mage::getResourceModel('choiceai_search/engine_choiceaisearch')
|
20 |
+
//->getEngine()
|
21 |
+
->getResultCollection()
|
22 |
+
->setStoreId($category->getStoreId())
|
23 |
+
->setQueryType('search')
|
24 |
+
->addFqFilter(array('store_id' => $category->getStoreId()));
|
25 |
+
$this->prepareProductCollection($collection);
|
26 |
+
$this->_productCollections[$category->getId()] = $collection;
|
27 |
+
}
|
28 |
+
|
29 |
+
return $collection;
|
30 |
+
}
|
31 |
+
}
|
app/code/local/ChoiceAI/Search/Model/Catalogsearch/Layer/Filter/Attribute.php
ADDED
@@ -0,0 +1,16 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
*
|
5 |
+
* @package ChoiceAI_Search
|
6 |
+
* @copyright Copyright (c) MineWhat
|
7 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
*/
|
9 |
+
|
10 |
+
class ChoiceAI_Search_Model_Catalogsearch_Layer_Filter_Attribute extends ChoiceAI_Search_Model_Catalog_Layer_Filter_Attribute
|
11 |
+
{
|
12 |
+
protected function _getIsFilterableAttribute($attribute)
|
13 |
+
{
|
14 |
+
return $attribute->getIsFilterableInSearch();
|
15 |
+
}
|
16 |
+
}
|
app/code/local/ChoiceAI/Search/Model/Resource/Catalog/Product/Collection.php
ADDED
@@ -0,0 +1,368 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* Custom catalog product collection model.
|
4 |
+
*
|
5 |
+
* @package ChoiceAI_Search
|
6 |
+
* @copyright Copyright (c) MineWhat
|
7 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
*/
|
9 |
+
class ChoiceAI_Search_Model_Resource_Catalog_Product_Collection extends Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection
|
10 |
+
{
|
11 |
+
/**
|
12 |
+
* @var ChoiceAI_Search_Model_Resource_Engine_Abstract Search engine.
|
13 |
+
*/
|
14 |
+
protected $_engine;
|
15 |
+
|
16 |
+
/**
|
17 |
+
* @var array Faceted data.
|
18 |
+
*/
|
19 |
+
protected $_facetedData = array();
|
20 |
+
|
21 |
+
/**
|
22 |
+
* @var array Facets conditions.
|
23 |
+
*/
|
24 |
+
protected $_facetsConditions = array();
|
25 |
+
|
26 |
+
/**
|
27 |
+
* @var array General default query.
|
28 |
+
*/
|
29 |
+
protected $_generalDefaultQuery = array('*' => '*');
|
30 |
+
|
31 |
+
/**
|
32 |
+
* @var string Search query text.
|
33 |
+
*/
|
34 |
+
protected $_searchQueryText = '';
|
35 |
+
|
36 |
+
/**
|
37 |
+
* @var array Search query filters.
|
38 |
+
*/
|
39 |
+
protected $_searchQueryFilters = array();
|
40 |
+
|
41 |
+
protected $_searchCategoryFilters =array();
|
42 |
+
|
43 |
+
/**
|
44 |
+
* @var array Search query range filters.
|
45 |
+
*/
|
46 |
+
protected $_searchQueryRangeFilters = array();
|
47 |
+
|
48 |
+
/**
|
49 |
+
* @var array Search entity ids.
|
50 |
+
*/
|
51 |
+
protected $_searchedEntityIds = array();
|
52 |
+
|
53 |
+
/**
|
54 |
+
* @var array Sort by definition.
|
55 |
+
*/
|
56 |
+
protected $_sortBy = array();
|
57 |
+
|
58 |
+
protected $qt = 'search';
|
59 |
+
|
60 |
+
protected $stats =array();
|
61 |
+
|
62 |
+
/**
|
63 |
+
* Adds facet condition to current collection.
|
64 |
+
*
|
65 |
+
* @param string $field
|
66 |
+
* @param mixed $condition
|
67 |
+
* @return ChoiceAI_Search_Model_Resource_Catalog_Product_Collection
|
68 |
+
*/
|
69 |
+
public function addFacetCondition($field, $condition = null)
|
70 |
+
{
|
71 |
+
if (array_key_exists($field, $this->_facetsConditions)) {
|
72 |
+
if (!empty($this->_facetsConditions[$field])){
|
73 |
+
$this->_facetsConditions[$field] = array($this->_facetsConditions[$field]);
|
74 |
+
}
|
75 |
+
$this->_facetsConditions[$field][] = $condition;
|
76 |
+
} else {
|
77 |
+
$this->_facetsConditions[$field] = $condition;
|
78 |
+
}
|
79 |
+
|
80 |
+
return $this;
|
81 |
+
}
|
82 |
+
|
83 |
+
/**
|
84 |
+
* Stores filter query.
|
85 |
+
*
|
86 |
+
* @param array $params
|
87 |
+
* @return ChoiceAI_Search_Model_Resource_Catalog_Product_Collection
|
88 |
+
*/
|
89 |
+
public function addFqFilter($params)
|
90 |
+
{
|
91 |
+
if (is_array($params)) {
|
92 |
+
foreach ($params as $field => $value) {
|
93 |
+
$this->_searchQueryFilters[$field] = $value;
|
94 |
+
}
|
95 |
+
}
|
96 |
+
|
97 |
+
return $this;
|
98 |
+
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Stores filter query.
|
102 |
+
*
|
103 |
+
* @param array $params
|
104 |
+
* @return ChoiceAI_Search_Model_Resource_Catalog_Product_Collection
|
105 |
+
*/
|
106 |
+
public function addCategoryId($id)
|
107 |
+
{
|
108 |
+
$this->_searchCategoryFilters = $id;
|
109 |
+
|
110 |
+
return $this;
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* setting the query type
|
115 |
+
*/
|
116 |
+
public function setQueryType($qt = 'search'){
|
117 |
+
$this->qt = $qt;
|
118 |
+
return $this;
|
119 |
+
}
|
120 |
+
|
121 |
+
/**
|
122 |
+
* Stores range filter query.
|
123 |
+
*
|
124 |
+
* @param array $params
|
125 |
+
* @return ChoiceAI_Search_Model_Resource_Catalog_Product_Collection
|
126 |
+
*/
|
127 |
+
public function addFqRangeFilter($params)
|
128 |
+
{
|
129 |
+
if (is_array($params)) {
|
130 |
+
foreach ($params as $field => $value) {
|
131 |
+
$this->_searchQueryRangeFilters[$field] = $value;
|
132 |
+
}
|
133 |
+
}
|
134 |
+
|
135 |
+
return $this;
|
136 |
+
}
|
137 |
+
|
138 |
+
/**
|
139 |
+
* Stores query text filter.
|
140 |
+
*
|
141 |
+
* @param $query
|
142 |
+
* @return ChoiceAI_Search_Model_Resource_Catalog_Product_Collection
|
143 |
+
*/
|
144 |
+
public function addSearchFilter($query)
|
145 |
+
{
|
146 |
+
$this->_searchQueryText = $query;
|
147 |
+
|
148 |
+
return $this;
|
149 |
+
}
|
150 |
+
|
151 |
+
/**
|
152 |
+
* Stores search query filter.
|
153 |
+
*
|
154 |
+
* @param mixed $param
|
155 |
+
* @param null $value
|
156 |
+
* @return ChoiceAI_Search_Model_Resource_Catalog_Product_Collection
|
157 |
+
*/
|
158 |
+
public function addSearchQfFilter($param, $value = null)
|
159 |
+
{
|
160 |
+
if (is_array($param)) {
|
161 |
+
foreach ($param as $field => $value) {
|
162 |
+
$this->addSearchQfFilter($field, $value);
|
163 |
+
}
|
164 |
+
} elseif (isset($value)) {
|
165 |
+
if (isset($this->_searchQueryFilters[$param]) && !is_array($this->_searchQueryFilters[$param])) {
|
166 |
+
$this->_searchQueryFilters[$param] = array($this->_searchQueryFilters[$param]);
|
167 |
+
$this->_searchQueryFilters[$param][] = $value;
|
168 |
+
} else {
|
169 |
+
$this->_searchQueryFilters[$param] = $value;
|
170 |
+
}
|
171 |
+
}
|
172 |
+
|
173 |
+
return $this;
|
174 |
+
}
|
175 |
+
|
176 |
+
/**
|
177 |
+
* Aggregates search query filters.
|
178 |
+
*
|
179 |
+
* @return array
|
180 |
+
*/
|
181 |
+
public function getExtendedSearchParams()
|
182 |
+
{
|
183 |
+
$result = $this->_searchQueryFilters;
|
184 |
+
$result['query_text'] = $this->_searchQueryText;
|
185 |
+
|
186 |
+
return $result;
|
187 |
+
}
|
188 |
+
|
189 |
+
/**
|
190 |
+
* Returns faceted data.
|
191 |
+
*
|
192 |
+
* @param string $field
|
193 |
+
* @return array
|
194 |
+
*/
|
195 |
+
public function getFacetedData($field)
|
196 |
+
{
|
197 |
+
|
198 |
+
if (array_key_exists($field, $this->_facetedData)) {
|
199 |
+
return $this->_facetedData[$field];
|
200 |
+
}
|
201 |
+
|
202 |
+
return array();
|
203 |
+
}
|
204 |
+
|
205 |
+
/**
|
206 |
+
* Returns collection size.
|
207 |
+
*
|
208 |
+
* @return int
|
209 |
+
*/
|
210 |
+
public function getSize()
|
211 |
+
{
|
212 |
+
if (is_null($this->_totalRecords)) {
|
213 |
+
$query = $this->_getQuery();
|
214 |
+
$params = $this->_getParams();
|
215 |
+
$params['limit'] = 1;
|
216 |
+
//$this->_engine->getIdsByQuery($query, $params);
|
217 |
+
$this->_totalRecords = 1;
|
218 |
+
//$this->_totalRecords = $this->_engine->getLastNumFound();
|
219 |
+
}
|
220 |
+
|
221 |
+
return $this->_totalRecords;
|
222 |
+
}
|
223 |
+
|
224 |
+
/**
|
225 |
+
* Retrieves current collection stats.
|
226 |
+
* Used for max price.
|
227 |
+
*
|
228 |
+
* @param $fields
|
229 |
+
* @return mixed
|
230 |
+
*/
|
231 |
+
public function getStats($field)
|
232 |
+
{
|
233 |
+
return isset($this->stats[$field])?$this->stats[$field]:array();
|
234 |
+
}
|
235 |
+
|
236 |
+
/**
|
237 |
+
* Defines current search engine.
|
238 |
+
*
|
239 |
+
* @param ChoiceAI_Search_Model_Resource_Engine_Abstract $engine
|
240 |
+
* @return ChoiceAI_Search_Model_Resource_Catalog_Product_Collection
|
241 |
+
*/
|
242 |
+
public function setEngine(ChoiceAI_Search_Model_Resource_Engine_Abstract $engine)
|
243 |
+
{
|
244 |
+
$this->_engine = $engine;
|
245 |
+
|
246 |
+
return $this;
|
247 |
+
}
|
248 |
+
|
249 |
+
/**
|
250 |
+
* Stores sort order.
|
251 |
+
*
|
252 |
+
* @param string $attribute
|
253 |
+
* @param string $dir
|
254 |
+
* @return ChoiceAI_Search_Model_Resource_Catalog_Product_Collection
|
255 |
+
*/
|
256 |
+
public function setOrder($attribute, $dir = self::SORT_ORDER_DESC)
|
257 |
+
{
|
258 |
+
$this->_sortBy[] = array($attribute => $dir);
|
259 |
+
|
260 |
+
return $this;
|
261 |
+
}
|
262 |
+
|
263 |
+
/**
|
264 |
+
* Handles collection filtering by ids retrieves from search engine.
|
265 |
+
* Will also stores faceted data and total records.
|
266 |
+
*
|
267 |
+
* @return Mage_Catalog_Model_Resource_Product_Collection
|
268 |
+
*/
|
269 |
+
protected function _beforeLoad()
|
270 |
+
{
|
271 |
+
if ($this->_engine) {
|
272 |
+
$result = $this->_engine->getIdsByQuery($this->qt, $this->_getParams());
|
273 |
+
$this->_facetedData = isset($result['faceted_data']) ? $result['faceted_data'] : array();
|
274 |
+
$this->_totalRecords = isset($result['total_count']) ? $result['total_count'] : null;
|
275 |
+
$this->stats = isset($result["stats"])?$result["stats"] :array();
|
276 |
+
$this->results = isset($result["results"]) ? $result["results"] : array();
|
277 |
+
}
|
278 |
+
foreach($this->results as $result){
|
279 |
+
$product = new Mage_Catalog_Model_Product();
|
280 |
+
$result['id'] = $result['uniqueId'];
|
281 |
+
$product->addData($result);
|
282 |
+
$this->_items[$result['id']]=$product;
|
283 |
+
}
|
284 |
+
|
285 |
+
return parent::_beforeLoad();
|
286 |
+
}
|
287 |
+
|
288 |
+
|
289 |
+
|
290 |
+
/**
|
291 |
+
* Load collection data into object items
|
292 |
+
*
|
293 |
+
* @return Mage_Eav_Model_Entity_Collection_Abstract
|
294 |
+
*/
|
295 |
+
public function load($printQuery = false, $logQuery = false)
|
296 |
+
{
|
297 |
+
if ($this->isLoaded()) {
|
298 |
+
return $this;
|
299 |
+
}
|
300 |
+
Varien_Profiler::start('__EAV_COLLECTION_BEFORE_LOAD__');
|
301 |
+
Mage::dispatchEvent('eav_collection_abstract_load_before', array('collection' => $this));
|
302 |
+
$this->_beforeLoad();
|
303 |
+
Varien_Profiler::stop('__EAV_COLLECTION_BEFORE_LOAD__');
|
304 |
+
|
305 |
+
|
306 |
+
Varien_Profiler::start('__EAV_COLLECTION_LOAD_ENT__');
|
307 |
+
// $this->_loadEntities($printQuery, $logQuery);
|
308 |
+
Varien_Profiler::stop('__EAV_COLLECTION_LOAD_ENT__');
|
309 |
+
Varien_Profiler::start('__EAV_COLLECTION_LOAD_ATTR__');
|
310 |
+
// $this->_loadAttributes($printQuery, $logQuery);
|
311 |
+
Varien_Profiler::stop('__EAV_COLLECTION_LOAD_ATTR__');
|
312 |
+
|
313 |
+
Varien_Profiler::start('__EAV_COLLECTION_ORIG_DATA__');
|
314 |
+
/*
|
315 |
+
foreach ($this->_items as $item) {
|
316 |
+
$item->setOrigData();
|
317 |
+
}*/
|
318 |
+
Varien_Profiler::stop('__EAV_COLLECTION_ORIG_DATA__');
|
319 |
+
|
320 |
+
$this->_setIsLoaded();
|
321 |
+
Varien_Profiler::start('__EAV_COLLECTION_AFTER_LOAD__');
|
322 |
+
$this->_afterLoad();
|
323 |
+
Varien_Profiler::stop('__EAV_COLLECTION_AFTER_LOAD__');
|
324 |
+
return $this;
|
325 |
+
}
|
326 |
+
|
327 |
+
/**
|
328 |
+
* Retrieves parameters.
|
329 |
+
*
|
330 |
+
* @return array
|
331 |
+
*/
|
332 |
+
protected function _getParams()
|
333 |
+
{
|
334 |
+
$store = Mage::app()->getStore($this->getStoreId());
|
335 |
+
$params = array();
|
336 |
+
$params['locale_code'] = $store->getConfig(Mage_Core_Model_Locale::XML_PATH_DEFAULT_LOCALE);
|
337 |
+
$params['filters'] = $this->_searchQueryFilters;
|
338 |
+
$params['category'] = $this->_searchCategoryFilters;
|
339 |
+
$params['range_filters'] = $this->_searchQueryRangeFilters;
|
340 |
+
|
341 |
+
if (!empty($this->_sortBy)) {
|
342 |
+
$params['sort_by'] = $this->_sortBy;
|
343 |
+
}
|
344 |
+
|
345 |
+
if ($this->_pageSize !== false) {
|
346 |
+
$page = ($this->_curPage > 0) ? (int) $this->_curPage : 1;
|
347 |
+
$rowCount = ($this->_pageSize > 0) ? (int) $this->_pageSize : 1;
|
348 |
+
$params['offset'] = $rowCount * ($page - 1);
|
349 |
+
$params['limit'] = $rowCount;
|
350 |
+
}
|
351 |
+
|
352 |
+
if (!empty($this->_facetsConditions)) {
|
353 |
+
$params['facets'] = $this->_facetsConditions;
|
354 |
+
}
|
355 |
+
|
356 |
+
return $params;
|
357 |
+
}
|
358 |
+
|
359 |
+
/**
|
360 |
+
* Returns stored text query.
|
361 |
+
*
|
362 |
+
* @return string
|
363 |
+
*/
|
364 |
+
protected function _getQuery()
|
365 |
+
{
|
366 |
+
return $this->_searchQueryText;
|
367 |
+
}
|
368 |
+
}
|
app/code/local/ChoiceAI/Search/Model/Resource/Engine/Abstract.php
ADDED
@@ -0,0 +1,453 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* search client.
|
4 |
+
*
|
5 |
+
* @package ChoiceAI_Search
|
6 |
+
* @copyright Copyright (c) MineWhat
|
7 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
*/
|
9 |
+
abstract class ChoiceAI_Search_Model_Resource_Engine_Abstract
|
10 |
+
{
|
11 |
+
const DEFAULT_ROWS_LIMIT = 9999;
|
12 |
+
|
13 |
+
const UNIQUE_KEY = 'unique';
|
14 |
+
|
15 |
+
/**
|
16 |
+
* @var string List of advanced index fields prefix.
|
17 |
+
*/
|
18 |
+
protected $_advancedIndexFieldsPrefix = '#';
|
19 |
+
|
20 |
+
/**
|
21 |
+
* @var array List of advanced dynamic index fields.
|
22 |
+
*/
|
23 |
+
protected $_advancedDynamicIndexFields = array(
|
24 |
+
'#position_category_',
|
25 |
+
'#price_'
|
26 |
+
);
|
27 |
+
|
28 |
+
/**
|
29 |
+
* @var object Search engine client.
|
30 |
+
*/
|
31 |
+
protected $_client;
|
32 |
+
|
33 |
+
/**
|
34 |
+
* @var array List of dates format.
|
35 |
+
*/
|
36 |
+
protected $_dateFormats = array();
|
37 |
+
|
38 |
+
/**
|
39 |
+
* @var array List of default query parameters.
|
40 |
+
*/
|
41 |
+
protected $_defaultQueryParams = array(
|
42 |
+
'offset' => 0,
|
43 |
+
'limit' => 100,
|
44 |
+
'sort_by' => array(array('relevance' => 'desc')),
|
45 |
+
'store_id' => null,
|
46 |
+
'locale_code' => null,
|
47 |
+
'fields' => array(),
|
48 |
+
'params' => array(),
|
49 |
+
'ignore_handler' => false,
|
50 |
+
'filters' => array(),
|
51 |
+
);
|
52 |
+
|
53 |
+
/**
|
54 |
+
* @var array List of indexable attribute parameters.
|
55 |
+
*/
|
56 |
+
protected $_indexableAttributeParams = array();
|
57 |
+
|
58 |
+
/**
|
59 |
+
* @var int Last number of results found.
|
60 |
+
*/
|
61 |
+
protected $_lastNumFound;
|
62 |
+
|
63 |
+
/**
|
64 |
+
* @var array List of non fulltext fields.
|
65 |
+
*/
|
66 |
+
protected $_notInFulltextField = array(
|
67 |
+
self::UNIQUE_KEY,
|
68 |
+
'id',
|
69 |
+
'store_id',
|
70 |
+
'in_stock',
|
71 |
+
'categories',
|
72 |
+
'show_in_categories',
|
73 |
+
'visibility'
|
74 |
+
);
|
75 |
+
|
76 |
+
/**
|
77 |
+
* @var bool Stores search engine availibility
|
78 |
+
*/
|
79 |
+
protected $_test = null;
|
80 |
+
|
81 |
+
/**
|
82 |
+
* @var array List of used fields.
|
83 |
+
*/
|
84 |
+
protected $_usedFields = array(
|
85 |
+
self::UNIQUE_KEY,
|
86 |
+
'id',
|
87 |
+
'sku',
|
88 |
+
'price',
|
89 |
+
'store_id',
|
90 |
+
'categories',
|
91 |
+
'show_in_categories',
|
92 |
+
'visibility',
|
93 |
+
'in_stock',
|
94 |
+
'score'
|
95 |
+
);
|
96 |
+
|
97 |
+
/**
|
98 |
+
* Get Indexer instance
|
99 |
+
*
|
100 |
+
* @return Mage_Index_Model_Indexer
|
101 |
+
*/
|
102 |
+
protected function _getIndexer()
|
103 |
+
{
|
104 |
+
return Mage::getSingleton('index/indexer');
|
105 |
+
}
|
106 |
+
|
107 |
+
/**
|
108 |
+
* Adds advanced index fields to index data.
|
109 |
+
*
|
110 |
+
* @param array $index
|
111 |
+
* @param int $storeId
|
112 |
+
* @param array $productIds
|
113 |
+
* @return array
|
114 |
+
*/
|
115 |
+
public function addAdvancedIndex($index, $storeId, $productIds = null)
|
116 |
+
{
|
117 |
+
return 1;
|
118 |
+
}
|
119 |
+
|
120 |
+
/**
|
121 |
+
* Checks if advanced index is allowed for current search engine.
|
122 |
+
*
|
123 |
+
* @return bool
|
124 |
+
*/
|
125 |
+
public function allowAdvancedIndex()
|
126 |
+
{
|
127 |
+
return false;
|
128 |
+
|
129 |
+
}
|
130 |
+
|
131 |
+
|
132 |
+
public function cleanIndex()
|
133 |
+
{
|
134 |
+
return $this;
|
135 |
+
}
|
136 |
+
|
137 |
+
/**
|
138 |
+
* Cleans cache.
|
139 |
+
*
|
140 |
+
* @return ChoiceAI_Search_Model_Resource_Engine_Abstract
|
141 |
+
*/
|
142 |
+
public function cleanCache()
|
143 |
+
{
|
144 |
+
return $this->_getIndexer()->getProcessByCode('catalogsearch_fulltext')->cleanCache();
|
145 |
+
|
146 |
+
}
|
147 |
+
|
148 |
+
|
149 |
+
|
150 |
+
|
151 |
+
/**
|
152 |
+
* Returns product visibility ids for search.
|
153 |
+
*
|
154 |
+
* @see Mage_Catalog_Model_Product_Visibility
|
155 |
+
* @return mixed
|
156 |
+
*/
|
157 |
+
public function getAllowedVisibility()
|
158 |
+
{
|
159 |
+
return Mage::getSingleton('catalog/product_visibility')->getVisibleInSearchIds();
|
160 |
+
}
|
161 |
+
|
162 |
+
/**
|
163 |
+
* Returns advanced index fields prefix.
|
164 |
+
*
|
165 |
+
* @return string
|
166 |
+
*/
|
167 |
+
public function getFieldsPrefix()
|
168 |
+
{
|
169 |
+
return $this->_advancedIndexFieldsPrefix;
|
170 |
+
}
|
171 |
+
|
172 |
+
/**
|
173 |
+
* Retrieves product ids for specified query.
|
174 |
+
*
|
175 |
+
* @param string $query
|
176 |
+
* @param array $params
|
177 |
+
* @param string $type
|
178 |
+
* @return array
|
179 |
+
*/
|
180 |
+
public function getIdsByQuery($query, $params = array(), $type = 'product')
|
181 |
+
{
|
182 |
+
$ids = array();
|
183 |
+
$params['fields'] = array('id');
|
184 |
+
$resultTmp = $this->search($query, $params, $type);
|
185 |
+
if (!empty($resultTmp['ids'])) {
|
186 |
+
foreach ($resultTmp['ids'] as $id) {
|
187 |
+
$ids[] = $id['uniqueId'];
|
188 |
+
}
|
189 |
+
}
|
190 |
+
$result = array(
|
191 |
+
'ids' => $ids,
|
192 |
+
'total_count' => (isset($resultTmp['total_count'])) ? $resultTmp['total_count'] : null,
|
193 |
+
'faceted_data' => (isset($resultTmp['facets'])) ? $resultTmp['facets'] : array(),
|
194 |
+
'results' => array_key_exists('result', $resultTmp)?$resultTmp["result"]: array(),
|
195 |
+
'stats' => array_key_exists('stats', $resultTmp)?$resultTmp["stats"]: array()
|
196 |
+
);
|
197 |
+
|
198 |
+
return $result;
|
199 |
+
}
|
200 |
+
|
201 |
+
/**
|
202 |
+
* Returns last number of results found.
|
203 |
+
*
|
204 |
+
* @return int
|
205 |
+
*/
|
206 |
+
public function getLastNumFound()
|
207 |
+
{
|
208 |
+
return $this->_lastNumFound;
|
209 |
+
}
|
210 |
+
|
211 |
+
/**
|
212 |
+
* Returns catalog product collection with current search engine set.
|
213 |
+
*
|
214 |
+
* @return ChoiceAI_Search_Model_Resource_Catalog_Product_Collection
|
215 |
+
*/
|
216 |
+
public function getResultCollection()
|
217 |
+
{
|
218 |
+
return Mage::getResourceModel('choiceai_search/catalog_product_collection')->setEngine($this);
|
219 |
+
}
|
220 |
+
|
221 |
+
|
222 |
+
/**
|
223 |
+
* Alias of isLayeredNavigationAllowed.
|
224 |
+
*
|
225 |
+
* @return bool
|
226 |
+
*/
|
227 |
+
public function isLeyeredNavigationAllowed()
|
228 |
+
{
|
229 |
+
return $this->isLayeredNavigationAllowed();
|
230 |
+
}
|
231 |
+
|
232 |
+
/**
|
233 |
+
* Checks if layered navigation is available for current search engine.
|
234 |
+
*
|
235 |
+
* @return bool
|
236 |
+
*/
|
237 |
+
public function isLayeredNavigationAllowed()
|
238 |
+
{
|
239 |
+
return true;
|
240 |
+
}
|
241 |
+
|
242 |
+
/**
|
243 |
+
* Prepares index data.
|
244 |
+
* Should be overriden in child classes if needed.
|
245 |
+
*
|
246 |
+
* @param $index
|
247 |
+
* @param string $separator
|
248 |
+
* @return array
|
249 |
+
*/
|
250 |
+
public function prepareEntityIndex($index, $separator = null)
|
251 |
+
{
|
252 |
+
return $this->_getHelper()->prepareIndexData($index, $separator);
|
253 |
+
}
|
254 |
+
|
255 |
+
/**
|
256 |
+
* Performs search query and facetting.
|
257 |
+
*
|
258 |
+
* @param string $query
|
259 |
+
* @param array $params
|
260 |
+
* @param string $type
|
261 |
+
* @return array
|
262 |
+
*/
|
263 |
+
public function search($query, $params = array(), $type = 'product')
|
264 |
+
{
|
265 |
+
try {
|
266 |
+
Varien_Profiler::start('CHOICEAI_SEARCH');
|
267 |
+
$result = $this->_search($query, $params, $type);
|
268 |
+
Varien_Profiler::stop('CHOICEAI_SEARCH');
|
269 |
+
|
270 |
+
return $result;
|
271 |
+
} catch (Exception $e) {
|
272 |
+
Mage::logException($e);
|
273 |
+
if ($this->_getHelper()->isDebugEnabled()) {
|
274 |
+
$this->_getHelper()->showError($e->getMessage());
|
275 |
+
}
|
276 |
+
}
|
277 |
+
|
278 |
+
return array();
|
279 |
+
}
|
280 |
+
|
281 |
+
/**
|
282 |
+
* Checks search engine availability.
|
283 |
+
* Should be overriden by child classes.
|
284 |
+
*
|
285 |
+
* @return bool
|
286 |
+
*/
|
287 |
+
public function test()
|
288 |
+
{
|
289 |
+
return true;
|
290 |
+
}
|
291 |
+
|
292 |
+
/**
|
293 |
+
* Transforms specified date to basic YYYY-MM-dd format.
|
294 |
+
*
|
295 |
+
* @param int $storeId
|
296 |
+
* @param string $date
|
297 |
+
* @return null|string
|
298 |
+
*/
|
299 |
+
protected function _getDate($storeId, $date = null)
|
300 |
+
{
|
301 |
+
if (!isset($this->_dateFormats[$storeId])) {
|
302 |
+
$timezone = Mage::getStoreConfig(Mage_Core_Model_Locale::XML_PATH_DEFAULT_TIMEZONE, $storeId);
|
303 |
+
$locale = Mage::getStoreConfig(Mage_Core_Model_Locale::XML_PATH_DEFAULT_LOCALE, $storeId);
|
304 |
+
$locale = new Zend_Locale($locale);
|
305 |
+
|
306 |
+
$dateObj = new Zend_Date(null, null, $locale);
|
307 |
+
$dateObj->setTimezone($timezone);
|
308 |
+
$this->_dateFormats[$storeId] = array($dateObj, $locale->getTranslation(null, 'date', $locale));
|
309 |
+
}
|
310 |
+
|
311 |
+
if (is_empty_date($date)) {
|
312 |
+
return null;
|
313 |
+
}
|
314 |
+
|
315 |
+
list($dateObj, $localeDateFormat) = $this->_dateFormats[$storeId];
|
316 |
+
$dateObj->setDate($date, $localeDateFormat);
|
317 |
+
|
318 |
+
return $dateObj->toString('YYYY-MM-dd');
|
319 |
+
}
|
320 |
+
|
321 |
+
/**
|
322 |
+
* Returns search helper.
|
323 |
+
*
|
324 |
+
* @return ChoiceAI_Search_Helper_Data
|
325 |
+
*/
|
326 |
+
protected function _getHelper()
|
327 |
+
{
|
328 |
+
return Mage::helper('choiceai_search');
|
329 |
+
}
|
330 |
+
|
331 |
+
/**
|
332 |
+
* Returns indexable attribute parameters.
|
333 |
+
*
|
334 |
+
* @return array
|
335 |
+
*/
|
336 |
+
protected function _getIndexableAttributeParams()
|
337 |
+
{
|
338 |
+
if (null === $this->_indexableAttributeParams) {
|
339 |
+
$this->_indexableAttributeParams = array();
|
340 |
+
$attributes = $this->_getHelper()->getSearchableAttributes();
|
341 |
+
foreach ($attributes as $attribute) {
|
342 |
+
/** @var $attribute Mage_Catalog_Model_Resource_Eav_Attribute */
|
343 |
+
$this->_indexableAttributeParams[$attribute->getAttributeCode()] = array(
|
344 |
+
'backend_type' => $attribute->getBackendType(),
|
345 |
+
'frontend_input' => $attribute->getFrontendInput(),
|
346 |
+
'search_weight' => $attribute->getSearchWeight(),
|
347 |
+
'is_searchable' => $attribute->getIsSearchable()
|
348 |
+
);
|
349 |
+
}
|
350 |
+
}
|
351 |
+
|
352 |
+
return $this->_getIndexer()->getProcessByCode('catalogsearch_fulltext')->_getIndexableAttributeParams();
|
353 |
+
}
|
354 |
+
|
355 |
+
/**
|
356 |
+
* Returns store locale code.
|
357 |
+
*
|
358 |
+
* @param int $storeId
|
359 |
+
* @return string
|
360 |
+
*/
|
361 |
+
protected function _getLocaleCode($storeId = null)
|
362 |
+
{
|
363 |
+
return $this->_getHelper()->getLocaleCode($storeId);
|
364 |
+
}
|
365 |
+
|
366 |
+
/**
|
367 |
+
* Transforms specified object to an array.
|
368 |
+
*
|
369 |
+
* @param $object
|
370 |
+
* @return array
|
371 |
+
*/
|
372 |
+
protected function _objectToArray($object)
|
373 |
+
{
|
374 |
+
if (!is_object($object) && !is_array($object)){
|
375 |
+
return $object;
|
376 |
+
}
|
377 |
+
if (is_object($object)){
|
378 |
+
$object = get_object_vars($object);
|
379 |
+
}
|
380 |
+
|
381 |
+
return array_map(array($this, '_objectToArray'), $object);
|
382 |
+
}
|
383 |
+
|
384 |
+
/**
|
385 |
+
* @param array $docsData
|
386 |
+
* @param string $type
|
387 |
+
* @param string $localeCode
|
388 |
+
* @return array
|
389 |
+
*/
|
390 |
+
protected function _prepareDocs($docsData, $type, $localeCode = null)
|
391 |
+
{
|
392 |
+
if (!is_array($docsData) || empty($docsData)) {
|
393 |
+
return array();
|
394 |
+
}
|
395 |
+
|
396 |
+
$docs = array();
|
397 |
+
foreach ($docsData as $entityId => $index) {
|
398 |
+
$index[self::UNIQUE_KEY] = $entityId . '|' . $index['store_id'];
|
399 |
+
$index['id'] = $entityId;
|
400 |
+
$index = $this->_prepareIndexData($index, $localeCode);
|
401 |
+
$docs[] = $this->_createDoc($entityId, $index, $type);
|
402 |
+
}
|
403 |
+
|
404 |
+
return $this->_getIndexer()->getProcessByCode('catalogsearch_fulltext')->_prepareDocs();
|
405 |
+
}
|
406 |
+
|
407 |
+
/**
|
408 |
+
* Prepares index data before indexation.
|
409 |
+
*
|
410 |
+
* @param array $data
|
411 |
+
* @param string $localeCode
|
412 |
+
* @return array
|
413 |
+
*/
|
414 |
+
protected function _prepareIndexData($data, $localeCode = null)
|
415 |
+
{
|
416 |
+
if (!is_array($data) || empty($data)) {
|
417 |
+
return array();
|
418 |
+
}
|
419 |
+
|
420 |
+
foreach ($data as $key => $value) {
|
421 |
+
if (in_array($key, $this->_usedFields)) {
|
422 |
+
continue;
|
423 |
+
} elseif ($key == 'options') {
|
424 |
+
unset($data[$key]);
|
425 |
+
continue;
|
426 |
+
}
|
427 |
+
$field = $this->_getHelper()->getAttributeFieldName($key, $localeCode);
|
428 |
+
$field = str_replace($this->_advancedIndexFieldsPrefix, '', $field);
|
429 |
+
if ($field != $key) {
|
430 |
+
$data[$field] = $value;
|
431 |
+
unset($data[$key]);
|
432 |
+
}
|
433 |
+
}
|
434 |
+
|
435 |
+
return $this->_getIndexer()->getProcessByCode('catalogsearch_fulltext')->_prepareIndexData();
|
436 |
+
}
|
437 |
+
|
438 |
+
/**
|
439 |
+
* Prepares query before search.
|
440 |
+
*
|
441 |
+
* @param mixed $query
|
442 |
+
* @return string
|
443 |
+
*/
|
444 |
+
protected function _prepareSearchConditions($query)
|
445 |
+
{
|
446 |
+
return $query;
|
447 |
+
}
|
448 |
+
|
449 |
+
public function saveEntityIndexes()
|
450 |
+
{
|
451 |
+
return $this;
|
452 |
+
}
|
453 |
+
}
|
app/code/local/ChoiceAI/Search/Model/Resource/Engine/Choiceaisearch.php
ADDED
@@ -0,0 +1,242 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* ChoiceAI engine.
|
5 |
+
*
|
6 |
+
* @package ChoiceAI_Search
|
7 |
+
* @copyright Copyright (c) MineWhat
|
8 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
9 |
+
*/
|
10 |
+
class ChoiceAI_Search_Model_Resource_Engine_ChoiceAIsearch extends ChoiceAI_Search_Model_Resource_Engine_Abstract
|
11 |
+
{
|
12 |
+
/**
|
13 |
+
* Initializes search engine.
|
14 |
+
*
|
15 |
+
* @see
|
16 |
+
*/
|
17 |
+
public function __construct()
|
18 |
+
{
|
19 |
+
$this->client = Mage::getResourceSingleton('choiceai_search/engine_choiceaisearch_client');
|
20 |
+
}
|
21 |
+
|
22 |
+
function _prepareFacetsQueryResponse($response = array()){
|
23 |
+
$result = array();
|
24 |
+
foreach ($response as $facetName=>$facetlist) {
|
25 |
+
if($facetlist["type"]=='facet_fields'){
|
26 |
+
$result[$facetName] = array();
|
27 |
+
$count = 0;
|
28 |
+
$facetKey ='';
|
29 |
+
foreach($facetlist['values'] as $value){
|
30 |
+
if($count++ % 2 == 0){
|
31 |
+
$facetKey = $value;
|
32 |
+
}else{
|
33 |
+
$result[$facetName][$facetKey]=$value;
|
34 |
+
}
|
35 |
+
}
|
36 |
+
}else if($facetlist["type"]=='facet_ranges'){
|
37 |
+
$result[$facetName] = array();
|
38 |
+
$count = 0;
|
39 |
+
$facetKey = '';
|
40 |
+
$gap = floatval($facetlist['values']['gap']);
|
41 |
+
foreach($facetlist['values']['counts'] as $value){
|
42 |
+
if($count++ % 2 == 0){
|
43 |
+
$facetKey = floatval($value);
|
44 |
+
}else{
|
45 |
+
$result[$facetName]['['.$facetKey.' TO '.($facetKey + $gap).']']=$value;
|
46 |
+
}
|
47 |
+
}
|
48 |
+
}
|
49 |
+
}
|
50 |
+
return $result;
|
51 |
+
|
52 |
+
}
|
53 |
+
|
54 |
+
/**
|
55 |
+
* prepares the facet condtion
|
56 |
+
*/
|
57 |
+
public function _prepareFacetsConditions($facets = array()){
|
58 |
+
|
59 |
+
$stringFacets = array();
|
60 |
+
$rangeFacets = array();
|
61 |
+
if(is_array($facets)){
|
62 |
+
foreach($facets as $facetKey=>$facetValue){
|
63 |
+
if(is_array($facetValue) && $facetValue != null && is_array($facetValue) && sizeof($facetValue) > 0 ){
|
64 |
+
if(isset($facetValue['from']) && isset($facetValue["to"])){
|
65 |
+
$facetValues= array();
|
66 |
+
$eachFacetValue= $facetValue;
|
67 |
+
if(!isset($eachFacetValue['from']) || $eachFacetValue['from'] == "" ){
|
68 |
+
$eachFacetValue['from'] = '0';
|
69 |
+
}
|
70 |
+
if(!isset($eachFacetValue['to']) || $eachFacetValue['to'] == "" ){
|
71 |
+
$eachFacetValue['to'] = '*';
|
72 |
+
}
|
73 |
+
$facetValues['from'] = $eachFacetValue['from'];
|
74 |
+
$facetValues['to'] = $eachFacetValue['to'];
|
75 |
+
$stringFacets[$facetKey][] = $facetValues;
|
76 |
+
} else {
|
77 |
+
$stringFacets[$facetKey] = $facetValue;
|
78 |
+
}
|
79 |
+
}
|
80 |
+
}
|
81 |
+
}
|
82 |
+
$facets=array();
|
83 |
+
$facets["attribute"] = $stringFacets;
|
84 |
+
$facets["range"] = $rangeFacets;
|
85 |
+
return $facets;
|
86 |
+
}
|
87 |
+
|
88 |
+
function str_lreplace($search, $replace, $subject)
|
89 |
+
{
|
90 |
+
$pos = strrpos($subject, $search);
|
91 |
+
|
92 |
+
if($pos !== false) {
|
93 |
+
$subject = substr_replace($subject, $replace, $pos, strlen($search));
|
94 |
+
}
|
95 |
+
return $subject;
|
96 |
+
}
|
97 |
+
|
98 |
+
protected function _prepareResponse($data){
|
99 |
+
|
100 |
+
/* @var $response ChoiceAI_ResultSet */
|
101 |
+
if (!$data instanceof ChoiceAI_ResultSet || $data->getTotalHits()<=0) {
|
102 |
+
return array();
|
103 |
+
}
|
104 |
+
|
105 |
+
$result = array();
|
106 |
+
|
107 |
+
foreach ($data->getResults() as $doc) {
|
108 |
+
$result[] =$doc->getHit();
|
109 |
+
}
|
110 |
+
return $result;
|
111 |
+
}
|
112 |
+
|
113 |
+
/**
|
114 |
+
* Prepares sort fields.
|
115 |
+
*
|
116 |
+
* @param array $sortBy
|
117 |
+
* @return array
|
118 |
+
*/
|
119 |
+
protected function _prepareSortFields($sortBy=array())
|
120 |
+
{
|
121 |
+
$sort =array();
|
122 |
+
if(!isset($sortBy) || sizeof($sortBy) == 0) {
|
123 |
+
$sortParameter = array_key_exists('order',$_GET)?$_GET['order']:null;
|
124 |
+
$sortBy = (!is_null($sortParameter))?
|
125 |
+
array(array($sortParameter => (isset($_GET['dir']) && $_GET['dir'] == 'desc')?'desc':'asc')): array();
|
126 |
+
$sessionSort = Mage::getSingleton('catalog/session')->getSortOrder();
|
127 |
+
$sessionDir = Mage::getSingleton('catalog/session')->getSortDirection();
|
128 |
+
$sortBy = (is_null($sortBy)|| sizeof($sortBy) == 0) && !is_null($sessionSort) ?
|
129 |
+
array(array($sessionSort => ($sessionDir === 'desc')?'desc':'asc')):$sortBy;
|
130 |
+
}
|
131 |
+
|
132 |
+
foreach($sortBy as $value){
|
133 |
+
foreach($value as $sortKey=>$sortValue){
|
134 |
+
if($sortKey != "position" && $sortKey != "relevance"){
|
135 |
+
if($sortValue == 'asc'){
|
136 |
+
$sort[$sortKey] = 1;
|
137 |
+
|
138 |
+
}else{
|
139 |
+
|
140 |
+
$sort[$sortKey] = -1;
|
141 |
+
|
142 |
+
}
|
143 |
+
}
|
144 |
+
}
|
145 |
+
}
|
146 |
+
return $sort;
|
147 |
+
}
|
148 |
+
|
149 |
+
|
150 |
+
public function getStats($data){
|
151 |
+
$stats = $data->getStats();
|
152 |
+
if(isset($stats) && is_array($stats)){
|
153 |
+
return $stats;
|
154 |
+
}
|
155 |
+
return array();
|
156 |
+
}
|
157 |
+
|
158 |
+
/**
|
159 |
+
* prepare limitN
|
160 |
+
* @param $params
|
161 |
+
* @return int|mixed
|
162 |
+
*/
|
163 |
+
protected function _prepareLimit($params) {
|
164 |
+
$limitInRequest = array_key_exists('limit', $_GET)?$_GET['limit']:null;
|
165 |
+
$limitOnSession = Mage::getSingleton('catalog/session')->getLimitPage();
|
166 |
+
if($limitOnSession === "all" || $limitInRequest === "all") {
|
167 |
+
$limitOnSession = 100;
|
168 |
+
}
|
169 |
+
$limit = ($limitInRequest > 0)? (int) $limitInRequest:($limitOnSession > 0? $limitOnSession: ((isset($_GET['mode']) && $_GET['mode'] == 'list')?Mage::getStoreConfig('catalog/frontend/list_per_page'): Mage::getStoreConfig('catalog/frontend/grid_per_page')));
|
170 |
+
if(array_key_exists("limit", $params)) {
|
171 |
+
$limit = (int)$params["limit"];
|
172 |
+
}
|
173 |
+
return $limit;
|
174 |
+
|
175 |
+
}
|
176 |
+
|
177 |
+
/**
|
178 |
+
* Performs search and facetting.
|
179 |
+
*
|
180 |
+
* @param string $query
|
181 |
+
* @param array $params
|
182 |
+
* @param string $type
|
183 |
+
* @return array
|
184 |
+
*/
|
185 |
+
protected function _search($qt, $params = array(), $type = 'product')
|
186 |
+
{
|
187 |
+
$multiselectValue = Mage::getConfig()->getNode('default/choiceai/general/multiselect_facet');
|
188 |
+
$multiselectValue = (!is_null($multiselectValue) &&
|
189 |
+
sizeof($multiselectValue) && $multiselectValue[0] == 'true')?true:false;
|
190 |
+
$limit = $this->_prepareLimit($params);
|
191 |
+
if(isset($_GET['p'])){
|
192 |
+
$page = ((int)$_GET['p'] > 0)?((int)$_GET['p'] - 1)* $limit:0;
|
193 |
+
}else{
|
194 |
+
$page = 0;
|
195 |
+
}
|
196 |
+
|
197 |
+
$facets = $this->_prepareFacetsConditions($params['filters']);
|
198 |
+
$searchParams = array();
|
199 |
+
$query = Mage::helper('catalogsearch')->getQueryText();
|
200 |
+
|
201 |
+
if(isset($query) && $query != ''){
|
202 |
+
$this->client = $this->client->setRuleset('search')->setQuery($query)->setFilters($facets['attribute']);
|
203 |
+
}else{
|
204 |
+
$this->client = $this->client->setRuleset('browse')->setCategoryId($params['category'])->setFilters($facets['attribute']);
|
205 |
+
}
|
206 |
+
$agent_tokens =explode(' ',$_SERVER['HTTP_USER_AGENT']);
|
207 |
+
$data = $this->client
|
208 |
+
->setOffset($page)
|
209 |
+
->setLimit($limit)
|
210 |
+
->setOtherOptions(array('wt' => 'json', 'user_agent' => $agent_tokens[0],
|
211 |
+
'stats' => 'price', 'indent' => 'on',
|
212 |
+
'u' => (isset($_COOKIE['choiceai_userId'])) ? $_COOKIE['choiceai_userId'] : NULL,
|
213 |
+
'facet.multiselect' => $multiselectValue?"true":"false"))
|
214 |
+
->setDebug(false)
|
215 |
+
->setSort($this->_prepareSortFields(array_key_exists('sort_by', $params)?$params['sort_by']:array()))
|
216 |
+
->search();
|
217 |
+
if (!$data instanceof ChoiceAI_ResultSet) {
|
218 |
+
return array();
|
219 |
+
}
|
220 |
+
|
221 |
+
if($data->getSpellCheckQuery()) {
|
222 |
+
Mage::unregister('spellcheckQuery');
|
223 |
+
Mage::register('spellcheckQuery', $data->getSpellCheckQuery());
|
224 |
+
}
|
225 |
+
|
226 |
+
|
227 |
+
/* @var $data ChoiceAI_ResultSet */
|
228 |
+
|
229 |
+
$result = array(
|
230 |
+
'total_count' => $data->getTotalHits(),
|
231 |
+
'result'=> $this->_prepareResponse($data),
|
232 |
+
'stats'=>$this->getStats($data)
|
233 |
+
);
|
234 |
+
$result['facets'] = $this->_prepareFacetsQueryResponse($data->getFacets());
|
235 |
+
Mage::unregister('start');
|
236 |
+
Mage::register('start', $page* Mage::getStoreConfig('catalog/frontend/grid_per_page'));
|
237 |
+
return $result;
|
238 |
+
}
|
239 |
+
|
240 |
+
}
|
241 |
+
|
242 |
+
?>
|
app/code/local/ChoiceAI/Search/Model/Resource/Engine/Choiceaisearch/Client.php
ADDED
@@ -0,0 +1,29 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
*
|
5 |
+
* @package ChoiceAI_Search
|
6 |
+
* @copyright Copyright (c) MineWhat
|
7 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
*/
|
9 |
+
|
10 |
+
class ChoiceAI_Search_Model_Resource_Engine_ChoiceAIsearch_Client extends ChoiceAI_Client{
|
11 |
+
|
12 |
+
const CONFIG_API_KEY = 'choiceai_personalisation/settings/api_key';
|
13 |
+
|
14 |
+
public function __construct()
|
15 |
+
{
|
16 |
+
$config = $this->_getHelper()->getEngineConfigData();
|
17 |
+
$config['context'] = Mage::getStoreConfig(self::CONFIG_API_KEY);
|
18 |
+
parent::__construct($config);
|
19 |
+
|
20 |
+
}
|
21 |
+
|
22 |
+
protected function _getHelper()
|
23 |
+
{
|
24 |
+
return Mage::helper('choiceai_search/choiceaisearch');
|
25 |
+
}
|
26 |
+
|
27 |
+
|
28 |
+
}
|
29 |
+
?>
|
app/code/local/ChoiceAI/Search/etc/config.xml
ADDED
@@ -0,0 +1,101 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?xml version="1.0"?>
|
2 |
+
<config>
|
3 |
+
<modules>
|
4 |
+
<ChoiceAI_Search>
|
5 |
+
<version>0.0.9</version>
|
6 |
+
</ChoiceAI_Search>
|
7 |
+
</modules>
|
8 |
+
<global>
|
9 |
+
<models>
|
10 |
+
<choiceai_search>
|
11 |
+
<class>ChoiceAI_Search_Model</class>
|
12 |
+
<resourceModel>choiceai_search_resource</resourceModel>
|
13 |
+
</choiceai_search>
|
14 |
+
<choiceai_search_resource>
|
15 |
+
<class>ChoiceAI_Search_Model_Resource</class>
|
16 |
+
</choiceai_search_resource>
|
17 |
+
<catalog>
|
18 |
+
<rewrite>
|
19 |
+
<config>ChoiceAI_Search_Model_Catalog_Config</config>
|
20 |
+
<category>ChoiceAI_Search_Model_Catalog_Category</category>
|
21 |
+
</rewrite>
|
22 |
+
</catalog>
|
23 |
+
</models>
|
24 |
+
<helpers>
|
25 |
+
<choiceai_search>
|
26 |
+
<class>ChoiceAI_Search_Helper</class>
|
27 |
+
</choiceai_search>
|
28 |
+
<catalogsearch>
|
29 |
+
<rewrite>
|
30 |
+
<data>ChoiceAI_Search_Helper_Catalogsearch</data>
|
31 |
+
</rewrite>
|
32 |
+
</catalogsearch>
|
33 |
+
</helpers>
|
34 |
+
<blocks>
|
35 |
+
<choiceai_search>
|
36 |
+
<class>ChoiceAI_Search_Block</class>
|
37 |
+
</choiceai_search>
|
38 |
+
<catalog>
|
39 |
+
<rewrite>
|
40 |
+
<layer_view>ChoiceAI_Search_Block_Catalog_Layer_View</layer_view>
|
41 |
+
<product_list>ChoiceAI_Search_Block_Catalog_Product_List</product_list>
|
42 |
+
<product_list_toolbar>ChoiceAI_Search_Block_Catalog_Product_List_Toolbar</product_list_toolbar>
|
43 |
+
</rewrite>
|
44 |
+
</catalog>
|
45 |
+
<catalogsearch>
|
46 |
+
<rewrite>
|
47 |
+
<layer>ChoiceAI_Search_Block_Catalogsearch_Layer</layer>
|
48 |
+
<result>ChoiceAI_Search_Block_Catalogsearch_Result</result>
|
49 |
+
</rewrite>
|
50 |
+
</catalogsearch>
|
51 |
+
<enterprise_search>
|
52 |
+
<rewrite>
|
53 |
+
<catalogsearch_layer>ChoiceAI_Search_Block_Catalogsearch_Enterprise_Layer</catalogsearch_layer>
|
54 |
+
</rewrite>
|
55 |
+
</enterprise_search>
|
56 |
+
</blocks>
|
57 |
+
<resources>
|
58 |
+
<choiceai_search_setup>
|
59 |
+
<setup>
|
60 |
+
<module>ChoiceAI_Search</module>
|
61 |
+
<class>Mage_Core_Model_Resource_Setup</class>
|
62 |
+
</setup>
|
63 |
+
</choiceai_search_setup>
|
64 |
+
</resources>
|
65 |
+
</global>
|
66 |
+
<default>
|
67 |
+
<catalog>
|
68 |
+
<search>
|
69 |
+
<choiceai_ruleset>search</choiceai_ruleset>
|
70 |
+
<choiceai_timeout>300</choiceai_timeout>
|
71 |
+
</search>
|
72 |
+
</catalog>
|
73 |
+
<choiceai>
|
74 |
+
<general>
|
75 |
+
<multiselect_facet>true</multiselect_facet>
|
76 |
+
<autosuggest_status>false</autosuggest_status>
|
77 |
+
<autosuggest_skin>#ff8400</autosuggest_skin>
|
78 |
+
<autosuggest_template>1column</autosuggest_template>
|
79 |
+
<autosuggest_max_suggestion>12</autosuggest_max_suggestion>
|
80 |
+
<autosuggest_top_queries_status>false</autosuggest_top_queries_status>
|
81 |
+
<autosuggest_keyword_status>true</autosuggest_keyword_status>
|
82 |
+
<autosuggest_search_scope_status>true</autosuggest_search_scope_status>
|
83 |
+
<autosuggest_max_products>2</autosuggest_max_products>
|
84 |
+
<autosuggest_product_header>Popular Products</autosuggest_product_header>
|
85 |
+
<autosuggest_keyword_header></autosuggest_keyword_header>
|
86 |
+
<autosuggest_search_scope_header></autosuggest_search_scope_header>
|
87 |
+
<autosuggest_show_cart>false</autosuggest_show_cart>
|
88 |
+
<autosuggest_sidecontent>right</autosuggest_sidecontent>
|
89 |
+
<autosuggest_topquery_header></autosuggest_topquery_header>
|
90 |
+
<autosuggest_keyword_header></autosuggest_keyword_header>
|
91 |
+
<autosuggest_search_scope_header></autosuggest_search_scope_header>
|
92 |
+
<autosuggest_pop_product_header>Popular Products</autosuggest_pop_product_header>
|
93 |
+
<search_mod_status>false</search_mod_status>
|
94 |
+
<search_mod_power>search</search_mod_power>
|
95 |
+
<search_hosted_status>false</search_hosted_status>
|
96 |
+
<search_hosted_int_status>false</search_hosted_int_status>
|
97 |
+
<search_hosted_redirect_url></search_hosted_redirect_url>
|
98 |
+
</general>
|
99 |
+
</choiceai>
|
100 |
+
</default>
|
101 |
+
</config>
|
app/code/local/ChoiceAI/Searchcore/Helper/Confighelper.php
ADDED
@@ -0,0 +1,472 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @category ChoiceAI
|
5 |
+
* @copyright Copyright (c) MineWhat
|
6 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
7 |
+
*/
|
8 |
+
class ChoiceAI_Searchcore_Helper_Confighelper extends ChoiceAI_Searchcore_Helper_Data
|
9 |
+
{
|
10 |
+
|
11 |
+
const SITE_KEY = "site_key";
|
12 |
+
|
13 |
+
const API_KEY = "api_key";
|
14 |
+
|
15 |
+
const SECRET_KEY = "secret_key";
|
16 |
+
|
17 |
+
const USERNAME = "username";
|
18 |
+
|
19 |
+
const NEED_FEATURE_FIELD_UPDATION = "need_feature_field_updation";
|
20 |
+
|
21 |
+
const IS_CRON_ENABLED = "cron_enabled";
|
22 |
+
|
23 |
+
const SUBJECT = 'subject';
|
24 |
+
|
25 |
+
const CONTENT = 'content';
|
26 |
+
|
27 |
+
const CC = 'cc';
|
28 |
+
|
29 |
+
|
30 |
+
/**
|
31 |
+
* All possible data type values supported choiceai
|
32 |
+
* @var array
|
33 |
+
*/
|
34 |
+
public static $data_types = array("text", "longText", "link", "decimal", "number", "datetime");
|
35 |
+
|
36 |
+
public function validateAndSaveKeys($website, $requestBody)
|
37 |
+
{
|
38 |
+
$errors = $this->validateKeyParams($requestBody);
|
39 |
+
if (sizeof($errors) > 0) {
|
40 |
+
return $errors;
|
41 |
+
}
|
42 |
+
$requestParams = json_decode($requestBody, true);
|
43 |
+
if (!$requestParams) {
|
44 |
+
$errors['message'] = 'Invalid Request';
|
45 |
+
return $errors;
|
46 |
+
}
|
47 |
+
$response = Mage::getModel("choiceai_searchcore/api_task_validatekeys")
|
48 |
+
->setData(ChoiceAI_Searchcore_Model_Api_Task_Validatekeys::SECRET_KEY, $requestParams[self::SECRET_KEY])
|
49 |
+
->setData(ChoiceAI_Searchcore_Model_Api_Task_Validatekeys::SITE_KEY, $requestParams[self::SITE_KEY])
|
50 |
+
->prepare($website)
|
51 |
+
->process();
|
52 |
+
if (!$response->isSuccess()) {
|
53 |
+
return $response->getErrors();
|
54 |
+
}
|
55 |
+
|
56 |
+
$existingSecretKey = Mage::getResourceModel('choiceai_searchcore/config')
|
57 |
+
->getValue($website->getWebsiteId(), ChoiceAI_Searchcore_Helper_Constants::SECRET_KEY);
|
58 |
+
$keyAlreadyExists = !is_null($existingSecretKey);
|
59 |
+
if ($keyAlreadyExists) {
|
60 |
+
$this->flushConfigs($website);
|
61 |
+
}
|
62 |
+
|
63 |
+
Mage::getResourceModel('choiceai_searchcore/config')
|
64 |
+
->setValue($website->getWebsiteId(), ChoiceAI_Searchcore_Helper_Constants::SECRET_KEY,
|
65 |
+
$requestParams[ChoiceAI_Searchcore_Helper_Constants::SECRET_KEY]);
|
66 |
+
Mage::getResourceModel('choiceai_searchcore/config')
|
67 |
+
->setValue($website->getWebsiteId(), ChoiceAI_Searchcore_Helper_Constants::SITE_KEY,
|
68 |
+
$requestParams[ChoiceAI_Searchcore_Helper_Constants::SITE_KEY]);
|
69 |
+
$response = $response->getResponse();
|
70 |
+
Mage::getResourceModel('choiceai_searchcore/config')
|
71 |
+
->setValue($website->getWebsiteId(),
|
72 |
+
ChoiceAI_Searchcore_Helper_Constants::API_KEY,
|
73 |
+
$response[ChoiceAI_Searchcore_Model_Api_Task_Validatekeys::API_KEY]);
|
74 |
+
Mage::getResourceModel('choiceai_searchcore/config')
|
75 |
+
->setValue($website->getWebsiteId(),
|
76 |
+
ChoiceAI_Searchcore_Helper_Constants::USERNAME,
|
77 |
+
$response[ChoiceAI_Searchcore_Model_Api_Task_Validatekeys::USERNAME]);
|
78 |
+
$this->saveConfig(Mage::app()->getWebsite(),
|
79 |
+
array(ChoiceAI_Searchcore_Helper_Constants::API_KEY => $response[ChoiceAI_Searchcore_Model_Api_Task_Validatekeys::API_KEY],
|
80 |
+
ChoiceAI_Searchcore_Helper_Constants::SITE_KEY => $requestParams[ChoiceAI_Searchcore_Helper_Constants::SITE_KEY]));
|
81 |
+
return $errors;
|
82 |
+
}
|
83 |
+
|
84 |
+
public function flushConfigs($website)
|
85 |
+
{
|
86 |
+
Mage::helper('choiceai_searchcore')->log(Zend_Log::DEBUG, 'Flushing all the configs');
|
87 |
+
$configs = $this->getEngineConfigData('', $website, true);
|
88 |
+
foreach ($configs as $config => $value) {
|
89 |
+
Mage::getConfig()->deleteConfig(ChoiceAI_Searchcore_Helper_Constants::CHOICEAI_CONFIG_PREFIX .
|
90 |
+
ChoiceAI_Searchcore_Helper_Constants::CONFIG_SEPARATOR .
|
91 |
+
$config,
|
92 |
+
'websites',
|
93 |
+
(int)$website->getWebsiteId());
|
94 |
+
}
|
95 |
+
Mage::getResourceModel('choiceai_searchcore/config')->deleteAll($website->getWebsiteId());
|
96 |
+
|
97 |
+
}
|
98 |
+
|
99 |
+
public function validateKeyParams($requestBody)
|
100 |
+
{
|
101 |
+
$errors = array();
|
102 |
+
$requestParams = json_decode($requestBody, true);
|
103 |
+
if (!$requestParams) {
|
104 |
+
Mage::helper('choiceai_searchcore')->log(Zend_Log::ERR, 'Invalid request with requestBody' . $requestBody);
|
105 |
+
$errors['message'] = 'Invalid Request';
|
106 |
+
return $errors;
|
107 |
+
}
|
108 |
+
if (!array_key_exists(ChoiceAI_Searchcore_Helper_Constants::SECRET_KEY, $requestParams)) {
|
109 |
+
$errors[ChoiceAI_Searchcore_Helper_Constants::SECRET_KEY] = "Has Empty Data";
|
110 |
+
}
|
111 |
+
if (!array_key_exists(ChoiceAI_Searchcore_Helper_Constants::SITE_KEY, $requestParams)) {
|
112 |
+
$errors[ChoiceAI_Searchcore_Helper_Constants::SITE_KEY] = "Has Empty Data";
|
113 |
+
}
|
114 |
+
return $errors;
|
115 |
+
}
|
116 |
+
|
117 |
+
public function getFeatureFields()
|
118 |
+
{
|
119 |
+
return ChoiceAI_Searchcore_Model_Field::$feature_fields;
|
120 |
+
}
|
121 |
+
|
122 |
+
public function getAllAttributes($fieldNameAsKey = false)
|
123 |
+
{
|
124 |
+
$attributes = Mage::getSingleton('eav/config')
|
125 |
+
->getEntityType(Mage_Catalog_Model_Product::ENTITY)->getAttributeCollection();
|
126 |
+
$fields = array();
|
127 |
+
foreach ($attributes as $attribute) {
|
128 |
+
$attributeType = $attribute->getFrontendInput();
|
129 |
+
$fieldType = $attributeType == 'media_image' ? ChoiceAI_Searchcore_Helper_Constants::FIELD_TYPE_IMAGE :
|
130 |
+
($attributeType == 'price' ? ChoiceAI_Searchcore_Helper_Constants::FIELD_TYPE_NUMBER :
|
131 |
+
($attributeType == 'date' ? ChoiceAI_Searchcore_Helper_Constants::FIELD_TYPE_DATE :
|
132 |
+
ChoiceAI_Searchcore_Helper_Constants::FIELD_TYPE_STRING));
|
133 |
+
$fieldType = ($attribute->getName() == "created_at") ? ChoiceAI_Searchcore_Helper_Constants::FIELD_TYPE_DATE : $fieldType;
|
134 |
+
$fieldType = ($attribute->getName() == "updated_at") ? ChoiceAI_Searchcore_Helper_Constants::FIELD_TYPE_DATE : $fieldType;
|
135 |
+
if ($fieldNameAsKey) {
|
136 |
+
$fields[$attribute->getName()] = array(ChoiceAI_Searchcore_Helper_Constants::FIELD_NAME => $attribute->getName(),
|
137 |
+
ChoiceAI_Searchcore_Helper_Constants::FIELD_TYPE => $fieldType);
|
138 |
+
} else {
|
139 |
+
$fields[] = array(ChoiceAI_Searchcore_Helper_Constants::FIELD_NAME => $attribute->getName(),
|
140 |
+
ChoiceAI_Searchcore_Helper_Constants::FIELD_TYPE => $fieldType);
|
141 |
+
}
|
142 |
+
}
|
143 |
+
if ($fieldNameAsKey) {
|
144 |
+
$fields['final_price'] = array(ChoiceAI_Searchcore_Helper_Constants::FIELD_NAME => "final_price",
|
145 |
+
ChoiceAI_Searchcore_Helper_Constants::FIELD_TYPE => ChoiceAI_Searchcore_Helper_Constants::FIELD_TYPE_NUMBER);
|
146 |
+
$fields['type_id'] = array(ChoiceAI_Searchcore_Helper_Constants::FIELD_NAME => "type_id",
|
147 |
+
ChoiceAI_Searchcore_Helper_Constants::FIELD_TYPE => ChoiceAI_Searchcore_Helper_Constants::FIELD_TYPE_STRING);
|
148 |
+
} else {
|
149 |
+
$fields[] = array(ChoiceAI_Searchcore_Helper_Constants::FIELD_NAME => "final_price",
|
150 |
+
ChoiceAI_Searchcore_Helper_Constants::FIELD_TYPE => ChoiceAI_Searchcore_Helper_Constants::FIELD_TYPE_NUMBER);
|
151 |
+
$fields[] = array(ChoiceAI_Searchcore_Helper_Constants::FIELD_NAME => "type_id",
|
152 |
+
ChoiceAI_Searchcore_Helper_Constants::FIELD_TYPE => ChoiceAI_Searchcore_Helper_Constants::FIELD_TYPE_STRING);
|
153 |
+
}
|
154 |
+
return $fields;
|
155 |
+
}
|
156 |
+
|
157 |
+
private function getFieldMapping($fields)
|
158 |
+
{
|
159 |
+
$fieldMapping = array();
|
160 |
+
foreach ($fields as $field) {
|
161 |
+
$fieldMapping[$field->getFieldName()] = $field;
|
162 |
+
}
|
163 |
+
return $fieldMapping;
|
164 |
+
}
|
165 |
+
|
166 |
+
/**
|
167 |
+
* @param $fields
|
168 |
+
* @return array
|
169 |
+
*/
|
170 |
+
private function validate($fields)
|
171 |
+
{
|
172 |
+
$errors = array();
|
173 |
+
if (!is_array($fields)) {
|
174 |
+
$errors["message"] = "Expecting theInput data should be an array, Given " . gettype($fields);
|
175 |
+
return $errors;
|
176 |
+
}
|
177 |
+
$existingAttributes = $this->getAllAttributes(true);
|
178 |
+
$featureFields = Mage::getModel('choiceai_searchcore/field')->getFeaturedFields();
|
179 |
+
foreach ($fields as $field) {
|
180 |
+
if (!array_key_exists(ChoiceAI_Searchcore_Model_Field::field_name, $field)) {
|
181 |
+
$errors["extra"] = "Not Present for all the fields";
|
182 |
+
continue;
|
183 |
+
} else if (is_null($field[ChoiceAI_Searchcore_Model_Field::field_name]) ||
|
184 |
+
$field[ChoiceAI_Searchcore_Model_Field::field_name] == ""
|
185 |
+
) {
|
186 |
+
$errors["extra"] = "field Name is empty for some fields";
|
187 |
+
continue;
|
188 |
+
}
|
189 |
+
if (!array_key_exists(ChoiceAI_Searchcore_Model_Field::datatype, $field)) {
|
190 |
+
$errors[$field[ChoiceAI_Searchcore_Model_Field::field_name]] = "Not Present for all the fields";
|
191 |
+
} else if (!in_array($field[ChoiceAI_Searchcore_Model_Field::datatype], ChoiceAI_Searchcore_Model_Field::$data_types)) {
|
192 |
+
Mage::helper('choiceai_searchcore')->log(Zend_Log::ERR, 'Invalid feature field ' .
|
193 |
+
$field[ChoiceAI_Searchcore_Model_Field::datatype]);
|
194 |
+
$errors[$field[ChoiceAI_Searchcore_Model_Field::field_name]] = "Invalid datatype specified";
|
195 |
+
}
|
196 |
+
|
197 |
+
if (array_key_exists($field[ChoiceAI_Searchcore_Model_Field::field_name], $existingAttributes)) {
|
198 |
+
if (!Mage::getSingleton('choiceai_searchcore/field')->validateDatatype($field[ChoiceAI_Searchcore_Model_Field::datatype], $existingAttributes[$field[ChoiceAI_Searchcore_Model_Field::field_name]][ChoiceAI_Searchcore_Helper_Constants::FIELD_TYPE])) {
|
199 |
+
$errors[$field[ChoiceAI_Searchcore_Model_Field::field_name]] = "Field cannot be mapped to " . $field[ChoiceAI_Searchcore_Model_Field::datatype];
|
200 |
+
}
|
201 |
+
}
|
202 |
+
|
203 |
+
if (array_key_exists(ChoiceAI_Searchcore_Model_Field::featured_field, $field)) {
|
204 |
+
if (!array_key_exists($field[ChoiceAI_Searchcore_Model_Field::featured_field], $featureFields)) {
|
205 |
+
Mage::helper('choiceai_searchcore')->log(Zend_Log::ERR, 'Invalid feature field ' .
|
206 |
+
$field[ChoiceAI_Searchcore_Model_Field::featured_field]);
|
207 |
+
$errors[$field[ChoiceAI_Searchcore_Model_Field::field_name]] = "Invalid feature field specified";
|
208 |
+
} else if (!Mage::getSingleton('choiceai_searchcore/field')->validateDatatype($featureFields[$field[ChoiceAI_Searchcore_Model_Field::featured_field]]["datatype"], $existingAttributes[$field[ChoiceAI_Searchcore_Model_Field::field_name]][ChoiceAI_Searchcore_Helper_Constants::FIELD_TYPE])) {
|
209 |
+
$errors[$field[ChoiceAI_Searchcore_Model_Field::field_name]] = "Field cannot be mapped to " . $field[ChoiceAI_Searchcore_Model_Field::datatype];
|
210 |
+
}
|
211 |
+
}
|
212 |
+
}
|
213 |
+
return $errors;
|
214 |
+
}
|
215 |
+
|
216 |
+
public function deleteFields($fields, $website)
|
217 |
+
{
|
218 |
+
$errors = $this->validate($fields);
|
219 |
+
if (sizeof($errors) != 0) {
|
220 |
+
return $errors;
|
221 |
+
}
|
222 |
+
$collection = $this->buildFieldCollection($fields, $website);
|
223 |
+
return Mage::getModel("choiceai_searchcore/field")->saveFields($collection);
|
224 |
+
}
|
225 |
+
|
226 |
+
/**
|
227 |
+
* @param $fields
|
228 |
+
* @param $website
|
229 |
+
* @return array
|
230 |
+
*/
|
231 |
+
public function saveFields($fields, $website)
|
232 |
+
{
|
233 |
+
$errors = $this->validate($fields);
|
234 |
+
if (sizeof($errors) != 0) {
|
235 |
+
return $errors;
|
236 |
+
}
|
237 |
+
$collection = $this->buildFieldCollectionToAdd($fields, $website);
|
238 |
+
$response = Mage::getModel("choiceai_searchcore/field")->saveFields($collection);
|
239 |
+
if (!is_array($response) && $response === true) {
|
240 |
+
Mage::getSingleton('choiceai_searchcore/field')->rebuildConfigCache($website);
|
241 |
+
$this->triggerUpdateFeatureField($website);
|
242 |
+
}
|
243 |
+
}
|
244 |
+
|
245 |
+
|
246 |
+
public function triggerUpdateFeatureField(Mage_Core_Model_Website $website)
|
247 |
+
{
|
248 |
+
Mage::getResourceModel('choiceai_searchcore/config')
|
249 |
+
->setValue($website->getWebsiteId(),
|
250 |
+
ChoiceAI_Searchcore_Helper_Constants::NEED_FEATURE_FIELD_UPDATION,
|
251 |
+
ChoiceAI_Searchcore_Helper_Constants::NEED_FEATURE_FIELD_UPDATION_TRUE);
|
252 |
+
$this->triggerFeedUpload($website);
|
253 |
+
}
|
254 |
+
|
255 |
+
/**
|
256 |
+
* Method to trigger feed upload
|
257 |
+
* @param Mage_Core_Model_Website $website
|
258 |
+
* @return void
|
259 |
+
*/
|
260 |
+
public function triggerFeedUpload(Mage_Core_Model_Website $website)
|
261 |
+
{
|
262 |
+
Mage::getModel('choiceai_searchcore/api_task_triggerfeedupload')
|
263 |
+
->prepare($website)
|
264 |
+
->process();
|
265 |
+
}
|
266 |
+
|
267 |
+
|
268 |
+
private function getFeatureFieldToFieldMapping($fields)
|
269 |
+
{
|
270 |
+
$featureFieldToFieldMapping = array();
|
271 |
+
foreach ($fields as $field) {
|
272 |
+
if ($field instanceof ChoiceAI_Searchcore_Model_Field &&
|
273 |
+
$field->hasData(ChoiceAI_Searchcore_Model_Field::featured_field) &&
|
274 |
+
!is_null($field->getData(ChoiceAI_Searchcore_Model_Field::featured_field))
|
275 |
+
) {
|
276 |
+
$featureFieldToFieldMapping[$field[ChoiceAI_Searchcore_Model_Field::featured_field]] = $field;
|
277 |
+
}
|
278 |
+
}
|
279 |
+
return $featureFieldToFieldMapping;
|
280 |
+
}
|
281 |
+
|
282 |
+
private function buildFieldCollection($fields, $website)
|
283 |
+
{
|
284 |
+
$collection = array();
|
285 |
+
$fieldMapping = $this->getFieldMapping($this->getFields($fields, $website));
|
286 |
+
foreach ($fields as $field) {
|
287 |
+
if (!array_key_exists(ChoiceAI_Searchcore_Model_Field::field_name, $field)) {
|
288 |
+
continue;
|
289 |
+
}
|
290 |
+
if (array_key_exists($field[ChoiceAI_Searchcore_Model_Field::field_name], $fieldMapping)) {
|
291 |
+
$collection[]["delete"] = $fieldMapping[$field[ChoiceAI_Searchcore_Model_Field::field_name]];
|
292 |
+
}
|
293 |
+
}
|
294 |
+
return $collection;
|
295 |
+
}
|
296 |
+
|
297 |
+
private function buildFieldCollectionToAdd($fields, $website)
|
298 |
+
{
|
299 |
+
$collection = array();
|
300 |
+
$fieldMapping = $this->getFieldMapping($this->getFields($fields, $website));
|
301 |
+
$featureFieldToFieldMapping = $this->getFeatureFieldToFieldMapping($fieldMapping);
|
302 |
+
|
303 |
+
foreach ($fields as $field) {
|
304 |
+
if (!array_key_exists(ChoiceAI_Searchcore_Model_Field::field_name, $field)) {
|
305 |
+
continue;
|
306 |
+
}
|
307 |
+
/*
|
308 |
+
All possible test cases
|
309 |
+
1) if field name is present and it was a feature field
|
310 |
+
1.a) if request feature field is equal to selected feature field, dont do anything
|
311 |
+
1.b) if request feature field is not equal to selected feature field, dont do anything
|
312 |
+
1.c) if request field is not a feature field,
|
313 |
+
remove the field name entry from the feature field row, save as different row.
|
314 |
+
|
315 |
+
2) if field name is present and it was not a feature field
|
316 |
+
2.a) if request field is a feature field,
|
317 |
+
remove the field name entry as a normal field and save as feature field
|
318 |
+
2.b) if request field is not a feature field,
|
319 |
+
update the existing field
|
320 |
+
|
321 |
+
3) if field name not present,
|
322 |
+
3.a) if it has feature field, delete it from db and insert the new field
|
323 |
+
3.b) save as a new field
|
324 |
+
*/
|
325 |
+
|
326 |
+
// case 1
|
327 |
+
if (array_key_exists($field[ChoiceAI_Searchcore_Model_Field::field_name], $fieldMapping) &&
|
328 |
+
$fieldMapping[$field[ChoiceAI_Searchcore_Model_Field::field_name]]->hasData(ChoiceAI_Searchcore_Model_Field::featured_field) &&
|
329 |
+
!is_null($fieldMapping[$field[ChoiceAI_Searchcore_Model_Field::field_name]]->getData(ChoiceAI_Searchcore_Model_Field::featured_field))
|
330 |
+
) {
|
331 |
+
//case 1 a)
|
332 |
+
if (array_key_exists(ChoiceAI_Searchcore_Model_Field::featured_field, $field) &&
|
333 |
+
$field[ChoiceAI_Searchcore_Model_Field::featured_field] ==
|
334 |
+
$fieldMapping[$field[ChoiceAI_Searchcore_Model_Field::field_name]][ChoiceAI_Searchcore_Model_Field::featured_field]
|
335 |
+
) {
|
336 |
+
continue;
|
337 |
+
} // case 1 b)
|
338 |
+
else if (array_key_exists(ChoiceAI_Searchcore_Model_Field::featured_field, $field)) {
|
339 |
+
$collection[]["delete"] = $featureFieldToFieldMapping[$field[ChoiceAI_Searchcore_Model_Field::featured_field]];
|
340 |
+
$collection[]["delete"] = $fieldMapping[$field[ChoiceAI_Searchcore_Model_Field::field_name]];
|
341 |
+
$fieldModel = Mage::getModel("choiceai_searchcore/field");
|
342 |
+
$fieldModel->setFeaturedField($field[ChoiceAI_Searchcore_Model_Field::featured_field]);
|
343 |
+
} //case 1 c)
|
344 |
+
else {
|
345 |
+
$collection[]["delete"] = $fieldMapping[$field[ChoiceAI_Searchcore_Model_Field::field_name]];
|
346 |
+
$fieldModel = Mage::getModel("choiceai_searchcore/field");
|
347 |
+
|
348 |
+
}
|
349 |
+
} else if (array_key_exists($field[ChoiceAI_Searchcore_Model_Field::field_name], $fieldMapping)) {
|
350 |
+
//case 2 a)
|
351 |
+
if (array_key_exists(ChoiceAI_Searchcore_Model_Field::featured_field, $field)) {
|
352 |
+
$collection[]["delete"] = $fieldMapping[$field[ChoiceAI_Searchcore_Model_Field::field_name]];
|
353 |
+
$fieldModel = Mage::getModel("choiceai_searchcore/field");
|
354 |
+
$fieldModel->setFeaturedField($field[ChoiceAI_Searchcore_Model_Field::featured_field]);
|
355 |
+
} // case 2 b)
|
356 |
+
else {
|
357 |
+
$fieldModel = $fieldMapping[$field[ChoiceAI_Searchcore_Model_Field::field_name]];
|
358 |
+
}
|
359 |
+
} else {
|
360 |
+
$fieldModel = Mage::getModel("choiceai_searchcore/field");
|
361 |
+
if (array_key_exists(ChoiceAI_Searchcore_Model_Field::featured_field, $field)) {
|
362 |
+
$fieldModel->setFeaturedField($field[ChoiceAI_Searchcore_Model_Field::featured_field]);
|
363 |
+
// case 3 a)
|
364 |
+
if (array_key_exists($field[ChoiceAI_Searchcore_Model_Field::featured_field], $featureFieldToFieldMapping)) {
|
365 |
+
$collection[]["delete"] = $featureFieldToFieldMapping[$field[ChoiceAI_Searchcore_Model_Field::featured_field]];
|
366 |
+
}
|
367 |
+
}
|
368 |
+
|
369 |
+
}
|
370 |
+
$fieldModel->setFieldName($field[ChoiceAI_Searchcore_Model_Field::field_name]);
|
371 |
+
$fieldModel->setDatatype($field[ChoiceAI_Searchcore_Model_Field::datatype]);
|
372 |
+
$fieldModel->setAutosuggest(0);
|
373 |
+
$fieldModel->setWebsiteId($website->getWebsiteId());
|
374 |
+
$fieldModel->setDisplayed(1);
|
375 |
+
$collection[]["add"] = $fieldModel;
|
376 |
+
}
|
377 |
+
return $collection;
|
378 |
+
}
|
379 |
+
|
380 |
+
/**
|
381 |
+
* Method to getFields, if
|
382 |
+
*
|
383 |
+
* @param $fields
|
384 |
+
* @return mixed
|
385 |
+
*/
|
386 |
+
private function getFields($fields, $website)
|
387 |
+
{
|
388 |
+
$inField = array();
|
389 |
+
foreach ($fields as $field) {
|
390 |
+
if ($field[ChoiceAI_Searchcore_Model_Field::field_name] == "") {
|
391 |
+
continue;
|
392 |
+
}
|
393 |
+
$inField[] = "'" . $field[ChoiceAI_Searchcore_Model_Field::field_name] . "'";
|
394 |
+
}
|
395 |
+
$collection = Mage::getResourceModel("choiceai_searchcore/field_collection");
|
396 |
+
|
397 |
+
$collection->getSelect()
|
398 |
+
->where('(' . ChoiceAI_Searchcore_Model_Field::field_name . ' in (' . implode(",", $inField) . ')' . " OR " .
|
399 |
+
ChoiceAI_Searchcore_Model_Field::featured_field . " IS NOT NULL) AND " .
|
400 |
+
ChoiceAI_Searchcore_Model_Field::website_id . " = " . $website->getWebsiteId());
|
401 |
+
return $collection->load();
|
402 |
+
}
|
403 |
+
|
404 |
+
|
405 |
+
/**
|
406 |
+
* Method to update feature fields to choiceai
|
407 |
+
*
|
408 |
+
* @return bool| array
|
409 |
+
*/
|
410 |
+
public function updateFeatureFields(Mage_Core_Model_Website $website)
|
411 |
+
{
|
412 |
+
$response = Mage::getModel("choiceai_searchcore/api_task_updatefeaturefields")
|
413 |
+
->prepare($website)
|
414 |
+
->process();
|
415 |
+
if (!$response->isSuccess()) {
|
416 |
+
Mage::log(Zend_Log::ERR,
|
417 |
+
"Update feature fields failed because of theses errors " . json_encode($response->getErrors()));
|
418 |
+
return $response->getErrors();
|
419 |
+
}
|
420 |
+
return true;
|
421 |
+
}
|
422 |
+
|
423 |
+
public function getNumberOfDocsInChoiceAI(Mage_Core_Model_Website $website)
|
424 |
+
{
|
425 |
+
$response = Mage::getModel('choiceai_searchcore/api_task_feeddetails')
|
426 |
+
->prepare($website)
|
427 |
+
->process();
|
428 |
+
if ($response->isSuccess()) {
|
429 |
+
$response = $response->getResponse();
|
430 |
+
$feedInfo = $response[ChoiceAI_Searchcore_Model_Api_Task_Feeddetails::FEEDINFO];
|
431 |
+
return $feedInfo[ChoiceAI_Searchcore_Model_Api_Task_Feeddetails::NUMDOCS];
|
432 |
+
}
|
433 |
+
return 0;
|
434 |
+
}
|
435 |
+
|
436 |
+
/**
|
437 |
+
* @param Mage_Core_Model_Website $website
|
438 |
+
* @return void
|
439 |
+
*/
|
440 |
+
public function triggerAutoggestIndexing(Mage_Core_Model_Website $website)
|
441 |
+
{
|
442 |
+
if (Mage::helper('core')->isModuleEnabled('ChoiceAI_Searchcore') &&
|
443 |
+
$this->isConfigTrue($website, ChoiceAI_Searchcore_Helper_Constants::AUTOSUGGEST_STATUS)
|
444 |
+
) {
|
445 |
+
//trigger Autosuggest
|
446 |
+
$response = Mage::getModel('choiceai_searchcore/api_task_autosuggestindex')
|
447 |
+
->prepare($website)
|
448 |
+
->process();
|
449 |
+
}
|
450 |
+
}
|
451 |
+
|
452 |
+
public function getCategoryExclusion(Mage_Core_Model_Website $website)
|
453 |
+
{
|
454 |
+
$conf = Mage::helper('choiceai_searchcore')->getEngineConfigData(ChoiceAI_Searchcore_Helper_Constants::EXCLUDE_CATEGORY, $website, true);
|
455 |
+
$categoryExclusionConf = json_decode($conf[ChoiceAI_Searchcore_Helper_Constants::EXCLUDE_CATEGORY], true);
|
456 |
+
if (!is_array($categoryExclusionConf)) {
|
457 |
+
return array();
|
458 |
+
}
|
459 |
+
$categoryToBeExcluded = array();
|
460 |
+
foreach ($categoryExclusionConf as $eachExclusion) {
|
461 |
+
$categoryToBeExcluded[] = (string)$eachExclusion;
|
462 |
+
}
|
463 |
+
return $categoryToBeExcluded;
|
464 |
+
}
|
465 |
+
|
466 |
+
public function getConfigData($name)
|
467 |
+
{
|
468 |
+
return (string)Mage::getConfig()->getNode("default/" . ChoiceAI_Searchcore_Helper_Constants::CHOICEAI_CONFIG_PREFIX . "/" . $name);
|
469 |
+
}
|
470 |
+
}
|
471 |
+
|
472 |
+
?>
|
app/code/local/ChoiceAI/Searchcore/Helper/Constants.php
ADDED
@@ -0,0 +1,195 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @category ChoiceAI
|
5 |
+
* @copyright Copyright (c) MineWhat
|
6 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
7 |
+
*/
|
8 |
+
|
9 |
+
class ChoiceAI_Searchcore_Helper_Constants extends Mage_Core_Helper_Abstract {
|
10 |
+
|
11 |
+
const SITE_KEY = "site_key";
|
12 |
+
|
13 |
+
const API_KEY = "api_key";
|
14 |
+
|
15 |
+
const SECRET_KEY = "secret_key";
|
16 |
+
|
17 |
+
const USERNAME = "username";
|
18 |
+
|
19 |
+
const NEED_FEATURE_FIELD_UPDATION = "need_feature_field_updation";
|
20 |
+
|
21 |
+
const NEED_FEATURE_FIELD_UPDATION_FALSE = '0';
|
22 |
+
|
23 |
+
const NEED_FEATURE_FIELD_UPDATION_TRUE = '1';
|
24 |
+
|
25 |
+
const IS_CRON_ENABLED = "cron_enabled";
|
26 |
+
|
27 |
+
const SUBJECT = 'subject';
|
28 |
+
|
29 |
+
const CONTENT = 'content';
|
30 |
+
|
31 |
+
const CC = 'cc';
|
32 |
+
|
33 |
+
const FILTER = 'filter';
|
34 |
+
|
35 |
+
const FILTER_RANGE_DELIMITER = "|`";
|
36 |
+
|
37 |
+
const FEATURE_FIELD_PRICE = 'price';
|
38 |
+
|
39 |
+
const FEATURE_FIELD_IMAGE_URL = 'imageUrl';
|
40 |
+
|
41 |
+
const FEATURE_FIELD_PRODUCT_URL = 'productUrl';
|
42 |
+
|
43 |
+
const FEATURE_FIELD_CATEGORY = 'category';
|
44 |
+
|
45 |
+
const FEATURE_FIELD_BRAND = 'brand';
|
46 |
+
|
47 |
+
const FEATURE_FIELD_TITLE = 'title';
|
48 |
+
|
49 |
+
const AUTOSUGGEST_STATUS = 'autosuggest_status';
|
50 |
+
|
51 |
+
const AUTOSUGGEST_SKIN = 'autosuggest_skin';
|
52 |
+
|
53 |
+
const AUTOSUGGEST_TEMPLATE = 'autosuggest_template';
|
54 |
+
|
55 |
+
const AUTOSUGGEST_MAX_SUGGESTION = 'autosuggest_max_suggestion';
|
56 |
+
|
57 |
+
const AUTOSUGGEST_TOP_QUERIES_STATUS = 'autosuggest_top_queries_status';
|
58 |
+
|
59 |
+
const AUTOSUGGEST_KEYWORD_STATUS = 'autosuggest_keyword_status';
|
60 |
+
|
61 |
+
const AUTOSUGGEST_SEARCH_SCOPE_STATUS = 'autosuggest_search_scope_status';
|
62 |
+
|
63 |
+
const AUTOSUGGEST_MAX_PRODUCTS = 'autosuggest_max_products';
|
64 |
+
|
65 |
+
const AUTOSUGGEST_POP_PRODUCT_HEADER = 'autosuggest_pop_product_header';
|
66 |
+
|
67 |
+
const AUTOSUGGEST_KEYWORD_HEADER = 'autosuggest_keyword_header';
|
68 |
+
|
69 |
+
const AUTOSUGGEST_TOPQUERY_HEADER = 'autosuggest_topquery_header';
|
70 |
+
|
71 |
+
const AUTOSUGGEST_SEARCH_SCOPE_HEADER = 'autosuggest_search_scope_header';
|
72 |
+
|
73 |
+
const AUTOSUGGEST_SHOW_CART = 'autosuggest_show_cart';
|
74 |
+
|
75 |
+
const AUTOSUGGEST_TEMPLATE_1COLUMN = '1column';
|
76 |
+
|
77 |
+
const AUTOSUGGEST_TEMPLATE_2COLUMN = '2column';
|
78 |
+
|
79 |
+
const AUTOSUGGEST_TEMPLATE_2COLUMN_LEFT = '2column-left';
|
80 |
+
|
81 |
+
const AUTOSUGGEST_TEMPLATE_2COLUMN_RIGHT = '2column-right';
|
82 |
+
|
83 |
+
const AUTOSUGGEST_TEMPLATE_1COLUMN_ADD_TO_CART = '1column-addToCart';
|
84 |
+
|
85 |
+
const AUTOSUGGEST_SIDECONTENT = 'autosuggest_sidecontent';
|
86 |
+
|
87 |
+
const AUTOSUGGEST_SIDECONTENT_RIGHT = 'right';
|
88 |
+
|
89 |
+
const AUTOSUGGEST_SIDECONTENT_LEFT = 'left';
|
90 |
+
|
91 |
+
const AUTOSUGGEST_INQUERY = "inFields";
|
92 |
+
|
93 |
+
const AUTOSUGGEST_KEYWORDSUGGESTION = "keywordSuggestions";
|
94 |
+
|
95 |
+
const AUTOSUGGEST_TOP_QUERY = "topQueries";
|
96 |
+
|
97 |
+
const AUTOSUGGEST_POP_PRODUCTS = "popularProducts";
|
98 |
+
|
99 |
+
const AUTOSUGGEST_MAIN_TEMPLATE = 'mainTpl';
|
100 |
+
|
101 |
+
const AUTOSUGGET_SIDE_TEMPLATE = 'sideTpl';
|
102 |
+
|
103 |
+
static $AUTOSUGGEST_SIDECONTENTS = array(self::AUTOSUGGEST_SIDECONTENT_RIGHT, self::AUTOSUGGEST_SIDECONTENT_LEFT);
|
104 |
+
|
105 |
+
static $AUTOSUGGEST_TEMPLATES = array(self::AUTOSUGGEST_TEMPLATE_1COLUMN, self::AUTOSUGGEST_TEMPLATE_2COLUMN);
|
106 |
+
|
107 |
+
const SEARCH_MOD_STATUS = 'search_mod_status';
|
108 |
+
|
109 |
+
const SEARCH_MOD_POWER = 'search_mod_power';
|
110 |
+
|
111 |
+
const SEARCH_HOSTED_STATUS = 'search_hosted_status';
|
112 |
+
|
113 |
+
const SEARCH_HOSTED_INT_STATUS = 'search_hosted_int_status';
|
114 |
+
|
115 |
+
const SEARCH_HOSTED_INT_COMPLETE = 'complete';
|
116 |
+
|
117 |
+
const SEARCH_HOSTED_INT_PROCESSING = 'processing';
|
118 |
+
|
119 |
+
const SEARCH_HOSTED_REDIRECT_URL = 'search_hosted_redirect_url';
|
120 |
+
|
121 |
+
const HOSTED_SEARCH_STATUS = 'hosted_search_status';
|
122 |
+
|
123 |
+
const CHOICEAI_CONFIG_PREFIX = 'choiceai/general';
|
124 |
+
|
125 |
+
const CONFIG_SEPARATOR = '/';
|
126 |
+
|
127 |
+
const SEARCH_POWER_LABEL = 'search';
|
128 |
+
|
129 |
+
const NAVIGATION_POWER_LABEL = 'navigation';
|
130 |
+
|
131 |
+
const ALL_POWER_LABEL = 'all';
|
132 |
+
|
133 |
+
const TRUE = "true";
|
134 |
+
|
135 |
+
const FALSE = "false";
|
136 |
+
|
137 |
+
const FIELD_NAME = 'field_name';
|
138 |
+
|
139 |
+
const FIELD_TYPE = 'field_type';
|
140 |
+
|
141 |
+
const FIELD_TYPE_STRING = 'string';
|
142 |
+
|
143 |
+
const FIELD_TYPE_IMAGE = 'image';
|
144 |
+
|
145 |
+
const FIELD_TYPE_NUMBER = 'number';
|
146 |
+
|
147 |
+
const FIELD_TYPE_DATE = 'date';
|
148 |
+
|
149 |
+
const CHOICEAI_DATATYPE_TEXT = "text";
|
150 |
+
|
151 |
+
const CHOICEAI_DATATYPE_LONGTEXT = "longText";
|
152 |
+
|
153 |
+
const CHOICEAI_DATATYPE_LINK = "link";
|
154 |
+
|
155 |
+
const CHOICEAI_DATATYPE_NUMBER = "number";
|
156 |
+
|
157 |
+
const CHOICEAI_DATATYPE_DECIMAL = "decimal";
|
158 |
+
|
159 |
+
const CHOICEAI_DATATYPE_DATE = "date";
|
160 |
+
|
161 |
+
const CHOICEAI_DATATYPE_BOOL = "bool";
|
162 |
+
|
163 |
+
const CHOICEAI_DATATYPE_SKU = "sku";
|
164 |
+
|
165 |
+
const FIELD_CONF = 'field_conf';
|
166 |
+
|
167 |
+
const INCLUDE_OUT_OF_STOCK = 'include_out_of_stock';
|
168 |
+
|
169 |
+
const INCLUDE_CHILD_PRODUCT = 'include_child_product';
|
170 |
+
|
171 |
+
const INCLUDE_ENABLED_CHILD_PRODUCT = 'include_only_enabled_child_product';
|
172 |
+
|
173 |
+
const INCLUDE_OUT_OF_STOCK_CHILD_PRODUCT = 'include_out_of_stock_child_product';
|
174 |
+
|
175 |
+
const INCLUDE_OUT_OF_STOCK_FROM_NON_CACHE = "include_out_of_stock_from_non_cache";
|
176 |
+
|
177 |
+
const INCLUDE_TAXONOMY_NODES = "include_taxonomy_nodes";
|
178 |
+
|
179 |
+
const INCLUDE_TAXONOMY_MAPPING = "include_taxonomy_mapping";
|
180 |
+
|
181 |
+
const FEED_STATUS_UPLOADING = 'UPLOADING';
|
182 |
+
|
183 |
+
const FEED_STATUS_UPLOADED_SUCCESSFULLY = 'UPLOADED SUCCESSFUL';
|
184 |
+
|
185 |
+
const FEED_STATUS_UPLOADED_FAILED = 'FAILED';
|
186 |
+
|
187 |
+
const EXCLUDE_CATEGORY = 'exclude_category';
|
188 |
+
|
189 |
+
const AUTH_TOKEN = 'auth_token';
|
190 |
+
|
191 |
+
const AUTH_REQUEST_PARAM = 'auth';
|
192 |
+
|
193 |
+
const LAST_UPLOAD_TIME = 'lastUpload';
|
194 |
+
|
195 |
+
}
|
app/code/local/ChoiceAI/Searchcore/Helper/Data.php
ADDED
@@ -0,0 +1,233 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @category ChoiceAI
|
5 |
+
* @package ChoiceAI_Searchcore
|
6 |
+
* @copyright Copyright (c) MineWhat
|
7 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
*/
|
9 |
+
class ChoiceAI_Searchcore_Helper_Data extends Mage_Core_Helper_Abstract {
|
10 |
+
|
11 |
+
const LOG_FILE = "choiceai_searchcore.log";
|
12 |
+
|
13 |
+
/**
|
14 |
+
* array field which stores the config
|
15 |
+
*
|
16 |
+
* @var array
|
17 |
+
*/
|
18 |
+
public $engineConfigData = NULL;
|
19 |
+
|
20 |
+
/**
|
21 |
+
* Method to log
|
22 |
+
*
|
23 |
+
* @param int $level
|
24 |
+
* @param string $message
|
25 |
+
*/
|
26 |
+
public function log($level, $message) {
|
27 |
+
Mage::log($message, $level, static::LOG_FILE, true);
|
28 |
+
}
|
29 |
+
|
30 |
+
/**
|
31 |
+
* Returns search engine config data.
|
32 |
+
*
|
33 |
+
* @param string $prefix
|
34 |
+
* @param mixed $store
|
35 |
+
* @return array
|
36 |
+
*/
|
37 |
+
public function getEngineConfigData($prefix = '', Mage_Core_Model_Website $website = null, $original = false)
|
38 |
+
{
|
39 |
+
if(is_null($website)) {
|
40 |
+
$website = Mage::app()->getWebsite();
|
41 |
+
}
|
42 |
+
$originalConfig = array();
|
43 |
+
if($original) {
|
44 |
+
$originalConfig = $this->getOriginalValue($prefix, $website);
|
45 |
+
}
|
46 |
+
if(is_null($this->engineConfigData)) {
|
47 |
+
$this->engineConfigData = Mage::getConfig()
|
48 |
+
->getNode(ChoiceAI_Searchcore_Helper_Constants::CHOICEAI_CONFIG_PREFIX, 'websites',
|
49 |
+
(int)$website->getWebsiteId());
|
50 |
+
}
|
51 |
+
|
52 |
+
if (!$this->engineConfigData) {
|
53 |
+
return false;
|
54 |
+
}
|
55 |
+
if ($this->engineConfigData->hasChildren()) {
|
56 |
+
$value = array();
|
57 |
+
foreach ($this->engineConfigData->asArray() as $k=>$v) {
|
58 |
+
if ($prefix != '' && preg_match("#^{$prefix}(.*)#", $k, $matches)) {
|
59 |
+
$value[$k] = $v;
|
60 |
+
}
|
61 |
+
}
|
62 |
+
} else {
|
63 |
+
$value = (string)$this->engineConfigData;
|
64 |
+
}
|
65 |
+
return array_merge($value,$originalConfig);
|
66 |
+
|
67 |
+
}
|
68 |
+
|
69 |
+
public function getOriginalValue($prefix = '', Mage_Core_Model_Website $website) {
|
70 |
+
$configDataCollection = Mage::getModel('core/config_data')
|
71 |
+
->getCollection()
|
72 |
+
->addScopeFilter('websites', (int)$website->getWebsiteId(), ChoiceAI_Searchcore_Helper_Constants::CHOICEAI_CONFIG_PREFIX)
|
73 |
+
->load();
|
74 |
+
$value =array();
|
75 |
+
foreach($configDataCollection as $data) {
|
76 |
+
$path = $data->getPath();
|
77 |
+
if (substr($path, 0, strlen(ChoiceAI_Searchcore_Helper_Constants::CHOICEAI_CONFIG_PREFIX)) == ChoiceAI_Searchcore_Helper_Constants::CHOICEAI_CONFIG_PREFIX) {
|
78 |
+
$path = substr($path, strlen(ChoiceAI_Searchcore_Helper_Constants::CHOICEAI_CONFIG_PREFIX) +1);
|
79 |
+
}
|
80 |
+
if ($prefix != '' && preg_match("#^{$prefix}(.*)#", $path, $matches)) {
|
81 |
+
$value[$path] = $data->getValue();
|
82 |
+
}
|
83 |
+
}
|
84 |
+
return $value;
|
85 |
+
}
|
86 |
+
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Method to validate the config save allowed
|
90 |
+
* @param Mage_Core_Model_Website $website
|
91 |
+
* @param $configName
|
92 |
+
* @param $origData
|
93 |
+
* @return string | null
|
94 |
+
*/
|
95 |
+
public function isConfigSaveAllowed(Mage_Core_Model_Website $website, $configName, $value, $origData = true) {
|
96 |
+
if(is_null($value) || is_array($value) || is_object($value)){
|
97 |
+
return "Invalid Value given";
|
98 |
+
}
|
99 |
+
if($configName == ChoiceAI_Searchcore_Helper_Constants::SEARCH_HOSTED_STATUS && $value == ChoiceAI_Searchcore_Helper_Constants::TRUE && $this->isConfigTrue($website, ChoiceAI_Searchcore_Helper_Constants::SEARCH_MOD_STATUS, $origData)) {
|
100 |
+
return "Module search is on";
|
101 |
+
}
|
102 |
+
if($configName == ChoiceAI_Searchcore_Helper_Constants::SEARCH_MOD_STATUS && $value == ChoiceAI_Searchcore_Helper_Constants::TRUE && $this->isConfigTrue($website, ChoiceAI_Searchcore_Helper_Constants::SEARCH_HOSTED_STATUS, $origData)) {
|
103 |
+
return "Hosted search is on";
|
104 |
+
}
|
105 |
+
|
106 |
+
return null;
|
107 |
+
}
|
108 |
+
|
109 |
+
|
110 |
+
/**
|
111 |
+
* @param Mage_Core_Model_Website $website
|
112 |
+
* @param $data
|
113 |
+
* @return void
|
114 |
+
*/
|
115 |
+
public function saveConfig(Mage_Core_Model_Website $website, $data) {
|
116 |
+
foreach($data as $key => $value) {
|
117 |
+
if(!is_null($this->isConfigSaveAllowed($website, $key, $value, true)))
|
118 |
+
continue;
|
119 |
+
Mage::getConfig()
|
120 |
+
->saveConfig(ChoiceAI_Searchcore_Helper_Constants::CHOICEAI_CONFIG_PREFIX .
|
121 |
+
ChoiceAI_Searchcore_Helper_Constants::CONFIG_SEPARATOR .
|
122 |
+
$key,
|
123 |
+
(string)$value,
|
124 |
+
'websites',
|
125 |
+
(int)$website->getWebsiteId());
|
126 |
+
}
|
127 |
+
}
|
128 |
+
|
129 |
+
public function isConfigTrue(Mage_Core_Model_Website $website, $configName, $origData = false) {
|
130 |
+
$configData = $this->getEngineConfigData($configName, $website, $origData);
|
131 |
+
return array_key_exists($configName, $configData) &&
|
132 |
+
$configData[$configName] == ChoiceAI_Searchcore_Helper_Constants::TRUE;
|
133 |
+
}
|
134 |
+
|
135 |
+
/*
|
136 |
+
* returns the choiceai site name
|
137 |
+
* @return String
|
138 |
+
*/
|
139 |
+
public function getSiteName(){
|
140 |
+
$siteKeyLabel = ChoiceAI_Searchcore_Helper_Constants::SITE_KEY;
|
141 |
+
$config = $this->getEngineConfigData($siteKeyLabel);
|
142 |
+
if(array_key_exists($siteKeyLabel, $config) && $config[$siteKeyLabel] != "")
|
143 |
+
return $config[$siteKeyLabel];
|
144 |
+
else {
|
145 |
+
$siteKey = Mage::getResourceModel('choiceai_searchcore/config')
|
146 |
+
->getValue(Mage::app()->getWebsite()->getWebsiteId(),
|
147 |
+
$siteKeyLabel);
|
148 |
+
if(isset($siteKey) && $siteKey != ''){
|
149 |
+
$this->saveConfig(Mage::app()->getWebsite(),
|
150 |
+
array($siteKeyLabel => $siteKey));
|
151 |
+
return $siteKey;
|
152 |
+
} else {
|
153 |
+
if(Mage::getIsDeveloperMode()) {
|
154 |
+
Mage::throwException("ChoiceAI site key is empty");
|
155 |
+
} else {
|
156 |
+
Mage::helper('choiceai_searchcore')->log(Zend_Log::ERR, 'ChoiceAI site key is not set');
|
157 |
+
return null;
|
158 |
+
}
|
159 |
+
}
|
160 |
+
}
|
161 |
+
}
|
162 |
+
|
163 |
+
/*
|
164 |
+
* returns the choiceai api Key
|
165 |
+
* @return String
|
166 |
+
*/
|
167 |
+
public function getApiKey(){
|
168 |
+
$apiKeyLabel = ChoiceAI_Searchcore_Helper_Constants::API_KEY;
|
169 |
+
$config = $this->getEngineConfigData($apiKeyLabel);
|
170 |
+
if(array_key_exists($apiKeyLabel, $config) && $config[$apiKeyLabel] != "")
|
171 |
+
return $config[$apiKeyLabel];
|
172 |
+
else {
|
173 |
+
$apiKey = Mage::getResourceModel('choiceai_searchcore/config')
|
174 |
+
->getValue(Mage::app()->getWebsite()->getWebsiteId(), $apiKeyLabel);
|
175 |
+
if(isset($apiKey) && $apiKey != ''){
|
176 |
+
$this->saveConfig(Mage::app()->getWebsite(),
|
177 |
+
array($apiKeyLabel => $apiKey));
|
178 |
+
return $apiKey;
|
179 |
+
} else {
|
180 |
+
if(Mage::getIsDeveloperMode()) {
|
181 |
+
Mage::throwException("ChoiceAI api key is empty");
|
182 |
+
} else {
|
183 |
+
Mage::helper('choiceai_searchcore')->log(Zend_Log::ERR, 'ChoiceAI Api key is not set');
|
184 |
+
return null;
|
185 |
+
}
|
186 |
+
}
|
187 |
+
}
|
188 |
+
}
|
189 |
+
|
190 |
+
/*
|
191 |
+
* decides which module should be given more priority based on the version
|
192 |
+
* @return boolean
|
193 |
+
*/
|
194 |
+
public function isExecutable() {
|
195 |
+
if(Mage::helper('core')->isModuleEnabled('ChoiceAI_Recscore')){
|
196 |
+
$otherModuleVersion = floatval(Mage::getConfig()->getModuleConfig("ChoiceAI_Recscore")->version);
|
197 |
+
$currentModuleVersion = floatval(Mage::getConfig()->getModuleConfig("ChoiceAI_Searchcore")->version);
|
198 |
+
if($this->version_compare($otherModuleVersion, $currentModuleVersion) > 0) {
|
199 |
+
return false;
|
200 |
+
} else if($this->version_compare($otherModuleVersion, $currentModuleVersion) == 0) {
|
201 |
+
return false;
|
202 |
+
}
|
203 |
+
|
204 |
+
}
|
205 |
+
return true;
|
206 |
+
}
|
207 |
+
|
208 |
+
//Compare two sets of versions, where major/minor/etc. releases are separated by dots.
|
209 |
+
//Returns 0 if both are equal, 1 if A > B, and -1 if B < A.
|
210 |
+
public function version_compare($a, $b)
|
211 |
+
{
|
212 |
+
$a = explode(".", rtrim($a, ".0")); //Split version into pieces and remove trailing .0
|
213 |
+
$b = explode(".", rtrim($b, ".0")); //Split version into pieces and remove trailing .0
|
214 |
+
foreach ($a as $depth => $aVal)
|
215 |
+
{ //Iterate over each piece of A
|
216 |
+
if (isset($b[$depth]))
|
217 |
+
{ //If B matches A to this depth, compare the values
|
218 |
+
if ($aVal > $b[$depth]) return 1; //Return A > B
|
219 |
+
else if ($aVal < $b[$depth]) return -1; //Return B > A
|
220 |
+
//An equal result is inconclusive at this point
|
221 |
+
}
|
222 |
+
else
|
223 |
+
{ //If B does not match A to this depth, then A comes after B in sort order
|
224 |
+
return 1; //so return A > B
|
225 |
+
}
|
226 |
+
}
|
227 |
+
//At this point, we know that to the depth that A and B extend to, they are equivalent.
|
228 |
+
//Either the loop ended because A is shorter than B, or both are equal.
|
229 |
+
return (count($a) < count($b)) ? -1 : 0;
|
230 |
+
}
|
231 |
+
|
232 |
+
}
|
233 |
+
?>
|
app/code/local/ChoiceAI/Searchcore/Helper/Feedhelper.php
ADDED
@@ -0,0 +1,288 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @category ChoiceAI
|
5 |
+
* @package ChoiceAI_Searchcore
|
6 |
+
* @copyright Copyright (c) MineWhat
|
7 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
*/
|
9 |
+
|
10 |
+
class ChoiceAI_Searchcore_Helper_Feedhelper extends ChoiceAI_Searchcore_Helper_Data {
|
11 |
+
|
12 |
+
var $categoryMap;
|
13 |
+
|
14 |
+
var $catlevel1List;
|
15 |
+
|
16 |
+
var $attributeToTypeMap;
|
17 |
+
|
18 |
+
var $_rootCategoryIds = array();
|
19 |
+
|
20 |
+
var $_filters;
|
21 |
+
|
22 |
+
protected function array_match($needle, $haystack) {
|
23 |
+
if(!is_array($needle)) {
|
24 |
+
return in_array($needle, $haystack);
|
25 |
+
}
|
26 |
+
|
27 |
+
foreach($needle as $eachNeedle) {
|
28 |
+
if(in_array($eachNeedle, $haystack)) {
|
29 |
+
return true;
|
30 |
+
}
|
31 |
+
}
|
32 |
+
return false;
|
33 |
+
}
|
34 |
+
|
35 |
+
public function getAllFilterableAttributes(Mage_Core_Model_Website $website) {
|
36 |
+
|
37 |
+
$filterableAttributes = array();
|
38 |
+
$stores = $website->getStores();
|
39 |
+
$this->tempCategoriesScanned = array();
|
40 |
+
foreach($stores as $store) {
|
41 |
+
Mage::app()->setCurrentStore($store);
|
42 |
+
$categoryId = $store->getRootCategoryId();
|
43 |
+
$category = Mage::getModel('catalog/category')->load($categoryId);
|
44 |
+
$this->tempCategoriesScanned[] = $categoryId;
|
45 |
+
$filterableAttributes = array_merge($filterableAttributes, $this->getFilterableAttributesForCategory($category));
|
46 |
+
}
|
47 |
+
return array_unique($filterableAttributes);
|
48 |
+
}
|
49 |
+
|
50 |
+
public function getFilterableAttributesForCategory($category) {
|
51 |
+
if(array_key_exists($category->getId(), $this->tempCategoriesScanned)) {
|
52 |
+
return array();
|
53 |
+
} else {
|
54 |
+
$this->tempCategoriesScanned[] = $category->getId();
|
55 |
+
}
|
56 |
+
$filterableAttributes = array();
|
57 |
+
$layer = Mage::getModel("catalog/layer");
|
58 |
+
$layer->setCurrentCategory($category);
|
59 |
+
$attributes = $layer->getFilterableAttributes();
|
60 |
+
foreach ($attributes as $attribute) {
|
61 |
+
$filterableAttributes[] = $attribute->getAttributeCode();
|
62 |
+
}
|
63 |
+
$childrenCategoryIds = $category->getAllChildren();
|
64 |
+
$childrenCategories = Mage::getModel('catalog/category')->getCollection()->addIdFilter($childrenCategoryIds)->load();
|
65 |
+
if(!is_null($childrenCategories)) {
|
66 |
+
foreach ($childrenCategories as $childrenCategory) {
|
67 |
+
$filterableAttributes = array_merge($filterableAttributes, $this->getFilterableAttributesForCategory($childrenCategory));
|
68 |
+
}
|
69 |
+
}
|
70 |
+
return array_unique($filterableAttributes);
|
71 |
+
}
|
72 |
+
|
73 |
+
/**
|
74 |
+
* function to get Category from the category id,
|
75 |
+
* This checks it present in the global array 'categoryMap', if it is not there fetches from db
|
76 |
+
* So that once it gets one category, it doesn't make db call again for the same category
|
77 |
+
*
|
78 |
+
* @param string $category_id
|
79 |
+
* @return Mage_Catalog_Model_Category
|
80 |
+
*/
|
81 |
+
public function getCategory($category_id = ""){
|
82 |
+
if(!isset($this->categoryMap[$category_id])){
|
83 |
+
$category = Mage::getModel('catalog/category')->load($category_id);
|
84 |
+
$this->categoryMap[$category_id] = $category;
|
85 |
+
$parentCategories = $category->getParentCategories();
|
86 |
+
foreach($parentCategories as $parentCategory) {
|
87 |
+
$parentCategory = Mage::getModel('catalog/category')->load($parentCategory->getId());
|
88 |
+
$this->categoryMap[$parentCategory->getId()] = $parentCategory;
|
89 |
+
}
|
90 |
+
return $this->categoryMap[$category_id];
|
91 |
+
}
|
92 |
+
return $this->categoryMap[$category_id];
|
93 |
+
}
|
94 |
+
|
95 |
+
public function getRootCategoryIds(Mage_Core_Model_Website $website) {
|
96 |
+
if(!array_key_exists($website->getWebsiteId(), $this->_rootCategoryIds)) {
|
97 |
+
foreach($website->getStores() as $store) {
|
98 |
+
$this->_rootCategoryIds[$website->getWebsiteId()][] = $store->getRootCategoryId();
|
99 |
+
}
|
100 |
+
}
|
101 |
+
return $this->_rootCategoryIds[$website->getWebsiteId()];
|
102 |
+
}
|
103 |
+
|
104 |
+
public function getCategoryOnLevel($category_ids, $level) {
|
105 |
+
if(!is_array($category_ids)) {
|
106 |
+
return array();
|
107 |
+
}
|
108 |
+
$categoryValues = array();
|
109 |
+
foreach($category_ids as $category_id) {
|
110 |
+
$category = $this->getCategory($category_id);
|
111 |
+
$parentIds = $category->getParentIds();
|
112 |
+
if(!is_null($category) && $category->getLevel() == $level) {
|
113 |
+
$categoryValues = array_merge($categoryValues, array($category->getName()));
|
114 |
+
} else if ($category instanceof Mage_Catalog_Model_Category &&
|
115 |
+
is_array($parentIds) &&
|
116 |
+
(sizeof($parentIds) >0)) {
|
117 |
+
$categoryValues = array_merge($categoryValues, $this->getCategoryOnLevel($parentIds, $level));
|
118 |
+
}
|
119 |
+
}
|
120 |
+
return $categoryValues;
|
121 |
+
}
|
122 |
+
|
123 |
+
/**
|
124 |
+
* method to get all the attributes
|
125 |
+
**/
|
126 |
+
public function getAttributeMapping(){
|
127 |
+
if(isset($this->attributeToTypeMap)){
|
128 |
+
return $this->attributeToTypeMap;
|
129 |
+
} else {
|
130 |
+
$attributes = Mage::getSingleton('eav/config')
|
131 |
+
->getEntityType(Mage_Catalog_Model_Product::ENTITY)->getAttributeCollection();
|
132 |
+
foreach($attributes as $attribute){
|
133 |
+
$this->attributeToTypeMap[$attribute->getAttributeCode()] = $attribute->getFrontendInput();
|
134 |
+
}
|
135 |
+
return $this->attributeToTypeMap;
|
136 |
+
}
|
137 |
+
}
|
138 |
+
|
139 |
+
public function isAttributePresent($attributeName) {
|
140 |
+
$fieldMap = $this->getAttributeMapping();
|
141 |
+
return array_key_exists( $attributeName, $fieldMap);
|
142 |
+
}
|
143 |
+
|
144 |
+
/**
|
145 |
+
* method to get field type of the field
|
146 |
+
* @param $attributeName
|
147 |
+
* @return string
|
148 |
+
*/
|
149 |
+
public function getFieldType($attributeName){
|
150 |
+
$fieldMap = $this->getAttributeMapping();
|
151 |
+
if(array_key_exists( $attributeName, $fieldMap)){
|
152 |
+
return $fieldMap[$attributeName];
|
153 |
+
} else {
|
154 |
+
return "text";
|
155 |
+
}
|
156 |
+
}
|
157 |
+
|
158 |
+
function endsWith($haystack, $needle) {
|
159 |
+
// search forward starting from end minus needle length characters
|
160 |
+
return $needle === "" || (($temp = strlen($haystack) - strlen($needle)) >= 0 && strpos($haystack, $needle, $temp) !== FALSE);
|
161 |
+
}
|
162 |
+
|
163 |
+
/*
|
164 |
+
* function to check whether the field is a multiSelect/select or not,
|
165 |
+
* This is optimized method, where it doesn't make a database call to get fieldType
|
166 |
+
* where it fetches from the local variable, which holds the information of field to fieldType mapping
|
167 |
+
* @param string $attributeName
|
168 |
+
* @return bool
|
169 |
+
*/
|
170 |
+
public function isMultiSelect($attributeName = ""){
|
171 |
+
if(!$this->excludeMultiSelectList($attributeName)) {
|
172 |
+
return false;
|
173 |
+
}
|
174 |
+
if( $this->isMultiSelectDatatype($attributeName)||
|
175 |
+
$attributeName == ChoiceAI_Searchcore_Model_Resource_Field::CATEGORY_IDS ||
|
176 |
+
$attributeName == ChoiceAI_Searchcore_Model_Resource_Field::CATEGORY_IDS_NAME ||
|
177 |
+
$attributeName == ChoiceAI_Searchcore_Model_Resource_Field::CAT_LEVEL_1_NAME ||
|
178 |
+
$attributeName == ChoiceAI_Searchcore_Model_Resource_Field::CAT_LEVEL_2_NAME ||
|
179 |
+
$attributeName == ChoiceAI_Searchcore_Model_Resource_Field::CAT_LEVEL_3_NAME ||
|
180 |
+
$this->endsWith($attributeName, 'Associated')){
|
181 |
+
return true;
|
182 |
+
}
|
183 |
+
return false;
|
184 |
+
}
|
185 |
+
|
186 |
+
public function excludeMultiSelectList($attributeName = "") {
|
187 |
+
if($attributeName == "status" || $attributeName == "visibility" || $attributeName == "entity_id" ){
|
188 |
+
return false;
|
189 |
+
}
|
190 |
+
return true;
|
191 |
+
}
|
192 |
+
|
193 |
+
|
194 |
+
public function isMultiSelectDatatype($attributeName = "") {
|
195 |
+
if(!$this->excludeMultiSelectList($attributeName)) {
|
196 |
+
return false;
|
197 |
+
}
|
198 |
+
|
199 |
+
if($this->getFieldType($attributeName) == "select" ||
|
200 |
+
$this->getFieldType($attributeName) == "multiselect") {
|
201 |
+
return true;
|
202 |
+
}
|
203 |
+
return false;
|
204 |
+
}
|
205 |
+
|
206 |
+
public function isImage($attributeName = "") {
|
207 |
+
if($this->getFieldType($attributeName) == "media_image") {
|
208 |
+
return true;
|
209 |
+
}
|
210 |
+
return false;
|
211 |
+
}
|
212 |
+
|
213 |
+
/**
|
214 |
+
* Get all root categories used by all stores.
|
215 |
+
* Note that root categories defined but not used, are not included.
|
216 |
+
*
|
217 |
+
* @return Mage_Catalog_Model_Category[]
|
218 |
+
*/
|
219 |
+
public function getAllRootCategories()
|
220 |
+
{
|
221 |
+
$categories = array();
|
222 |
+
|
223 |
+
/** @var $stores Mage_Searchcore_Model_Store[] */
|
224 |
+
$stores = Mage::app()->getStores();
|
225 |
+
|
226 |
+
foreach ($stores as $store) {
|
227 |
+
$id = $store->getRootCategoryId();
|
228 |
+
if (!isset($categories[$id])) {
|
229 |
+
$categories[$id] = Mage::getModel('catalog/category')->load($id);
|
230 |
+
}
|
231 |
+
}
|
232 |
+
|
233 |
+
return $categories;
|
234 |
+
}
|
235 |
+
|
236 |
+
public function getUniqueId($product, $item=null) {
|
237 |
+
$type= null;
|
238 |
+
if($product->hasData('type_id')) {
|
239 |
+
$type = $product->getData('type_id');
|
240 |
+
}
|
241 |
+
|
242 |
+
switch($type){
|
243 |
+
case 'configurable':
|
244 |
+
$productId = $product->getData('entity_id');
|
245 |
+
break;
|
246 |
+
case 'grouped':
|
247 |
+
$productId = $product->getData('entity_id');
|
248 |
+
break;
|
249 |
+
case 'bundle':
|
250 |
+
$productId = $product->getData('entity_id');
|
251 |
+
break;
|
252 |
+
case 'simple':
|
253 |
+
if ($item != null && $item instanceof Mage_Sales_Model_Order) {
|
254 |
+
if($item->getParentItem() != null) {
|
255 |
+
$productId = $item->getParentItem()->getProductId();
|
256 |
+
return $productId;
|
257 |
+
}
|
258 |
+
}
|
259 |
+
$parentIds = Mage::getModel('catalog/product_type_configurable')->getParentIdsByChild($product->getId());
|
260 |
+
if(!isset($parentIds) || sizeof($parentIds) == 0) {
|
261 |
+
$parentIds = Mage::getModel('catalog/product_type_grouped')->getParentIdsByChild($product->getId());
|
262 |
+
if(isset($parentIds) && sizeof($parentIds) > 0) {
|
263 |
+
return $parentIds[0];
|
264 |
+
}
|
265 |
+
} else {
|
266 |
+
return $parentIds[0];
|
267 |
+
}
|
268 |
+
$productId = $product->getData('entity_id');
|
269 |
+
break;
|
270 |
+
default:
|
271 |
+
$productId = $product->getData('entity_id');
|
272 |
+
}
|
273 |
+
return $productId;
|
274 |
+
}
|
275 |
+
|
276 |
+
/**
|
277 |
+
* Method to get the filters that need to be excluded in the website
|
278 |
+
* @param Mage_Core_Model_Website $website
|
279 |
+
* @return array
|
280 |
+
*/
|
281 |
+
public function getFilters(Mage_Core_Model_Website $website) {
|
282 |
+
if(!isset($this->_filters)) {
|
283 |
+
$this->_filters = Mage::getResourceModel('choiceai_searchcore/config')->getFilters($website);
|
284 |
+
}
|
285 |
+
return $this->_filters;
|
286 |
+
}
|
287 |
+
|
288 |
+
}
|
app/code/local/ChoiceAI/Searchcore/Model/Api/Request.php
ADDED
@@ -0,0 +1,212 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* Class to make the request to the ChoiceAI api
|
5 |
+
*
|
6 |
+
* @category ChoiceAI
|
7 |
+
* @package ChoiceAI_Searchcore
|
8 |
+
* @copyright Copyright (c) MineWhat
|
9 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
10 |
+
*/
|
11 |
+
class ChoiceAI_Searchcore_Model_Api_Request extends Varien_Object {
|
12 |
+
|
13 |
+
/**
|
14 |
+
* end url where the request is firing
|
15 |
+
* @var
|
16 |
+
*/
|
17 |
+
protected $url = "";
|
18 |
+
|
19 |
+
/**
|
20 |
+
* http method
|
21 |
+
* @var
|
22 |
+
*/
|
23 |
+
protected $method = Zend_Http_Client::GET;
|
24 |
+
|
25 |
+
/*
|
26 |
+
* Boolean to check whether the data should be sent as raw data or not
|
27 |
+
*/
|
28 |
+
protected $rawData = false;
|
29 |
+
|
30 |
+
/**
|
31 |
+
* http response type
|
32 |
+
* @var
|
33 |
+
*/
|
34 |
+
protected $response = "";
|
35 |
+
|
36 |
+
/**
|
37 |
+
* headers needed to sent
|
38 |
+
* @var
|
39 |
+
*/
|
40 |
+
protected $headers = array();
|
41 |
+
|
42 |
+
protected $jsonResponse = true;
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Connection timeout to the api calls made to choiceai
|
46 |
+
*/
|
47 |
+
protected $timeout = 30;
|
48 |
+
|
49 |
+
public function isJsonResponse() {
|
50 |
+
return $this->jsonResponse;
|
51 |
+
}
|
52 |
+
|
53 |
+
public function setJsonResponse($value) {
|
54 |
+
if(is_bool($value) && $value == false) {
|
55 |
+
$this->jsonResponse = false;
|
56 |
+
}
|
57 |
+
return $this;
|
58 |
+
}
|
59 |
+
|
60 |
+
public function getHeaders() {
|
61 |
+
return $this->headers;
|
62 |
+
}
|
63 |
+
|
64 |
+
public function setHeaders(array $headers) {
|
65 |
+
$this->headers = $headers;
|
66 |
+
return $this;
|
67 |
+
}
|
68 |
+
|
69 |
+
public function getTimeout() {
|
70 |
+
return $this->timeout;
|
71 |
+
}
|
72 |
+
|
73 |
+
public function setTimeout($timeout) {
|
74 |
+
if(is_int($timeout) && $timeout >= 0) {
|
75 |
+
$this->timeout = $timeout;
|
76 |
+
}
|
77 |
+
return $this;
|
78 |
+
}
|
79 |
+
|
80 |
+
public function setHeader(string $header,string $value) {
|
81 |
+
$this->headers[$header] = $value;
|
82 |
+
return $this;
|
83 |
+
}
|
84 |
+
|
85 |
+
/**
|
86 |
+
* Method to get the url
|
87 |
+
*
|
88 |
+
* @return mixed
|
89 |
+
*/
|
90 |
+
protected function getUrl() {
|
91 |
+
return $this->url;
|
92 |
+
}
|
93 |
+
|
94 |
+
/**
|
95 |
+
* setter method to set url variable
|
96 |
+
*
|
97 |
+
* @param $url
|
98 |
+
* @return $this
|
99 |
+
*/
|
100 |
+
public function setUrl($url) {
|
101 |
+
$this->url = $url;
|
102 |
+
return $this;
|
103 |
+
}
|
104 |
+
|
105 |
+
/**
|
106 |
+
* Method to get the method
|
107 |
+
*
|
108 |
+
* @return mixed
|
109 |
+
*/
|
110 |
+
protected function getMethod() {
|
111 |
+
return $this->method;
|
112 |
+
}
|
113 |
+
|
114 |
+
/**
|
115 |
+
* setter method to set method variable
|
116 |
+
*
|
117 |
+
* @param $method
|
118 |
+
* @return void
|
119 |
+
*/
|
120 |
+
public function setMethod($method) {
|
121 |
+
$this->method = $method;
|
122 |
+
return $this;
|
123 |
+
}
|
124 |
+
|
125 |
+
/**
|
126 |
+
* Method to check whether parameters to be sent as raw parameter
|
127 |
+
*
|
128 |
+
* @return bool
|
129 |
+
*/
|
130 |
+
protected function isRawData() {
|
131 |
+
return $this->rawData;
|
132 |
+
}
|
133 |
+
|
134 |
+
/**
|
135 |
+
* setter method to set rawdata variable
|
136 |
+
*
|
137 |
+
* @param bool $rawData
|
138 |
+
* @return $this
|
139 |
+
*/
|
140 |
+
public function setRawData($rawData= true) {
|
141 |
+
$this->rawData = $rawData;
|
142 |
+
return $this;
|
143 |
+
}
|
144 |
+
|
145 |
+
|
146 |
+
/**
|
147 |
+
* return Zend Rest Client
|
148 |
+
*
|
149 |
+
* @return Zend_Http_Client
|
150 |
+
*/
|
151 |
+
protected function getRestClient(){
|
152 |
+
|
153 |
+
$request = new Zend_Http_Client();
|
154 |
+
$request->setUri($this->getUrl())
|
155 |
+
->setHeaders(array("Accept" => "application/json") + $this->getHeaders())
|
156 |
+
->setMethod($this->getMethod())
|
157 |
+
->setConfig(
|
158 |
+
array(
|
159 |
+
'timeout' => $this->getTimeout()
|
160 |
+
)
|
161 |
+
);
|
162 |
+
if($this->isRawData()) {
|
163 |
+
$params = json_encode($this->getData());
|
164 |
+
$request->setRawData($params, 'application/json');
|
165 |
+
} else if($this->getMethod() == Zend_Http_Client::GET) {
|
166 |
+
$request->setParameterGet($this->getData());
|
167 |
+
} else {
|
168 |
+
$request->setParameterPost($this->getData());
|
169 |
+
}
|
170 |
+
return $request;
|
171 |
+
}
|
172 |
+
|
173 |
+
|
174 |
+
/**
|
175 |
+
* Method which will make the api call
|
176 |
+
*
|
177 |
+
* @return false|ChoiceAI_Searchcore_Model_Api_Response
|
178 |
+
*/
|
179 |
+
public function execute(){
|
180 |
+
try {
|
181 |
+
$request = $this->getRestClient();
|
182 |
+
$raw_response = $request->request();
|
183 |
+
} catch (Zend_Http_Client_Exception $e) {
|
184 |
+
Mage::helper('choiceai_searchcore')->log(Zend_Log::ERR,
|
185 |
+
sprintf($this->getUrl() ." failed because HTTP error: %s", $e->getMessage()));
|
186 |
+
return Mage::getModel('choiceai_searchcore/api_response')
|
187 |
+
->setErrorMessage(ChoiceAI_Searchcore_Model_Api_Response::SERVER_ERR);
|
188 |
+
}
|
189 |
+
return Mage::getModel("choiceai_searchcore/api_response")
|
190 |
+
->setJsonResponse($this->isJsonResponse())
|
191 |
+
->setResponse($raw_response, $this->getUrl());
|
192 |
+
}
|
193 |
+
|
194 |
+
/**
|
195 |
+
* Method to return string
|
196 |
+
*
|
197 |
+
* @return string
|
198 |
+
*/
|
199 |
+
public function __toString() {
|
200 |
+
|
201 |
+
$parameters = $this->getData();
|
202 |
+
if (count($parameters) > 0) {
|
203 |
+
$parameters_as_string = json_encode($parameters);
|
204 |
+
}
|
205 |
+
return "Request to url " . $this->getUrl() . " with method " . $this->getMethod()
|
206 |
+
. (count($parameters) > 0?(" with parameters " . $parameters_as_string):"");
|
207 |
+
}
|
208 |
+
|
209 |
+
|
210 |
+
}
|
211 |
+
|
212 |
+
?>
|
app/code/local/ChoiceAI/Searchcore/Model/Api/Response.php
ADDED
@@ -0,0 +1,165 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @category ChoiceAI
|
5 |
+
* @package ChoiceAI_Searchcore
|
6 |
+
* @copyright Copyright (c) MineWhat
|
7 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
*/
|
9 |
+
class ChoiceAI_Searchcore_Model_Api_Response extends Varien_Object {
|
10 |
+
|
11 |
+
const SERVER_ERR = 'Unable to reach choiceai server, Please contact support';
|
12 |
+
|
13 |
+
const SERVER_RESPONSE_ERR = 'Invalid response from ChoiceAI, Please contact support';
|
14 |
+
|
15 |
+
/**
|
16 |
+
* Variable to maintain the response successful or not
|
17 |
+
* @var
|
18 |
+
*/
|
19 |
+
protected $success;
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Variable to maintain the response successful or not
|
23 |
+
* @var
|
24 |
+
*/
|
25 |
+
protected $errors = array();
|
26 |
+
|
27 |
+
protected $jsonResponse = true;
|
28 |
+
|
29 |
+
/**
|
30 |
+
* Variable to store the response from the api
|
31 |
+
* @var
|
32 |
+
*/
|
33 |
+
protected $response;
|
34 |
+
|
35 |
+
public function isJsonResponse() {
|
36 |
+
|
37 |
+
return $this->jsonResponse;
|
38 |
+
}
|
39 |
+
|
40 |
+
public function setJsonResponse($value) {
|
41 |
+
if(is_bool($value) && $value == false) {
|
42 |
+
$this->jsonResponse = false;
|
43 |
+
}
|
44 |
+
return $this;
|
45 |
+
}
|
46 |
+
|
47 |
+
public function _construct() {
|
48 |
+
$this->success = false;
|
49 |
+
$this->message = "Empty response";
|
50 |
+
$this->response = array();
|
51 |
+
}
|
52 |
+
|
53 |
+
public function setSuccess($success) {
|
54 |
+
if(is_bool($success)) {
|
55 |
+
$this->success = $success;
|
56 |
+
}
|
57 |
+
return $this;
|
58 |
+
}
|
59 |
+
|
60 |
+
/**
|
61 |
+
* Method to check exact error message
|
62 |
+
*
|
63 |
+
* @return bool
|
64 |
+
*/
|
65 |
+
public function isSuccess() {
|
66 |
+
return $this->success;
|
67 |
+
}
|
68 |
+
|
69 |
+
public function setErrors($errors = array()) {
|
70 |
+
$this->errors = $errors;
|
71 |
+
return $this;
|
72 |
+
}
|
73 |
+
|
74 |
+
public function getErrors() {
|
75 |
+
return $this->errors;
|
76 |
+
}
|
77 |
+
|
78 |
+
public function setErrorMessage($message) {
|
79 |
+
$this->errors['message'] = $message;
|
80 |
+
return $this;
|
81 |
+
}
|
82 |
+
|
83 |
+
public function setError(string $key, string $value) {
|
84 |
+
$this->errors[$key] = $value;
|
85 |
+
return $this;
|
86 |
+
}
|
87 |
+
|
88 |
+
/**
|
89 |
+
* Method to get Message
|
90 |
+
*
|
91 |
+
* @return string
|
92 |
+
*/
|
93 |
+
public function getMessage() {
|
94 |
+
if(array_key_exists('message', $this->errors)) {
|
95 |
+
return $this->errors['message'];
|
96 |
+
}
|
97 |
+
return null;
|
98 |
+
}
|
99 |
+
|
100 |
+
/**
|
101 |
+
* Method to set the message
|
102 |
+
*
|
103 |
+
* @param $message
|
104 |
+
* @return $this
|
105 |
+
*/
|
106 |
+
public function setMessage($message) {
|
107 |
+
$this->errors['message'] = $message;
|
108 |
+
return $this;
|
109 |
+
}
|
110 |
+
|
111 |
+
/**
|
112 |
+
* Method to return the response
|
113 |
+
*
|
114 |
+
* @return array
|
115 |
+
*/
|
116 |
+
public function getResponse() {
|
117 |
+
return $this->response;
|
118 |
+
}
|
119 |
+
|
120 |
+
/**
|
121 |
+
* Method to set the response
|
122 |
+
*
|
123 |
+
* @param Zend_Http_Response $response
|
124 |
+
* @param $url
|
125 |
+
* @return $this
|
126 |
+
*/
|
127 |
+
public function setResponse(Zend_Http_Response $response, $url) {
|
128 |
+
if($response->isSuccessful()) {
|
129 |
+
$this->success = true;
|
130 |
+
$this->setMessage("success");
|
131 |
+
$body = $response->getBody();
|
132 |
+
if(!$this->isJsonResponse()) {
|
133 |
+
#Mage::helper('choiceai_searchcore')->log(Zend_Log::DEBUG, "response from the " . $url . " is successful");
|
134 |
+
$this->setData("body", $body);
|
135 |
+
return $this;
|
136 |
+
}
|
137 |
+
$this->response = json_decode($body, true);
|
138 |
+
#Mage::helper('choiceai_searchcore')->log(Zend_Log::DEBUG, "response from the " . $url . " is " . $body);
|
139 |
+
if($this->response == false || !is_array($this->response) || sizeof($this->response) == 0) {
|
140 |
+
$this->success = false;
|
141 |
+
$this->setMessage("Invalid Authorization credentials");
|
142 |
+
Mage::helper('choiceai_searchcore')->log(Zend_Log::ERR, $url . " api failed cos ". $this->getMessage());
|
143 |
+
return $this;
|
144 |
+
}
|
145 |
+
} else {
|
146 |
+
|
147 |
+
$this->success = false;
|
148 |
+
switch ($response->getStatus()) {
|
149 |
+
case 500:
|
150 |
+
$message = "ChoiceAI API server error, Please contact support \n" . $response->getBody();
|
151 |
+
$this->setMessage("ChoiceAI API server error, Please contact support \n");
|
152 |
+
break;
|
153 |
+
default:
|
154 |
+
$message = "ChoiceAI Unexpected error, Please contact support";
|
155 |
+
$this->setMessage($message);
|
156 |
+
}
|
157 |
+
Mage::helper('choiceai_searchcore')
|
158 |
+
->log(Zend_Log::ERR, $url . " api failed cos ". $response->getStatus() . ":" . $message);
|
159 |
+
}
|
160 |
+
return $this;
|
161 |
+
}
|
162 |
+
|
163 |
+
|
164 |
+
}
|
165 |
+
?>
|
app/code/local/ChoiceAI/Searchcore/Model/Api/Task.php
ADDED
@@ -0,0 +1,84 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @category ChoiceAI
|
5 |
+
* @package ChoiceAI_Searchcore
|
6 |
+
* @copyright Copyright (c) MineWhat
|
7 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
*/
|
9 |
+
abstract class ChoiceAI_Searchcore_Model_Api_Task extends Varien_Object {
|
10 |
+
|
11 |
+
static $PLATFORM_API_BASE_URL = "https://accounts.choiceaiapi.com/admin/";
|
12 |
+
|
13 |
+
static $RECOMMENDATION_SETTINGS_URL = "https://starwreck.choiceai.com/";
|
14 |
+
|
15 |
+
static $TRACKER_URL = "https://tracker.choiceaiapi.com/";
|
16 |
+
|
17 |
+
const TIMEOUT = 30;
|
18 |
+
|
19 |
+
static $url = "";
|
20 |
+
|
21 |
+
const method = Zend_Http_Client::GET;
|
22 |
+
|
23 |
+
protected $preparationSuccessful;
|
24 |
+
|
25 |
+
protected $errors;
|
26 |
+
|
27 |
+
protected $headers = array();
|
28 |
+
|
29 |
+
protected $isRawData = false;
|
30 |
+
|
31 |
+
const jsonResponse = true;
|
32 |
+
|
33 |
+
public function __construct() {
|
34 |
+
$this->preparationSuccessful = false;
|
35 |
+
$this->errors = array();
|
36 |
+
static::$PLATFORM_API_BASE_URL = Mage::helper('choiceai_searchcore/confighelper')->getConfigData('platform_url');
|
37 |
+
static::$RECOMMENDATION_SETTINGS_URL = Mage::helper('choiceai_searchcore/confighelper')->getConfigData('service_url');
|
38 |
+
static::$TRACKER_URL = Mage::helper('choiceai_searchcore/confighelper')->getConfigData('tracker_url');
|
39 |
+
}
|
40 |
+
|
41 |
+
/**
|
42 |
+
* Method to check whether parameters to be sent as raw parameter
|
43 |
+
*
|
44 |
+
* @return bool
|
45 |
+
*/
|
46 |
+
protected function isRawData() {
|
47 |
+
return $this->isRawData;
|
48 |
+
}
|
49 |
+
|
50 |
+
abstract public function prepare(Mage_Core_Model_Website $website);
|
51 |
+
|
52 |
+
abstract protected function postProcess(ChoiceAI_Searchcore_Model_Api_Response $response);
|
53 |
+
|
54 |
+
/**
|
55 |
+
* Method which will make the api call
|
56 |
+
*
|
57 |
+
* @return false|ChoiceAI_Searchcore_Model_Api_Response
|
58 |
+
*/
|
59 |
+
public function process() {
|
60 |
+
if(!$this->preparationSuccessful) {
|
61 |
+
Mage::helper("choiceai_searchcore")
|
62 |
+
->log(Zend_Log::ERR,
|
63 |
+
sizeof($this->errors == 0)?"prepare method not called":json_encode($this->errors));
|
64 |
+
return Mage::getModel("choiceai_searchcore/api_response")
|
65 |
+
->setErrors(sizeof($this->errors) == 0?array("message" => "prepare method not called"):$this->errors);
|
66 |
+
}
|
67 |
+
$request = Mage::getModel("choiceai_searchcore/api_request")
|
68 |
+
->setUrl(static::$url)
|
69 |
+
->setMethod(static::method)
|
70 |
+
->setHeaders($this->headers)
|
71 |
+
->setTimeout(static::TIMEOUT)
|
72 |
+
->setJsonResponse(static::jsonResponse);
|
73 |
+
if($this->isRawData()) {
|
74 |
+
$request->setRawData(true);
|
75 |
+
}
|
76 |
+
if($this->getData()) {
|
77 |
+
$request->addData($this->getData());
|
78 |
+
}
|
79 |
+
|
80 |
+
return $this->postProcess($request->execute());
|
81 |
+
}
|
82 |
+
|
83 |
+
}
|
84 |
+
?>
|
app/code/local/ChoiceAI/Searchcore/Model/Api/Task/Analyticsimpression.php
ADDED
@@ -0,0 +1,49 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @category ChoiceAI
|
5 |
+
* @copyright Copyright (c) MineWhat
|
6 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
7 |
+
*/
|
8 |
+
class ChoiceAI_Searchcore_Model_Api_Task_Analyticsimpression extends ChoiceAI_Searchcore_Model_Api_Task
|
9 |
+
{
|
10 |
+
|
11 |
+
const method = Zend_Http_Client::GET;
|
12 |
+
|
13 |
+
public function prepare(Mage_Core_Model_Website $website) {
|
14 |
+
$this->preparationSuccessful = true;
|
15 |
+
$this->prepareUrl($website);
|
16 |
+
$this->prepareHeaders($website);
|
17 |
+
return $this;
|
18 |
+
}
|
19 |
+
|
20 |
+
protected function prepareUrl(Mage_Core_Model_Website $website) {
|
21 |
+
$siteKey = Mage::getResourceModel("choiceai_searchcore/config")
|
22 |
+
->getValue($website->getWebsiteId(), ChoiceAI_Searchcore_Helper_Confighelper::SITE_KEY);
|
23 |
+
if(is_null($siteKey)) {
|
24 |
+
$this->preparationSuccessful = false;
|
25 |
+
$this->errors["message"] = "Site key not set";
|
26 |
+
return;
|
27 |
+
}
|
28 |
+
|
29 |
+
static::$url = static::$RECOMMENDATION_SETTINGS_URL . "dashboard/analytics/integrationDetails/" . $siteKey;
|
30 |
+
}
|
31 |
+
|
32 |
+
protected function prepareHeaders(Mage_Core_Model_Website $website) {
|
33 |
+
$username = Mage::getResourceModel("choiceai_searchcore/config")
|
34 |
+
->getValue($website->getWebsiteId(), ChoiceAI_Searchcore_Helper_Confighelper::USERNAME);
|
35 |
+
if(is_null($username)) {
|
36 |
+
$this->preparationSuccessful = false;
|
37 |
+
$this->errors["message"] = "Secret key not set";
|
38 |
+
return;
|
39 |
+
}
|
40 |
+
|
41 |
+
$this->headers["authorization"] = "Basic " . base64_encode($username . ':$uauth');
|
42 |
+
}
|
43 |
+
|
44 |
+
protected function postProcess(ChoiceAI_Searchcore_Model_Api_Response $response) {
|
45 |
+
return $response;
|
46 |
+
}
|
47 |
+
|
48 |
+
}
|
49 |
+
?>
|
app/code/local/ChoiceAI/Searchcore/Model/Api/Task/Autosuggestindex.php
ADDED
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @category ChoiceAI
|
5 |
+
* @package ChoiceAI_Searchcore
|
6 |
+
* @copyright Copyright (c) MineWhat
|
7 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
*/
|
9 |
+
class ChoiceAI_Searchcore_Model_Api_Task_Autosuggestindex extends ChoiceAI_Searchcore_Model_Api_Task {
|
10 |
+
|
11 |
+
const method = Zend_Http_Client::POST;
|
12 |
+
|
13 |
+
const STATUS = 'status';
|
14 |
+
|
15 |
+
const MESSAGE = 'message';
|
16 |
+
|
17 |
+
public function prepare(Mage_Core_Model_Website $website) {
|
18 |
+
$this->preparationSuccessful = true;
|
19 |
+
$this->prepareUrl($website);
|
20 |
+
$this->prepareHeaders($website);
|
21 |
+
return $this;
|
22 |
+
}
|
23 |
+
|
24 |
+
protected function prepareUrl(Mage_Core_Model_Website $website) {
|
25 |
+
$siteKey = Mage::getResourceModel("choiceai_searchcore/config")
|
26 |
+
->getValue($website->getWebsiteId(), ChoiceAI_Searchcore_Helper_Confighelper::SITE_KEY);
|
27 |
+
if(is_null($siteKey)) {
|
28 |
+
$this->preparationSuccessful = false;
|
29 |
+
$this->errors["message"] = "Site key not set";
|
30 |
+
return;
|
31 |
+
}
|
32 |
+
|
33 |
+
static::$url = static::$PLATFORM_API_BASE_URL . $siteKey . "/build-autosuggest";
|
34 |
+
}
|
35 |
+
|
36 |
+
protected function prepareHeaders(Mage_Core_Model_Website $website) {
|
37 |
+
$apiKey = Mage::getResourceModel("choiceai_searchcore/config")
|
38 |
+
->getValue($website->getWebsiteId(), ChoiceAI_Searchcore_Helper_Confighelper::API_KEY);
|
39 |
+
$secretKey = Mage::getResourceModel("choiceai_searchcore/config")
|
40 |
+
->getValue($website->getWebsiteId(), ChoiceAI_Searchcore_Helper_Confighelper::SECRET_KEY);
|
41 |
+
if(is_null($secretKey) || is_null($apiKey)) {
|
42 |
+
$this->preparationSuccessful = false;
|
43 |
+
$this->errors["message"] = "Site key not set";
|
44 |
+
return;
|
45 |
+
}
|
46 |
+
$this->headers["Authorization"] = base64_encode($apiKey.":" .$secretKey);
|
47 |
+
}
|
48 |
+
|
49 |
+
protected function postProcess(ChoiceAI_Searchcore_Model_Api_Response $response) {
|
50 |
+
return $response;
|
51 |
+
}
|
52 |
+
}
|
app/code/local/ChoiceAI/Searchcore/Model/Api/Task/Feeddetails.php
ADDED
@@ -0,0 +1,71 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @category ChoiceAI
|
5 |
+
* @package ChoiceAI_Searchcore
|
6 |
+
* @copyright Copyright (c) MineWhat
|
7 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
*/
|
9 |
+
class ChoiceAI_Searchcore_Model_Api_Task_Feeddetails extends ChoiceAI_Searchcore_Model_Api_Task {
|
10 |
+
|
11 |
+
const method = Zend_Http_Client::GET;
|
12 |
+
|
13 |
+
const STATUS = 'status';
|
14 |
+
|
15 |
+
const MESSAGE = 'message';
|
16 |
+
|
17 |
+
const FEEDINFO = 'feedInfo';
|
18 |
+
|
19 |
+
const NUMDOCS = 'numDocs';
|
20 |
+
|
21 |
+
public function prepare(Mage_Core_Model_Website $website) {
|
22 |
+
$this->preparationSuccessful = true;
|
23 |
+
$this->prepareUrl($website);
|
24 |
+
$this->prepareHeaders($website);
|
25 |
+
return $this;
|
26 |
+
}
|
27 |
+
|
28 |
+
protected function prepareUrl(Mage_Core_Model_Website $website) {
|
29 |
+
$siteKey = Mage::getResourceModel("choiceai_searchcore/config")
|
30 |
+
->getValue($website->getWebsiteId(), ChoiceAI_Searchcore_Helper_Confighelper::SITE_KEY);
|
31 |
+
if(is_null($siteKey)) {
|
32 |
+
$this->preparationSuccessful = false;
|
33 |
+
$this->errors["message"] = "Site key not set";
|
34 |
+
return;
|
35 |
+
}
|
36 |
+
|
37 |
+
static::$url = static::$PLATFORM_API_BASE_URL . $siteKey . "/feed-info";
|
38 |
+
}
|
39 |
+
|
40 |
+
protected function prepareHeaders(Mage_Core_Model_Website $website) {
|
41 |
+
$apiKey = Mage::getResourceModel("choiceai_searchcore/config")
|
42 |
+
->getValue($website->getWebsiteId(), ChoiceAI_Searchcore_Helper_Confighelper::API_KEY);
|
43 |
+
$secretKey = Mage::getResourceModel("choiceai_searchcore/config")
|
44 |
+
->getValue($website->getWebsiteId(), ChoiceAI_Searchcore_Helper_Confighelper::SECRET_KEY);
|
45 |
+
if(is_null($secretKey) || is_null($apiKey)) {
|
46 |
+
$this->preparationSuccessful = false;
|
47 |
+
$this->errors["message"] = "Site key not set";
|
48 |
+
return;
|
49 |
+
}
|
50 |
+
$this->headers["Authorization"] = base64_encode($apiKey.":" .$secretKey);
|
51 |
+
}
|
52 |
+
|
53 |
+
protected function postProcess(ChoiceAI_Searchcore_Model_Api_Response $response) {
|
54 |
+
if(!$response->isSuccess()) {
|
55 |
+
return $response;
|
56 |
+
}
|
57 |
+
$responseObj = $response->getResponse();
|
58 |
+
if(!array_key_exists(self::STATUS, $responseObj) || !array_key_exists(self::FEEDINFO, $responseObj)) {
|
59 |
+
$response->setSuccess(false);
|
60 |
+
$response->setMessage('Invalid response from choiceai');
|
61 |
+
return $response;
|
62 |
+
}
|
63 |
+
if($responseObj[self::STATUS] != 200 || !array_key_exists(self::NUMDOCS, $responseObj[self::FEEDINFO])) {
|
64 |
+
$response->setSuccess(false);
|
65 |
+
$response->setMessage("status code :" .$responseObj[self::STATUS].",".
|
66 |
+
(array_key_exists(self::MESSAGE, $responseObj)?$responseObj[self::MESSAGE]:""));
|
67 |
+
return $response;
|
68 |
+
}
|
69 |
+
return $response;
|
70 |
+
}
|
71 |
+
}
|
app/code/local/ChoiceAI/Searchcore/Model/Api/Task/Searchimpression.php
ADDED
@@ -0,0 +1,57 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @category ChoiceAI
|
5 |
+
* @package ChoiceAI_Searchcore
|
6 |
+
* @copyright Copyright (c) MineWhat
|
7 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
*/
|
9 |
+
class ChoiceAI_Searchcore_Model_Api_Task_Searchimpression extends ChoiceAI_Searchcore_Model_Api_Task
|
10 |
+
{
|
11 |
+
|
12 |
+
const method = Zend_Http_Client::GET;
|
13 |
+
|
14 |
+
public function prepare(Mage_Core_Model_Website $website) {
|
15 |
+
$this->preparationSuccessful = true;
|
16 |
+
$this->prepareUrl($website);
|
17 |
+
$this->prepareHeaders($website);
|
18 |
+
return $this;
|
19 |
+
}
|
20 |
+
|
21 |
+
protected function prepareUrl(Mage_Core_Model_Website $website) {
|
22 |
+
$siteKey = Mage::getResourceModel("choiceai_searchcore/config")
|
23 |
+
->getValue($website->getWebsiteId(), ChoiceAI_Searchcore_Helper_Confighelper::SITE_KEY);
|
24 |
+
if(is_null($siteKey)) {
|
25 |
+
$this->preparationSuccessful = false;
|
26 |
+
$this->errors["message"] = "Site key not set";
|
27 |
+
return;
|
28 |
+
}
|
29 |
+
|
30 |
+
static::$url = static::$RECOMMENDATION_SETTINGS_URL . "dashboard/analytics/hits/" . $siteKey;
|
31 |
+
}
|
32 |
+
|
33 |
+
protected function prepareHeaders(Mage_Core_Model_Website $website) {
|
34 |
+
$username = Mage::getResourceModel("choiceai_searchcore/config")
|
35 |
+
->getValue($website->getWebsiteId(), ChoiceAI_Searchcore_Helper_Confighelper::USERNAME);
|
36 |
+
if(is_null($username)) {
|
37 |
+
$this->preparationSuccessful = false;
|
38 |
+
$this->errors["message"] = "Secret key not set";
|
39 |
+
return;
|
40 |
+
}
|
41 |
+
|
42 |
+
$this->headers["authorization"] = "Basic " . base64_encode($username . ':$uauth');
|
43 |
+
}
|
44 |
+
|
45 |
+
protected function postProcess(ChoiceAI_Searchcore_Model_Api_Response $response) {
|
46 |
+
$respObj = $response->getResponse();
|
47 |
+
if(array_key_exists("FunnelResponse", $respObj)) {
|
48 |
+
if(array_key_exists("Funnels",$respObj["FunnelResponse"])) {
|
49 |
+
return $response;
|
50 |
+
}
|
51 |
+
}
|
52 |
+
$response->setSuccess(false);
|
53 |
+
$response->setErrorMessage("Unexpected response from ChoiceAI server, Contact Support");
|
54 |
+
return $response;
|
55 |
+
}
|
56 |
+
}
|
57 |
+
?>
|
app/code/local/ChoiceAI/Searchcore/Model/Api/Task/Searchsetup.php
ADDED
@@ -0,0 +1,52 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @category ChoiceAI
|
5 |
+
* @package ChoiceAI_Searchcore
|
6 |
+
* @copyright Copyright (c) MineWhat
|
7 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
*/
|
9 |
+
class ChoiceAI_Searchcore_Model_Api_Task_Searchsetup extends ChoiceAI_Searchcore_Model_Api_Task {
|
10 |
+
|
11 |
+
const method = Zend_Http_Client::POST;
|
12 |
+
|
13 |
+
const STATUS = 'status';
|
14 |
+
|
15 |
+
const MESSAGE = 'message';
|
16 |
+
|
17 |
+
public function prepare(Mage_Core_Model_Website $website) {
|
18 |
+
$this->preparationSuccessful = true;
|
19 |
+
$this->prepareUrl($website);
|
20 |
+
$this->prepareHeaders($website);
|
21 |
+
return $this;
|
22 |
+
}
|
23 |
+
|
24 |
+
protected function prepareUrl(Mage_Core_Model_Website $website) {
|
25 |
+
$siteKey = Mage::getResourceModel("choiceai_searchcore/config")
|
26 |
+
->getValue($website->getWebsiteId(), ChoiceAI_Searchcore_Helper_Confighelper::SITE_KEY);
|
27 |
+
if(is_null($siteKey)) {
|
28 |
+
$this->preparationSuccessful = false;
|
29 |
+
$this->errors["message"] = "Site key not set";
|
30 |
+
return;
|
31 |
+
}
|
32 |
+
|
33 |
+
static::$url = static::$PLATFORM_API_BASE_URL . $siteKey . "/complete-search";
|
34 |
+
}
|
35 |
+
|
36 |
+
protected function prepareHeaders(Mage_Core_Model_Website $website) {
|
37 |
+
$apiKey = Mage::getResourceModel("choiceai_searchcore/config")
|
38 |
+
->getValue($website->getWebsiteId(), ChoiceAI_Searchcore_Helper_Confighelper::API_KEY);
|
39 |
+
$secretKey = Mage::getResourceModel("choiceai_searchcore/config")
|
40 |
+
->getValue($website->getWebsiteId(), ChoiceAI_Searchcore_Helper_Confighelper::SECRET_KEY);
|
41 |
+
if(is_null($secretKey) || is_null($apiKey)) {
|
42 |
+
$this->preparationSuccessful = false;
|
43 |
+
$this->errors["message"] = "Site key not set";
|
44 |
+
return;
|
45 |
+
}
|
46 |
+
$this->headers["Authorization"] = base64_encode($apiKey.":" .$secretKey);
|
47 |
+
}
|
48 |
+
|
49 |
+
protected function postProcess(ChoiceAI_Searchcore_Model_Api_Response $response) {
|
50 |
+
return $response;
|
51 |
+
}
|
52 |
+
}
|
app/code/local/ChoiceAI/Searchcore/Model/Api/Task/Supportmail.php
ADDED
@@ -0,0 +1,48 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category ChoiceAI
|
4 |
+
* @package ChoiceAI_Searchcore
|
5 |
+
* @copyright Copyright (c) MineWhat
|
6 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
7 |
+
*/
|
8 |
+
class ChoiceAI_Searchcore_Model_Api_Task_Supportmail extends ChoiceAI_Searchcore_Model_Api_Task {
|
9 |
+
|
10 |
+
const method = Zend_Http_Client::POST;
|
11 |
+
protected $isRawData = true;
|
12 |
+
|
13 |
+
|
14 |
+
public function prepare(Mage_Core_Model_Website $website) {
|
15 |
+
$this->preparationSuccessful = true;
|
16 |
+
$this->prepareUrl($website);
|
17 |
+
$this->prepareHeaders($website);
|
18 |
+
return $this;
|
19 |
+
}
|
20 |
+
|
21 |
+
protected function prepareUrl(Mage_Core_Model_Website $website) {
|
22 |
+
$siteKey = Mage::getResourceModel("choiceai_searchcore/config")
|
23 |
+
->getValue($website->getWebsiteId(), ChoiceAI_Searchcore_Helper_Confighelper::SITE_KEY);
|
24 |
+
if(is_null($siteKey)) {
|
25 |
+
$this->preparationSuccessful = false;
|
26 |
+
$this->errors["message"] = "Site key not set";
|
27 |
+
return;
|
28 |
+
}
|
29 |
+
|
30 |
+
static::$url = static::$RECOMMENDATION_SETTINGS_URL . "dashboard/mail/support";
|
31 |
+
}
|
32 |
+
|
33 |
+
protected function prepareHeaders(Mage_Core_Model_Website $website) {
|
34 |
+
$username = Mage::getResourceModel("choiceai_searchcore/config")
|
35 |
+
->getValue($website->getWebsiteId(), ChoiceAI_Searchcore_Helper_Confighelper::USERNAME);
|
36 |
+
if(is_null($username)) {
|
37 |
+
$this->preparationSuccessful = false;
|
38 |
+
$this->errors["message"] = "Secret key not set";
|
39 |
+
return;
|
40 |
+
}
|
41 |
+
|
42 |
+
$this->headers["authorization"] = "Basic " . base64_encode($username . ':$uauth');
|
43 |
+
}
|
44 |
+
|
45 |
+
protected function postProcess(ChoiceAI_Searchcore_Model_Api_Response $response) {
|
46 |
+
return $response;
|
47 |
+
}
|
48 |
+
}
|
app/code/local/ChoiceAI/Searchcore/Model/Api/Task/Trackcart.php
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @category ChoiceAI
|
5 |
+
* @package ChoiceAI_Searchcore
|
6 |
+
* @copyright Copyright (c) MineWhat
|
7 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
*/
|
9 |
+
class ChoiceAI_Searchcore_Model_Api_Task_Trackcart extends ChoiceAI_Searchcore_Model_Api_Task {
|
10 |
+
|
11 |
+
const method = Zend_Http_Client::POST;
|
12 |
+
|
13 |
+
const jsonResponse = false;
|
14 |
+
|
15 |
+
const TIMEOUT = 5;
|
16 |
+
|
17 |
+
public function prepare(Mage_Core_Model_Website $website) {
|
18 |
+
$this->prepareUrl($website);
|
19 |
+
$this->isRawData = true;
|
20 |
+
return $this;
|
21 |
+
}
|
22 |
+
|
23 |
+
protected function prepareUrl(Mage_Core_Model_Website $website)
|
24 |
+
{
|
25 |
+
$siteKey = Mage::getResourceModel("choiceai_searchcore/config")
|
26 |
+
->getValue($website->getWebsiteId(), ChoiceAI_Searchcore_Helper_Confighelper::SITE_KEY);
|
27 |
+
if (is_null($siteKey)) {
|
28 |
+
$this->errors["message"] = "Site key not set";
|
29 |
+
return;
|
30 |
+
}
|
31 |
+
|
32 |
+
$uid = array_key_exists('choiceai_userId', $_COOKIE) ? $_COOKIE['choiceai_userId'] : null;
|
33 |
+
if (!isset($uid) || is_null($uid)) {
|
34 |
+
$this->errors["message"] = "UID Missing";
|
35 |
+
return;
|
36 |
+
}
|
37 |
+
|
38 |
+
static::$url = static::$TRACKER_URL . "v1.0/$siteKey/track/cart/$uid";
|
39 |
+
$this->preparationSuccessful = true;
|
40 |
+
}
|
41 |
+
|
42 |
+
protected function postProcess(ChoiceAI_Searchcore_Model_Api_Response $response) {
|
43 |
+
return $response;
|
44 |
+
}
|
45 |
+
}
|
46 |
+
?>
|
app/code/local/ChoiceAI/Searchcore/Model/Api/Task/Trackorder.php
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @category ChoiceAI
|
5 |
+
* @package ChoiceAI_Searchcore
|
6 |
+
* @copyright Copyright (c) MineWhat
|
7 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
*/
|
9 |
+
class ChoiceAI_Searchcore_Model_Api_Task_Trackorder extends ChoiceAI_Searchcore_Model_Api_Task {
|
10 |
+
|
11 |
+
const method = Zend_Http_Client::POST;
|
12 |
+
|
13 |
+
const jsonResponse = false;
|
14 |
+
|
15 |
+
const TIMEOUT = 5;
|
16 |
+
|
17 |
+
public function prepare(Mage_Core_Model_Website $website) {
|
18 |
+
$this->prepareUrl($website);
|
19 |
+
$this->isRawData = true;
|
20 |
+
return $this;
|
21 |
+
}
|
22 |
+
|
23 |
+
protected function prepareUrl(Mage_Core_Model_Website $website)
|
24 |
+
{
|
25 |
+
$siteKey = Mage::getResourceModel("choiceai_searchcore/config")
|
26 |
+
->getValue($website->getWebsiteId(), ChoiceAI_Searchcore_Helper_Confighelper::SITE_KEY);
|
27 |
+
if (is_null($siteKey)) {
|
28 |
+
$this->errors["message"] = "Site key not set";
|
29 |
+
return;
|
30 |
+
}
|
31 |
+
|
32 |
+
$uid = array_key_exists('choiceai_userId', $_COOKIE) ? $_COOKIE['choiceai_userId'] : null;
|
33 |
+
if (!isset($uid) || is_null($uid)) {
|
34 |
+
$this->errors["message"] = "UID Missing";
|
35 |
+
return;
|
36 |
+
}
|
37 |
+
|
38 |
+
static::$url = static::$TRACKER_URL . "v1.0/$siteKey/track/order/$uid";
|
39 |
+
$this->preparationSuccessful = true;
|
40 |
+
}
|
41 |
+
|
42 |
+
protected function postProcess(ChoiceAI_Searchcore_Model_Api_Response $response) {
|
43 |
+
return $response;
|
44 |
+
}
|
45 |
+
}
|
46 |
+
?>
|
app/code/local/ChoiceAI/Searchcore/Model/Api/Task/Triggerfeedupload.php
ADDED
@@ -0,0 +1,42 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* class to validate the secret key and site key with choiceai
|
5 |
+
*
|
6 |
+
* @category ChoiceAI
|
7 |
+
* @package ChoiceAI_Searchcore
|
8 |
+
* @copyright Copyright (c) MineWhat
|
9 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
10 |
+
*/
|
11 |
+
class ChoiceAI_Searchcore_Model_Api_Task_Triggerfeedupload extends ChoiceAI_Searchcore_Model_Api_Task {
|
12 |
+
|
13 |
+
const method = Zend_Http_Client::POST;
|
14 |
+
|
15 |
+
const TIMEOUT = 5;
|
16 |
+
|
17 |
+
public function prepare(Mage_Core_Model_Website $website) {
|
18 |
+
$this->preparationSuccessful = true;
|
19 |
+
$this->prepareUrl();
|
20 |
+
$this->prepareParams($website);
|
21 |
+
return $this;
|
22 |
+
}
|
23 |
+
|
24 |
+
protected function prepareUrl() {
|
25 |
+
static::$url = Mage::getBaseUrl()."searchcore/config/productsync";
|
26 |
+
return $this;
|
27 |
+
}
|
28 |
+
|
29 |
+
protected function prepareParams(Mage_Core_Model_Website $website) {
|
30 |
+
$this->setData("site", $website->getName());
|
31 |
+
$this->setData("auth", Mage::getSingleton('choiceai_searchcore/auth')->getAuthKey());
|
32 |
+
return $this;
|
33 |
+
}
|
34 |
+
|
35 |
+
protected function postProcess(ChoiceAI_Searchcore_Model_Api_Response $response) {
|
36 |
+
$response->setSuccess(true);
|
37 |
+
$response->setErrors(array());
|
38 |
+
return $response;
|
39 |
+
}
|
40 |
+
}
|
41 |
+
|
42 |
+
?>
|
app/code/local/ChoiceAI/Searchcore/Model/Api/Task/Updatefeaturefields.php
ADDED
@@ -0,0 +1,83 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @category ChoiceAI
|
5 |
+
* @package ChoiceAI_Searchcore
|
6 |
+
* @copyright Copyright (c) MineWhat
|
7 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
*/
|
9 |
+
class ChoiceAI_Searchcore_Model_Api_Task_Updatefeaturefields extends ChoiceAI_Searchcore_Model_Api_Task {
|
10 |
+
|
11 |
+
const method = Zend_Http_Client::POST;
|
12 |
+
|
13 |
+
const STATUS = 'status';
|
14 |
+
|
15 |
+
const MESSAGE = 'message';
|
16 |
+
|
17 |
+
public function prepare(Mage_Core_Model_Website $website) {
|
18 |
+
$this->preparationSuccessful = true;
|
19 |
+
$this->prepareUrl($website);
|
20 |
+
$this->prepareHeaders($website);
|
21 |
+
$this->prepareData($website);
|
22 |
+
$this->isRawData = true;
|
23 |
+
return $this;
|
24 |
+
}
|
25 |
+
|
26 |
+
protected function prepareUrl(Mage_Core_Model_Website $website) {
|
27 |
+
$siteKey = Mage::getResourceModel("choiceai_searchcore/config")
|
28 |
+
->getValue($website->getWebsiteId(), ChoiceAI_Searchcore_Helper_Confighelper::SITE_KEY);
|
29 |
+
if(is_null($siteKey)) {
|
30 |
+
$this->preparationSuccessful = false;
|
31 |
+
$this->errors["message"] = "Site key not set";
|
32 |
+
return;
|
33 |
+
}
|
34 |
+
|
35 |
+
static::$url = static::$PLATFORM_API_BASE_URL . $siteKey . "/field-mapping";
|
36 |
+
}
|
37 |
+
|
38 |
+
protected function prepareHeaders(Mage_Core_Model_Website $website) {
|
39 |
+
$apiKey = Mage::getResourceModel("choiceai_searchcore/config")
|
40 |
+
->getValue($website->getWebsiteId(), ChoiceAI_Searchcore_Helper_Confighelper::API_KEY);
|
41 |
+
$secretKey = Mage::getResourceModel("choiceai_searchcore/config")
|
42 |
+
->getValue($website->getWebsiteId(), ChoiceAI_Searchcore_Helper_Confighelper::SECRET_KEY);
|
43 |
+
if(is_null($secretKey) || is_null($apiKey)) {
|
44 |
+
$this->preparationSuccessful = false;
|
45 |
+
$this->errors["message"] = "Site key not set";
|
46 |
+
return;
|
47 |
+
}
|
48 |
+
$this->headers["Authorization"] = base64_encode($apiKey.":" .$secretKey);
|
49 |
+
}
|
50 |
+
|
51 |
+
protected function prepareData($website) {
|
52 |
+
$featureFields = Mage::getResourceModel("choiceai_searchcore/field_collection")->getFeatureFields($website);
|
53 |
+
$featureFieldMap = array();
|
54 |
+
foreach($featureFields as $field) {
|
55 |
+
if($field[ChoiceAI_Searchcore_Model_Field::featured_field] == ChoiceAI_Searchcore_Helper_Constants::FEATURE_FIELD_IMAGE_URL) {
|
56 |
+
$featureFieldMap[$field[ChoiceAI_Searchcore_Model_Field::featured_field]] = "choiceai_NA";
|
57 |
+
continue;
|
58 |
+
}
|
59 |
+
$featureFieldMap[$field[ChoiceAI_Searchcore_Model_Field::featured_field]] =
|
60 |
+
$field[ChoiceAI_Searchcore_Model_Field::field_name];
|
61 |
+
}
|
62 |
+
$this->setData("fieldMapping", $featureFieldMap);
|
63 |
+
}
|
64 |
+
|
65 |
+
protected function postProcess(ChoiceAI_Searchcore_Model_Api_Response $response) {
|
66 |
+
if(!$response->isSuccess()) {
|
67 |
+
return $response;
|
68 |
+
}
|
69 |
+
$responseObj = $response->getResponse();
|
70 |
+
if(!array_key_exists(self::STATUS, $responseObj)) {
|
71 |
+
$response->setSuccess(false);
|
72 |
+
$response->setMessage('Invalid response from choiceai');
|
73 |
+
return $response;
|
74 |
+
}
|
75 |
+
if($responseObj[self::STATUS] != 200) {
|
76 |
+
$response->setSuccess(false);
|
77 |
+
$response->setMessage("status code :" .$responseObj[self::STATUS].",".
|
78 |
+
(array_key_exists(self::MESSAGE, $responseObj)?$responseObj[self::MESSAGE]:""));
|
79 |
+
return $response;
|
80 |
+
}
|
81 |
+
return $response;
|
82 |
+
}
|
83 |
+
}
|
app/code/local/ChoiceAI/Searchcore/Model/Api/Task/Validatekeys.php
ADDED
@@ -0,0 +1,73 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* class to validate the secret key and site key with choiceai
|
5 |
+
*
|
6 |
+
* @category ChoiceAI
|
7 |
+
* @package ChoiceAI_Searchcore
|
8 |
+
* @copyright Copyright (c) MineWhat
|
9 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
10 |
+
*/
|
11 |
+
class ChoiceAI_Searchcore_Model_Api_Task_Validatekeys extends ChoiceAI_Searchcore_Model_Api_Task {
|
12 |
+
|
13 |
+
const method = Zend_Http_Client::POST;
|
14 |
+
|
15 |
+
const SECRET_KEY = "secretKey";
|
16 |
+
|
17 |
+
const SITE_KEY = "siteKey";
|
18 |
+
|
19 |
+
const API_KEY = 'apiKey';
|
20 |
+
|
21 |
+
const USERNAME = 'username';
|
22 |
+
|
23 |
+
public function prepare(Mage_Core_Model_Website $website) {
|
24 |
+
$this->prepareUrl();
|
25 |
+
$this->prepareHeaders($website);
|
26 |
+
$this->prepareParams();
|
27 |
+
return $this;
|
28 |
+
}
|
29 |
+
|
30 |
+
protected function prepareUrl() {
|
31 |
+
static::$url = static::$RECOMMENDATION_SETTINGS_URL . "dashboard/authenticateMagento";
|
32 |
+
return $this;
|
33 |
+
}
|
34 |
+
|
35 |
+
protected function prepareHeaders() {
|
36 |
+
return $this;
|
37 |
+
}
|
38 |
+
|
39 |
+
protected function prepareParams() {
|
40 |
+
$params = $this->getData();
|
41 |
+
if(!array_key_exists(static::SECRET_KEY, $params)) {
|
42 |
+
$this->preparationSuccessful = false;
|
43 |
+
$this->errors[ChoiceAI_Searchcore_Helper_Confighelper::SECRET_KEY] = "secret key expected";
|
44 |
+
}
|
45 |
+
if(!array_key_exists(static::SITE_KEY, $params)) {
|
46 |
+
$this->preparationSuccessful = false;
|
47 |
+
$this->errors[ChoiceAI_Searchcore_Helper_Confighelper::SITE_KEY] = "site key expected";
|
48 |
+
}
|
49 |
+
if(sizeof($this->getData()) > 2) {
|
50 |
+
$this->preparationSuccessful = false;
|
51 |
+
$this->errors["message"] = "Extra Parameters Present";
|
52 |
+
}
|
53 |
+
if(sizeof($this->errors) == 0) {
|
54 |
+
$this->preparationSuccessful = true;
|
55 |
+
}
|
56 |
+
$this->isRawData = true;
|
57 |
+
return $this;
|
58 |
+
}
|
59 |
+
|
60 |
+
protected function postProcess(ChoiceAI_Searchcore_Model_Api_Response $response) {
|
61 |
+
if(!$response->isSuccess()) {
|
62 |
+
return $response;
|
63 |
+
}
|
64 |
+
$responseObj = $response->getResponse();
|
65 |
+
if(!array_key_exists(self::API_KEY, $responseObj) || !array_key_exists(self::USERNAME, $responseObj)) {
|
66 |
+
$response->setSuccess(false);
|
67 |
+
$response->setMessage('Invalid Combination, Please Refer Docs');
|
68 |
+
}
|
69 |
+
return $response;
|
70 |
+
}
|
71 |
+
}
|
72 |
+
|
73 |
+
?>
|
app/code/local/ChoiceAI/Searchcore/Model/Config.php
ADDED
@@ -0,0 +1,47 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* This class maintains all the configuration w.r.t ChoiceAI with site basis
|
5 |
+
*
|
6 |
+
* @category ChoiceAI
|
7 |
+
* @package ChoiceAI_Searchcore
|
8 |
+
* @copyright Copyright (c) MineWhat
|
9 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
10 |
+
*/
|
11 |
+
class ChoiceAI_Searchcore_Model_Config extends Mage_Core_Model_Abstract {
|
12 |
+
|
13 |
+
const KEY = "choiceai_key";
|
14 |
+
|
15 |
+
const VALUE = 'value';
|
16 |
+
|
17 |
+
const WEBSITE_ID = 'website_id';
|
18 |
+
|
19 |
+
const FEED_LOCK_TIME = 'feed_lock_time';
|
20 |
+
|
21 |
+
const FEED_LOCK = 'feed_lock';
|
22 |
+
|
23 |
+
const FEED_LOCK_TRUE = '1';
|
24 |
+
|
25 |
+
const FEED_LOCK_FALSE = '0';
|
26 |
+
|
27 |
+
const FEED_STATUS = 'feed_status';
|
28 |
+
|
29 |
+
const MAX_FEED_LOCK_TIME = 6;
|
30 |
+
|
31 |
+
const LAST_UPLOAD_TIME = 'lastUpload';
|
32 |
+
|
33 |
+
const FILTER_DELIMITER = "|`";
|
34 |
+
|
35 |
+
const FILTER = 'filter';
|
36 |
+
|
37 |
+
/**
|
38 |
+
*
|
39 |
+
* @return void
|
40 |
+
*/
|
41 |
+
protected function _construct()
|
42 |
+
{
|
43 |
+
$this->_init('choiceai_searchcore/config');
|
44 |
+
}
|
45 |
+
}
|
46 |
+
|
47 |
+
?>
|
app/code/local/ChoiceAI/Searchcore/Model/Field.php
ADDED
@@ -0,0 +1,342 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* This class maintains the config of the fields that are needed by choiceai
|
5 |
+
*
|
6 |
+
* @category ChoiceAI
|
7 |
+
* @package ChoiceAI_Searchcore
|
8 |
+
* @copyright Copyright (c) MineWhat
|
9 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
10 |
+
*/
|
11 |
+
class ChoiceAI_Searchcore_Model_Field extends Mage_Core_Model_Abstract
|
12 |
+
{
|
13 |
+
|
14 |
+
/**
|
15 |
+
* field name column in db
|
16 |
+
*/
|
17 |
+
const field_name = "field_name";
|
18 |
+
|
19 |
+
/**
|
20 |
+
* datatype column name in db
|
21 |
+
*/
|
22 |
+
const datatype = "datatype";
|
23 |
+
|
24 |
+
/**
|
25 |
+
* autosuggest column name in db
|
26 |
+
*/
|
27 |
+
const autosuggest = "autosuggest";
|
28 |
+
|
29 |
+
/**
|
30 |
+
* featured_field column name in db
|
31 |
+
*/
|
32 |
+
const featured_field = "featured_field";
|
33 |
+
|
34 |
+
/**
|
35 |
+
* displayable column name in db
|
36 |
+
*/
|
37 |
+
const dislayable = "displayed";
|
38 |
+
|
39 |
+
const multivalued = 'multivalued';
|
40 |
+
|
41 |
+
/**
|
42 |
+
* website id column name in db
|
43 |
+
*/
|
44 |
+
const website_id = "website_id";
|
45 |
+
|
46 |
+
const status = 'status';
|
47 |
+
|
48 |
+
/**
|
49 |
+
* All possible data type values supported choiceai
|
50 |
+
* @var array
|
51 |
+
*/
|
52 |
+
public static $data_types = array(ChoiceAI_Searchcore_Helper_Constants::CHOICEAI_DATATYPE_TEXT, ChoiceAI_Searchcore_Helper_Constants::CHOICEAI_DATATYPE_LONGTEXT,
|
53 |
+
ChoiceAI_Searchcore_Helper_Constants::CHOICEAI_DATATYPE_LINK, ChoiceAI_Searchcore_Helper_Constants::CHOICEAI_DATATYPE_NUMBER,
|
54 |
+
ChoiceAI_Searchcore_Helper_Constants::CHOICEAI_DATATYPE_DECIMAL, ChoiceAI_Searchcore_Helper_Constants::CHOICEAI_DATATYPE_DATE);
|
55 |
+
|
56 |
+
|
57 |
+
public static $displayableFeatureFields = array('title', 'price',
|
58 |
+
'brand', 'color', 'size', 'imageUrl', 'productUrl');
|
59 |
+
|
60 |
+
public static $featurefields = array();
|
61 |
+
|
62 |
+
/**
|
63 |
+
*
|
64 |
+
* @return void
|
65 |
+
*/
|
66 |
+
protected function _construct()
|
67 |
+
{
|
68 |
+
$this->_init('choiceai_searchcore/field');
|
69 |
+
ChoiceAI_Searchcore_Model_Field::$featurefields = $this->getFeaturedFields();
|
70 |
+
|
71 |
+
}
|
72 |
+
|
73 |
+
|
74 |
+
/**
|
75 |
+
* Save fields
|
76 |
+
*
|
77 |
+
* @return void
|
78 |
+
*/
|
79 |
+
public function saveFields($collection)
|
80 |
+
{
|
81 |
+
$this->_getResource()->beginTransaction();
|
82 |
+
try {
|
83 |
+
foreach ($collection as $data) {
|
84 |
+
if (sizeof($data) > 0) {
|
85 |
+
if (array_key_exists("add", $data)) {
|
86 |
+
$data["add"]->save();
|
87 |
+
} else if (array_key_exists("delete", $data)) {
|
88 |
+
$data["delete"]->delete();
|
89 |
+
}
|
90 |
+
}
|
91 |
+
}
|
92 |
+
|
93 |
+
$this->_getResource()->commit();
|
94 |
+
} catch (Exception $e) {
|
95 |
+
$this->_getResource()->rollBack();
|
96 |
+
Mage::helper("choiceai_searchcore")->log(Zend_Log::ERR, "Saving fields failed because " . $e->getMessage());
|
97 |
+
return array('OTHERS' => $e->getMessage());
|
98 |
+
}
|
99 |
+
return true;
|
100 |
+
|
101 |
+
}
|
102 |
+
|
103 |
+
/*
|
104 |
+
* method to get the featured fields
|
105 |
+
*/
|
106 |
+
public function getFeaturedFields()
|
107 |
+
{
|
108 |
+
$featuredFields = array();
|
109 |
+
$featuredFields["uniqueId"] = $this->getField("text", "false", "false");
|
110 |
+
$featuredFields["sellingPrice"] = $this->getField("decimal", "false", "false");
|
111 |
+
$featuredFields["discount"] = $this->getField("decimal", "false", "false");
|
112 |
+
$featuredFields["rating"] = $this->getField("decimal", "false", "false");
|
113 |
+
$featuredFields["brandId"] = $this->getField("text", "false", "false");
|
114 |
+
$featuredFields[ChoiceAI_Searchcore_Model_Resource_Field::CAT_LEVEL_1_NAME] =
|
115 |
+
$this->getField("text", "false", "false");
|
116 |
+
$featuredFields[ChoiceAI_Searchcore_Model_Resource_Field::CAT_LEVEL_2_NAME] =
|
117 |
+
$this->getField("text", "false", "false");
|
118 |
+
$featuredFields[ChoiceAI_Searchcore_Model_Resource_Field::CAT_LEVEL_3_NAME] =
|
119 |
+
$this->getField("text", "false", "false");
|
120 |
+
$featuredFields[ChoiceAI_Searchcore_Model_Resource_Field::CAT_LEVEL_4_NAME] =
|
121 |
+
$this->getField("text", "false", "false");
|
122 |
+
$featuredFields[ChoiceAI_Searchcore_Model_Resource_Field::CAT_LEVEL_1] =
|
123 |
+
$this->getField("text", "true", "false");
|
124 |
+
$featuredFields[ChoiceAI_Searchcore_Model_Resource_Field::CAT_LEVEL_2] =
|
125 |
+
$this->getField("text", "true", "false");
|
126 |
+
$featuredFields[ChoiceAI_Searchcore_Model_Resource_Field::CAT_LEVEL_3] =
|
127 |
+
$this->getField("text", "true", "false");
|
128 |
+
$featuredFields[ChoiceAI_Searchcore_Model_Resource_Field::CAT_LEVEL_4] =
|
129 |
+
$this->getField("text", "true", "false");
|
130 |
+
$featuredFields["category"] = $this->getField("text", "true", "true");
|
131 |
+
$featuredFields["subCategory"] = $this->getField("text", "true", "true");
|
132 |
+
$featuredFields["color"] = $this->getField("text", "true", "false");
|
133 |
+
$featuredFields["size"] = $this->getField("text", "true", "false");
|
134 |
+
$featuredFields["availability"] = $this->getField("bool", "false", "false");
|
135 |
+
$featuredFields["description"] = $this->getField("longText", "false", "false");
|
136 |
+
$featuredFields["imageUrl"] = $this->getField("link", "true", "false");
|
137 |
+
$featuredFields["productUrl"] = $this->getField("link", "false", "false");
|
138 |
+
$featuredFields["brand"] = $this->getField("text", "false", "true");
|
139 |
+
$featuredFields["price"] = $this->getField("decimal", "false", "false");
|
140 |
+
$featuredFields["title"] = $this->getField("text", "false", "true");
|
141 |
+
$featuredFields["gender"] = $this->getField("text", "false", "false");
|
142 |
+
$featuredFields["choiceaiVisibility"] = $this->getField("text", "false", "false");
|
143 |
+
return $featuredFields;
|
144 |
+
}
|
145 |
+
|
146 |
+
public function getField($dataType, $multiValued, $autosuggest)
|
147 |
+
{
|
148 |
+
return array(self::status => 1, self::datatype => $dataType,
|
149 |
+
self::multivalued => ($multiValued == "true") ? 1 : 0,
|
150 |
+
self::autosuggest => ($autosuggest == "true") ? 1 : 0);
|
151 |
+
|
152 |
+
}
|
153 |
+
|
154 |
+
public function rebuildConfigCache(Mage_Core_Model_Website $website) {
|
155 |
+
$this->setBrandFieldName($website);
|
156 |
+
$this->setCategoryFieldName($website);
|
157 |
+
$this->setImageUrlFieldName($website);
|
158 |
+
$this->setPriceFieldName($website);
|
159 |
+
$this->setProductUrlFieldName($website);
|
160 |
+
$this->setTitleFieldName($website);
|
161 |
+
}
|
162 |
+
|
163 |
+
public function getPriceFieldName()
|
164 |
+
{
|
165 |
+
$priceFieldConfig =
|
166 |
+
Mage::helper('choiceai_searchcore')->getEngineConfigData(ChoiceAI_Searchcore_Helper_Constants::FEATURE_FIELD_PRICE);
|
167 |
+
if (array_key_exists(ChoiceAI_Searchcore_Helper_Constants::FEATURE_FIELD_PRICE, $priceFieldConfig)) {
|
168 |
+
return $priceFieldConfig[ChoiceAI_Searchcore_Helper_Constants::FEATURE_FIELD_PRICE];
|
169 |
+
}
|
170 |
+
$this->rebuildConfigCache(Mage::app()->getWebsite());
|
171 |
+
$priceField = $this->_getResource()->getFieldByFeatureField(Mage::app()->getWebsite()->getWebsiteId(),
|
172 |
+
ChoiceAI_Searchcore_Helper_Constants::FEATURE_FIELD_PRICE);
|
173 |
+
return $priceField;
|
174 |
+
}
|
175 |
+
|
176 |
+
public function setPriceFieldName(Mage_Core_Model_Website $website) {
|
177 |
+
$priceName = $this->getResource()->getFieldByFeatureField($website->getWebsiteId(),
|
178 |
+
ChoiceAI_Searchcore_Helper_Constants::FEATURE_FIELD_PRICE);
|
179 |
+
Mage::helper('choiceai_searchcore')->saveConfig($website,
|
180 |
+
array(ChoiceAI_Searchcore_Helper_Constants::FEATURE_FIELD_PRICE => $priceName));
|
181 |
+
}
|
182 |
+
|
183 |
+
public function getImageUrlFieldName()
|
184 |
+
{
|
185 |
+
$imageUrlFieldName = $this->_getResource()->getFieldByFeatureField(Mage::app()->getWebsite()->getWebsiteId(),
|
186 |
+
ChoiceAI_Searchcore_Helper_Constants::FEATURE_FIELD_IMAGE_URL);
|
187 |
+
return $imageUrlFieldName;
|
188 |
+
}
|
189 |
+
|
190 |
+
public function setImageUrlFieldName(Mage_Core_Model_Website $website)
|
191 |
+
{
|
192 |
+
$imageField = $this->getResource()->getFieldByFeatureField($website->getWebsiteId(),
|
193 |
+
ChoiceAI_Searchcore_Helper_Constants::FEATURE_FIELD_IMAGE_URL);
|
194 |
+
Mage::helper('choiceai_searchcore')->saveConfig($website,
|
195 |
+
array(ChoiceAI_Searchcore_Helper_Constants::FEATURE_FIELD_IMAGE_URL => $imageField));
|
196 |
+
}
|
197 |
+
|
198 |
+
public function getProductUrlFieldName()
|
199 |
+
{
|
200 |
+
$fieldConfig =
|
201 |
+
Mage::helper('choiceai_searchcore')
|
202 |
+
->getEngineConfigData(ChoiceAI_Searchcore_Helper_Constants::FEATURE_FIELD_PRODUCT_URL);
|
203 |
+
if(array_key_exists(ChoiceAI_Searchcore_Helper_Constants::FEATURE_FIELD_PRODUCT_URL, $fieldConfig)) {
|
204 |
+
return $fieldConfig[ChoiceAI_Searchcore_Helper_Constants::FEATURE_FIELD_PRODUCT_URL];
|
205 |
+
}
|
206 |
+
$this->rebuildConfigCache(Mage::app()->getWebsite());
|
207 |
+
$productUrl = $this->_getResource()->getFieldByFeatureField(Mage::app()->getWebsite()->getWebsiteId(),
|
208 |
+
ChoiceAI_Searchcore_Helper_Constants::FEATURE_FIELD_PRODUCT_URL);
|
209 |
+
return $productUrl;
|
210 |
+
|
211 |
+
}
|
212 |
+
|
213 |
+
public function setProductUrlFieldName(Mage_Core_Model_Website $website)
|
214 |
+
{
|
215 |
+
$productUrlField = $this->getResource()->getFieldByFeatureField($website->getWebsiteId(),
|
216 |
+
ChoiceAI_Searchcore_Helper_Constants::FEATURE_FIELD_PRODUCT_URL);
|
217 |
+
Mage::helper('choiceai_searchcore')->saveConfig($website,
|
218 |
+
array(ChoiceAI_Searchcore_Helper_Constants::FEATURE_FIELD_PRODUCT_URL => $productUrlField));
|
219 |
+
}
|
220 |
+
|
221 |
+
public function getCategoryFieldName()
|
222 |
+
{
|
223 |
+
$fieldConfig =
|
224 |
+
Mage::helper('choiceai_searchcore')
|
225 |
+
->getEngineConfigData(ChoiceAI_Searchcore_Helper_Constants::FEATURE_FIELD_CATEGORY);
|
226 |
+
if(array_key_exists(ChoiceAI_Searchcore_Helper_Constants::FEATURE_FIELD_CATEGORY, $fieldConfig)) {
|
227 |
+
return $fieldConfig[ChoiceAI_Searchcore_Helper_Constants::FEATURE_FIELD_CATEGORY];
|
228 |
+
}
|
229 |
+
$this->rebuildConfigCache(Mage::app()->getWebsite());
|
230 |
+
$categoryField = $this->_getResource()->getFieldByFeatureField(Mage::app()->getWebsite()->getWebsiteId(),
|
231 |
+
ChoiceAI_Searchcore_Helper_Constants::FEATURE_FIELD_CATEGORY);
|
232 |
+
return $categoryField;
|
233 |
+
}
|
234 |
+
|
235 |
+
public function setCategoryFieldName(Mage_Core_Model_Website $website)
|
236 |
+
{
|
237 |
+
$categortField = $this->getResource()->getFieldByFeatureField($website->getWebsiteId(),
|
238 |
+
ChoiceAI_Searchcore_Helper_Constants::FEATURE_FIELD_CATEGORY);
|
239 |
+
Mage::helper('choiceai_searchcore')->saveConfig($website,
|
240 |
+
array(ChoiceAI_Searchcore_Helper_Constants::FEATURE_FIELD_CATEGORY => $categortField));
|
241 |
+
}
|
242 |
+
|
243 |
+
public function getBrandFieldName()
|
244 |
+
{
|
245 |
+
$fieldConfig =
|
246 |
+
Mage::helper('choiceai_searchcore')
|
247 |
+
->getEngineConfigData(ChoiceAI_Searchcore_Helper_Constants::FEATURE_FIELD_BRAND);
|
248 |
+
if(array_key_exists(ChoiceAI_Searchcore_Helper_Constants::FEATURE_FIELD_BRAND, $fieldConfig)) {
|
249 |
+
return $fieldConfig[ChoiceAI_Searchcore_Helper_Constants::FEATURE_FIELD_BRAND];
|
250 |
+
}
|
251 |
+
$this->rebuildConfigCache(Mage::app()->getWebsite());
|
252 |
+
$brandField = $this->_getResource()->getFieldByFeatureField(Mage::app()->getWebsite()->getWebsiteId(),
|
253 |
+
ChoiceAI_Searchcore_Helper_Constants::FEATURE_FIELD_BRAND);
|
254 |
+
return $brandField;
|
255 |
+
}
|
256 |
+
|
257 |
+
public function setBrandFieldName(Mage_Core_Model_Website $website)
|
258 |
+
{
|
259 |
+
$brandField = $this->getResource()->getFieldByFeatureField($website->getWebsiteId(),
|
260 |
+
ChoiceAI_Searchcore_Helper_Constants::FEATURE_FIELD_BRAND);
|
261 |
+
Mage::helper('choiceai_searchcore')->saveConfig($website,
|
262 |
+
array(ChoiceAI_Searchcore_Helper_Constants::FEATURE_FIELD_BRAND => $brandField));
|
263 |
+
}
|
264 |
+
|
265 |
+
public function getTitleFieldName()
|
266 |
+
{
|
267 |
+
$fieldConfig =
|
268 |
+
Mage::helper('choiceai_searchcore')
|
269 |
+
->getEngineConfigData(ChoiceAI_Searchcore_Helper_Constants::FEATURE_FIELD_TITLE);
|
270 |
+
if(array_key_exists(ChoiceAI_Searchcore_Helper_Constants::FEATURE_FIELD_TITLE, $fieldConfig)) {
|
271 |
+
return $fieldConfig[ChoiceAI_Searchcore_Helper_Constants::FEATURE_FIELD_TITLE];
|
272 |
+
}
|
273 |
+
$this->rebuildConfigCache(Mage::app()->getWebsite());
|
274 |
+
$titleField = $this->_getResource()->getFieldByFeatureField(Mage::app()->getWebsite()->getWebsiteId(),
|
275 |
+
ChoiceAI_Searchcore_Helper_Constants::FEATURE_FIELD_TITLE);
|
276 |
+
return $titleField;
|
277 |
+
}
|
278 |
+
|
279 |
+
public function setTitleFieldName(Mage_Core_Model_Website $website)
|
280 |
+
{
|
281 |
+
$titleField = $this->getResource()->getFieldByFeatureField($website->getWebsiteId(),
|
282 |
+
ChoiceAI_Searchcore_Helper_Constants::FEATURE_FIELD_TITLE);
|
283 |
+
Mage::helper('choiceai_searchcore')->saveConfig($website,
|
284 |
+
array(ChoiceAI_Searchcore_Helper_Constants::FEATURE_FIELD_TITLE => $titleField));
|
285 |
+
}
|
286 |
+
|
287 |
+
public function getImageFields($website)
|
288 |
+
{
|
289 |
+
$conf = Mage::helper('choiceai_searchcore')->getEngineConfigData(ChoiceAI_Searchcore_Helper_Constants::FIELD_CONF, $website, true);
|
290 |
+
$fieldConf = json_decode($conf[ChoiceAI_Searchcore_Helper_Constants::FIELD_CONF], true);
|
291 |
+
if (!is_array($fieldConf)) {
|
292 |
+
return array();
|
293 |
+
}
|
294 |
+
$imageFields = array();
|
295 |
+
foreach ($fieldConf as $field => $conf) {
|
296 |
+
if (!is_array($conf) || !array_key_exists('image_full', $conf)) {
|
297 |
+
continue;
|
298 |
+
}
|
299 |
+
$imageFields[$field] = Mage::helper('choiceai_searchcore')->isConfigTrue($website, 'image_full') ? true : false;
|
300 |
+
}
|
301 |
+
return $imageFields;
|
302 |
+
}
|
303 |
+
|
304 |
+
public function getCopyFields($website)
|
305 |
+
{
|
306 |
+
$conf = Mage::helper('choiceai_searchcore')->getEngineConfigData(ChoiceAI_Searchcore_Helper_Constants::FIELD_CONF, $website, true);
|
307 |
+
|
308 |
+
$fieldConf = json_decode($conf[ChoiceAI_Searchcore_Helper_Constants::FIELD_CONF], true);
|
309 |
+
if (!is_array($fieldConf)) {
|
310 |
+
return array();
|
311 |
+
}
|
312 |
+
$imageFields = array();
|
313 |
+
foreach ($fieldConf as $field => $conf) {
|
314 |
+
if (!is_array($conf) || !array_key_exists('copy_field', $conf)) {
|
315 |
+
continue;
|
316 |
+
}
|
317 |
+
$imageFields[$field] = $conf['copy_field'];
|
318 |
+
}
|
319 |
+
return $imageFields;
|
320 |
+
}
|
321 |
+
|
322 |
+
public function validateDatatype($choiceaiDatatype, $magentoDatatype)
|
323 |
+
{
|
324 |
+
if ($choiceaiDatatype == ChoiceAI_Searchcore_Helper_Constants::CHOICEAI_DATATYPE_TEXT || $choiceaiDatatype == ChoiceAI_Searchcore_Helper_Constants::CHOICEAI_DATATYPE_LONGTEXT ||
|
325 |
+
$choiceaiDatatype == ChoiceAI_Searchcore_Helper_Constants::CHOICEAI_DATATYPE_LINK
|
326 |
+
) {
|
327 |
+
return true;
|
328 |
+
}
|
329 |
+
if ($choiceaiDatatype == ChoiceAI_Searchcore_Helper_Constants::CHOICEAI_DATATYPE_NUMBER && $magentoDatatype == ChoiceAI_Searchcore_Helper_Constants::FIELD_TYPE_NUMBER) {
|
330 |
+
return true;
|
331 |
+
}
|
332 |
+
if ($choiceaiDatatype == ChoiceAI_Searchcore_Helper_Constants::CHOICEAI_DATATYPE_DECIMAL && $magentoDatatype == ChoiceAI_Searchcore_Helper_Constants::FIELD_TYPE_NUMBER) {
|
333 |
+
return true;
|
334 |
+
}
|
335 |
+
if ($choiceaiDatatype == ChoiceAI_Searchcore_Helper_Constants::CHOICEAI_DATATYPE_DATE && $magentoDatatype == ChoiceAI_Searchcore_Helper_Constants::FIELD_TYPE_DATE) {
|
336 |
+
return true;
|
337 |
+
}
|
338 |
+
return false;
|
339 |
+
}
|
340 |
+
}
|
341 |
+
|
342 |
+
?>
|
app/code/local/ChoiceAI/Searchcore/Model/Observer.php
ADDED
@@ -0,0 +1,201 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @category ChoiceAI
|
5 |
+
* @package ChoiceAI_Searchcore
|
6 |
+
* @copyright Copyright (c) MineWhat
|
7 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
*/
|
9 |
+
class ChoiceAI_Searchcore_Model_Observer {
|
10 |
+
|
11 |
+
/**
|
12 |
+
* Observer method to track the add to cart
|
13 |
+
* @return $this
|
14 |
+
*/
|
15 |
+
public function trackAddToCart(Varien_Event_Observer $observer) {
|
16 |
+
if(!Mage::helper('choiceai_searchcore')->isExecutable()) {
|
17 |
+
return;
|
18 |
+
}
|
19 |
+
$product = $observer->getEvent()->getProduct();
|
20 |
+
if(!$product instanceof Mage_Catalog_Model_Product) {
|
21 |
+
Mage::helper('choiceai_searchcore')->log(Zend_Log::ERR, 'CART_TRACKER:product is not a valid type');
|
22 |
+
return $this;
|
23 |
+
}
|
24 |
+
$uniqueId = Mage::helper('choiceai_searchcore/feedhelper')->getUniqueId($product);
|
25 |
+
$response = Mage::getModel('choiceai_searchcore/api_task_trackcart')
|
26 |
+
->setData('data', array('pid' => $uniqueId,
|
27 |
+
'visit_type' => 'repeat'))
|
28 |
+
->setData('ip', isset($_SERVER['HTTP_X_FORWARDED_FOR'])?$_SERVER['HTTP_X_FORWARDED_FOR']:$_SERVER['REMOTE_ADDR'])
|
29 |
+
->setData('agent', $_SERVER['HTTP_USER_AGENT'])
|
30 |
+
->prepare(Mage::app()->getWebsite())
|
31 |
+
->process();
|
32 |
+
Mage::helper('choiceai_searchcore')->log(Zend_Log::DEBUG, "CART_TRACKER: request with uniqueId ".$uniqueId);
|
33 |
+
if(!$response->isSuccess()) {
|
34 |
+
Mage::helper('choiceai_searchcore')
|
35 |
+
->log(Zend_Log::ERR, 'CART_TRACKER:request failed because ' .json_encode($response->getErrors()));
|
36 |
+
}
|
37 |
+
return $this;
|
38 |
+
}
|
39 |
+
|
40 |
+
/**
|
41 |
+
* Observer method to track orders
|
42 |
+
* @return $this
|
43 |
+
*/
|
44 |
+
public function trackOrder(Varien_Event_Observer $observer) {
|
45 |
+
if(!Mage::helper('choiceai_searchcore')->isExecutable()) {
|
46 |
+
return;
|
47 |
+
}
|
48 |
+
$payment = $observer->getEvent()->getPayment();
|
49 |
+
/* @var Mage_Sales_Model_Order_Payment */
|
50 |
+
|
51 |
+
if(!$payment instanceof Mage_Sales_Model_Order_Payment) {
|
52 |
+
Mage::helper('choiceai_searchcore')->log(Zend_Log::ERR, 'ORDER_TRACKER:payment is not a valid type');
|
53 |
+
return $this;
|
54 |
+
}
|
55 |
+
$items = $payment->getOrder()->getAllVisibleItems();
|
56 |
+
|
57 |
+
if(!is_array($items)) {
|
58 |
+
return $this;
|
59 |
+
}
|
60 |
+
|
61 |
+
foreach($items as $item) {
|
62 |
+
if($item instanceof Mage_Sales_Model_Order) {
|
63 |
+
Mage::helper('choiceai_searchcore')
|
64 |
+
->log(Zend_Log::ERR, 'ORDER_TRACKER:request failed because item is of instancetype ' . get_class($item));
|
65 |
+
continue;
|
66 |
+
}
|
67 |
+
$product =$item->getProduct();
|
68 |
+
if(!$product instanceof Mage_Catalog_Model_Product) {
|
69 |
+
return $this;
|
70 |
+
}
|
71 |
+
$uniqueId = Mage::helper('choiceai_searchcore/feedhelper')->getUniqueId($product, $item);
|
72 |
+
$response = Mage::getModel('choiceai_searchcore/api_task_trackorder')
|
73 |
+
->setData('data',
|
74 |
+
array('visit_type' => 'repeat',
|
75 |
+
'pid' => $uniqueId,
|
76 |
+
'qty' => $item->getQtyOrdered(),
|
77 |
+
'price' => $item->getPriceInclTax()))
|
78 |
+
->setData('ip', isset($_SERVER['HTTP_X_FORWARDED_FOR']) ? $_SERVER['HTTP_X_FORWARDED_FOR'] : $_SERVER['REMOTE_ADDR'])
|
79 |
+
->setData('agent', $_SERVER['HTTP_USER_AGENT'])
|
80 |
+
->prepare(Mage::app()->getWebsite())
|
81 |
+
->process();
|
82 |
+
Mage::helper('choiceai_searchcore')->log(Zend_Log::DEBUG, "ORDER_TRACKER: request with uniqueId ".$uniqueId);
|
83 |
+
|
84 |
+
if(!$response->isSuccess()) {
|
85 |
+
Mage::helper('choiceai_searchcore')
|
86 |
+
->log(Zend_Log::ERR, 'ORDER_TRACKER:request failed because ' . json_encode($response->getErrors()));
|
87 |
+
}
|
88 |
+
Mage::getSingleton('choiceai_searchcore/sync')->addProduct($product);
|
89 |
+
}
|
90 |
+
return $this;
|
91 |
+
}
|
92 |
+
|
93 |
+
/**
|
94 |
+
* Method to sync the product catalog through cron
|
95 |
+
* @param Varien_Event_Observer $observer
|
96 |
+
* @return $this
|
97 |
+
*/
|
98 |
+
public function syncFull($observer)
|
99 |
+
{
|
100 |
+
if(!Mage::helper('choiceai_searchcore')->isExecutable()) {
|
101 |
+
return;
|
102 |
+
}
|
103 |
+
$websiteCollection = Mage::getModel('core/website')->getCollection()->load();
|
104 |
+
if(!$websiteCollection instanceof Varien_Data_Collection) {
|
105 |
+
return $this;
|
106 |
+
}
|
107 |
+
foreach ($websiteCollection as $website) {
|
108 |
+
if($website instanceof Mage_Core_Model_Website) {
|
109 |
+
return $this;
|
110 |
+
}
|
111 |
+
Mage::getResourceModel('choiceai_searchcore/config')
|
112 |
+
->setValue($website->getWebsiteId(), ChoiceAI_Searchcore_Helper_Constants::IS_CRON_ENABLED, 1);
|
113 |
+
Mage::getSingleton('choiceai_searchcore/feed_feedmanager')->process(true, $website);
|
114 |
+
}
|
115 |
+
return $this;
|
116 |
+
}
|
117 |
+
|
118 |
+
/*
|
119 |
+
* Method to sync the product incremental catalog through cron
|
120 |
+
* @param Varien_Event_Observer $observer
|
121 |
+
* @return $this
|
122 |
+
*/
|
123 |
+
public function syncIncremental($observer)
|
124 |
+
{
|
125 |
+
if(!Mage::helper('choiceai_searchcore')->isExecutable()) {
|
126 |
+
return;
|
127 |
+
}
|
128 |
+
$websiteCollection = Mage::getModel('core/website')->getCollection()->load();
|
129 |
+
if(!$websiteCollection instanceof Varien_Data_Collection) {
|
130 |
+
return $this;
|
131 |
+
}
|
132 |
+
foreach ($websiteCollection as $website) {
|
133 |
+
if($website instanceof Mage_Core_Model_Website) {
|
134 |
+
return $this;
|
135 |
+
}
|
136 |
+
Mage::getResourceModel('choiceai_searchcore/config')
|
137 |
+
->setValue($website->getWebsiteId(), ChoiceAI_Searchcore_Helper_Constants::IS_CRON_ENABLED, 1);
|
138 |
+
Mage::getSingleton('choiceai_searchcore/feed_feedmanager')->process(false, $website);
|
139 |
+
}
|
140 |
+
return $this;
|
141 |
+
}
|
142 |
+
|
143 |
+
/**
|
144 |
+
* Method to track deleted product
|
145 |
+
* @param Varien_Event_Observer $observer
|
146 |
+
* @return void
|
147 |
+
*/
|
148 |
+
public function trackDelete(Varien_Event_Observer $observer) {
|
149 |
+
if(!Mage::helper('choiceai_searchcore')->isExecutable()) {
|
150 |
+
return $this;
|
151 |
+
}
|
152 |
+
$product = $observer->getEvent()->getDataObject();
|
153 |
+
if(!$product instanceof Mage_Catalog_Model_Product) {
|
154 |
+
return $this;
|
155 |
+
}
|
156 |
+
$parentIds = Mage::getModel('catalog/product_type_grouped')->getParentIdsByChild($product->getId());
|
157 |
+
if(!$parentIds)
|
158 |
+
$parentIds = Mage::getModel('catalog/product_type_configurable')->getParentIdsByChild($product->getId());
|
159 |
+
|
160 |
+
if(!is_array($parentIds)) {
|
161 |
+
return $this;
|
162 |
+
}
|
163 |
+
|
164 |
+
foreach($parentIds as $parentId) {
|
165 |
+
$parentProduct = Mage::getModel('catalog/product')->load($parentId);
|
166 |
+
if($parentProduct instanceof Mage_Catalog_Model_Product) {
|
167 |
+
return $this;
|
168 |
+
}
|
169 |
+
Mage::getSingleton('choiceai_searchcore/sync')->addProduct($parentProduct);
|
170 |
+
}
|
171 |
+
Mage::getSingleton('choiceai_searchcore/sync')->deleteProduct($product);
|
172 |
+
return $this;
|
173 |
+
}
|
174 |
+
|
175 |
+
/**
|
176 |
+
* Method to track deleted product
|
177 |
+
* @param Varien_Event_Observer $observer
|
178 |
+
* @return void
|
179 |
+
*/
|
180 |
+
|
181 |
+
public function catalogInventorySave(Varien_Event_Observer $observer) {
|
182 |
+
if(!Mage::helper('choiceai_searchcore')->isExecutable()) {
|
183 |
+
return;
|
184 |
+
}
|
185 |
+
$_item = $observer->getEvent()->getItem();
|
186 |
+
if(!$_item instanceof Mage_Catalog_Order_Item) {
|
187 |
+
return $this;
|
188 |
+
}
|
189 |
+
$product = $_item->getProduct();
|
190 |
+
if(!$product instanceof Mage_Catalog_Model_Product) {
|
191 |
+
return $this;
|
192 |
+
}
|
193 |
+
Mage::getSingleton('choiceai_searchcore/sync')->addProduct($product);
|
194 |
+
return $this;
|
195 |
+
}
|
196 |
+
|
197 |
+
public function saleOrderCancel(Varien_Event_Observer $observer) {
|
198 |
+
return $this;
|
199 |
+
}
|
200 |
+
}
|
201 |
+
?>
|
app/code/local/ChoiceAI/Searchcore/Model/Resource/Attribute.php
ADDED
@@ -0,0 +1,27 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category ChoiceAI
|
4 |
+
* @package ChoiceAI_Searchcore
|
5 |
+
* @copyright Copyright (c) MineWhat
|
6 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
7 |
+
*/
|
8 |
+
class ChoiceAI_Searchcore_Model_Resource_Attribute {
|
9 |
+
|
10 |
+
protected $attributeMap = array();
|
11 |
+
public function getAttributeValue($attributeCode, $value, $product){
|
12 |
+
if(!isset($this->attributeMap[$value])){
|
13 |
+
if(!($product instanceof Mage_Catalog_Model_Product) || Mage::getResourceModel('catalog/product')->getAttribute($attributeCode) == null){
|
14 |
+
return null;
|
15 |
+
}
|
16 |
+
$options = Mage::getResourceModel('catalog/product')->getAttribute($attributeCode)
|
17 |
+
->getSource()->getAllOptions();
|
18 |
+
foreach($options as $option){
|
19 |
+
$this->attributeMap[$option["value"]] = $option["label"];
|
20 |
+
}
|
21 |
+
}
|
22 |
+
return array_key_exists($value, $this->attributeMap)?$this->attributeMap[$value]:null;
|
23 |
+
}
|
24 |
+
|
25 |
+
}
|
26 |
+
|
27 |
+
?>
|
app/code/local/ChoiceAI/Searchcore/Model/Resource/Config.php
ADDED
@@ -0,0 +1,213 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @category ChoiceAI
|
5 |
+
* @package ChoiceAI_Searchcore
|
6 |
+
* @copyright Copyright (c) MineWhat
|
7 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
*/
|
9 |
+
class ChoiceAI_Searchcore_Model_Resource_Config extends Mage_Core_Model_Mysql4_Abstract
|
10 |
+
{
|
11 |
+
|
12 |
+
/**
|
13 |
+
* ChoiceAI Config table Name
|
14 |
+
*
|
15 |
+
* @var string
|
16 |
+
*/
|
17 |
+
protected $_choiceaiConfigTable;
|
18 |
+
|
19 |
+
// date format
|
20 |
+
const DATE_FORMAT = 'Y-m-d H:i:s';
|
21 |
+
|
22 |
+
/**
|
23 |
+
* @return void
|
24 |
+
*/
|
25 |
+
protected function _construct()
|
26 |
+
{
|
27 |
+
$this->_init('choiceai_searchcore/config', 'id');
|
28 |
+
$this->_choiceaiConfigTable = $this->getTable('choiceai_searchcore/config');
|
29 |
+
}
|
30 |
+
|
31 |
+
public function getValues($websiteId, $key) {
|
32 |
+
if(!isset($key) || is_array($key) ){
|
33 |
+
return array();
|
34 |
+
}
|
35 |
+
$adapter = $this->_getReadAdapter();
|
36 |
+
$select = $adapter->select()
|
37 |
+
->from($this->_choiceaiConfigTable, ChoiceAI_Searchcore_Model_Config::VALUE)
|
38 |
+
->where(ChoiceAI_Searchcore_Model_Config::WEBSITE_ID.' = ?', (int)$websiteId)
|
39 |
+
->where(ChoiceAI_Searchcore_Model_Config::KEY.' = ?', $key);
|
40 |
+
$rows = $adapter->fetchAll($select);
|
41 |
+
$values = array();
|
42 |
+
foreach($rows as $row) {
|
43 |
+
if(array_key_exists(ChoiceAI_Searchcore_Model_Config::VALUE, $row)) {
|
44 |
+
$values[] = $row[ChoiceAI_Searchcore_Model_Config::VALUE];
|
45 |
+
}
|
46 |
+
}
|
47 |
+
return $values;
|
48 |
+
}
|
49 |
+
|
50 |
+
/**
|
51 |
+
* @param $website_id
|
52 |
+
* @param $key
|
53 |
+
* @return null|string
|
54 |
+
*/
|
55 |
+
public function getValue($website_id, $key)
|
56 |
+
{
|
57 |
+
$adapter = $this->_getReadAdapter();
|
58 |
+
if(is_array($key)) {
|
59 |
+
$keyValuePair = array();
|
60 |
+
foreach ($key as $eachKey) {
|
61 |
+
$keyValuePair[$eachKey] = $this->getValue($website_id, $eachKey);
|
62 |
+
}
|
63 |
+
return $keyValuePair;
|
64 |
+
}
|
65 |
+
$select = $adapter->select()
|
66 |
+
->from($this->_choiceaiConfigTable, 'value')
|
67 |
+
->where('`'.ChoiceAI_Searchcore_Model_Config::WEBSITE_ID.'` = ?', (int)$website_id)
|
68 |
+
->where('`'.ChoiceAI_Searchcore_Model_Config::KEY.'` = ?', $key);
|
69 |
+
$result = $adapter->fetchOne($select);
|
70 |
+
if($result === false) {
|
71 |
+
return null;
|
72 |
+
}
|
73 |
+
return $result;
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* @param int $website_id
|
78 |
+
* @param string $key
|
79 |
+
* @param string $value
|
80 |
+
* @return void
|
81 |
+
*/
|
82 |
+
public function setValue($website_id, $key, $value = null)
|
83 |
+
{
|
84 |
+
if(is_array($key)) {
|
85 |
+
foreach($key as $eachKey => $eachValue) {
|
86 |
+
$this->setValue($website_id, $eachKey, $eachValue);
|
87 |
+
}
|
88 |
+
return;
|
89 |
+
}
|
90 |
+
if (!isset($value) || $value == "" || !isset($key) || $key == "") {
|
91 |
+
return;
|
92 |
+
}
|
93 |
+
|
94 |
+
$config = Mage::getModel('choiceai_searchcore/config')->getCollection()
|
95 |
+
->addFieldToFilter(ChoiceAI_Searchcore_Model_Config::KEY, $key)
|
96 |
+
->addFieldToFilter(ChoiceAI_Searchcore_Model_Config::WEBSITE_ID, (int)$website_id)
|
97 |
+
->getFirstItem();
|
98 |
+
|
99 |
+
$config->setWebsiteId($website_id)
|
100 |
+
->setChoiceAIKey($key)
|
101 |
+
->setValue($value)
|
102 |
+
->save();
|
103 |
+
}
|
104 |
+
|
105 |
+
public function updateValues($websiteId, $key, $values = array()) {
|
106 |
+
$this->deleteKey($websiteId, $key);
|
107 |
+
$this->beginTransaction();
|
108 |
+
foreach($values as $eachValue) {
|
109 |
+
Mage::getModel('choiceai_searchcore/config')
|
110 |
+
->setWebsiteId($websiteId)
|
111 |
+
->setChoiceAIKey($key)
|
112 |
+
->setValue($eachValue)
|
113 |
+
->save();
|
114 |
+
}
|
115 |
+
$this->commit();
|
116 |
+
}
|
117 |
+
|
118 |
+
public function deleteKey($websiteId, $key) {
|
119 |
+
$write = Mage::getSingleton("core/resource")->getConnection("core_write");
|
120 |
+
$query = "DELETE FROM choiceai_recommendation_conf WHERE " . ChoiceAI_Searchcore_Model_Config::KEY . " = :key"
|
121 |
+
. " and " . ChoiceAI_Searchcore_Model_Config::WEBSITE_ID . " = :website_id";
|
122 |
+
$binds = array(
|
123 |
+
ChoiceAI_Searchcore_Model_Config::KEY => $key,
|
124 |
+
ChoiceAI_Searchcore_Model_Config::WEBSITE_ID => $websiteId
|
125 |
+
);
|
126 |
+
$write->query($query, $binds);
|
127 |
+
|
128 |
+
}
|
129 |
+
|
130 |
+
public function lockSite($website_id) {
|
131 |
+
$this->setValue($website_id, array(
|
132 |
+
ChoiceAI_Searchcore_Model_Config::FEED_LOCK => ChoiceAI_Searchcore_Model_Config::FEED_LOCK_TRUE,
|
133 |
+
ChoiceAI_Searchcore_Model_Config::FEED_LOCK_TIME => date(self::DATE_FORMAT)));
|
134 |
+
|
135 |
+
}
|
136 |
+
|
137 |
+
|
138 |
+
public function unLockSite($website_id) {
|
139 |
+
$this->setValue($website_id, ChoiceAI_Searchcore_Model_Config::FEED_LOCK,
|
140 |
+
ChoiceAI_Searchcore_Model_Config::FEED_LOCK_FALSE);
|
141 |
+
}
|
142 |
+
|
143 |
+
/**
|
144 |
+
* Method will check whether there is a feed lock or not
|
145 |
+
* @param $website_id
|
146 |
+
* @return bool
|
147 |
+
*/
|
148 |
+
public function isLock($website_id) {
|
149 |
+
//fetch the values for feedlock, feed lock time from db
|
150 |
+
$feedLockDetails = $this->getValue($website_id,
|
151 |
+
array(ChoiceAI_Searchcore_Model_Config::FEED_LOCK, ChoiceAI_Searchcore_Model_Config::FEED_LOCK_TIME));
|
152 |
+
//fetch feed lock from @var feedLockDetails
|
153 |
+
$feedLock = array_key_exists(ChoiceAI_Searchcore_Model_Config::FEED_LOCK, $feedLockDetails)?
|
154 |
+
$feedLockDetails[ChoiceAI_Searchcore_Model_Config::FEED_LOCK]:null;
|
155 |
+
if(is_null($feedLock) || $feedLock == ChoiceAI_Searchcore_Model_Config::FEED_LOCK_FALSE){
|
156 |
+
return false;
|
157 |
+
}
|
158 |
+
// Ignoring the feed Lock, if the feed has been locked more than $maxFeedLockTime
|
159 |
+
if($feedLock == ChoiceAI_Searchcore_Model_Config::FEED_LOCK_TRUE &&
|
160 |
+
array_key_exists(ChoiceAI_Searchcore_Model_Config::FEED_LOCK_TIME, $feedLockDetails)) {
|
161 |
+
$feedLockTime = $feedLockDetails[ChoiceAI_Searchcore_Model_Config::FEED_LOCK_TIME];
|
162 |
+
$date = strtotime($feedLockTime);
|
163 |
+
$currentTime = strtotime(date(self::DATE_FORMAT));
|
164 |
+
$diff = abs($date - $currentTime);
|
165 |
+
$maxFeedLockTime = Mage::getConfig()->getNode('default/choiceai/general/max_feed_lock_feed');
|
166 |
+
if(is_null($maxFeedLockTime)) {
|
167 |
+
$maxFeedLockTime = ChoiceAI_Searchcore_Model_Config::MAX_FEED_LOCK_TIME;
|
168 |
+
}
|
169 |
+
if(round($diff / ( 60 * 60 )) > $maxFeedLockTime) {
|
170 |
+
return false;
|
171 |
+
}
|
172 |
+
}
|
173 |
+
return true;
|
174 |
+
}
|
175 |
+
|
176 |
+
/**
|
177 |
+
* Method to get all the filters
|
178 |
+
* @param Mage_Core_Model_Website $website
|
179 |
+
* @return array
|
180 |
+
*/
|
181 |
+
public function getFilters(Mage_Core_Model_Website $website) {
|
182 |
+
$values = Mage::getResourceModel('choiceai_searchcore/config')->getValues($website->getWebsiteId(),
|
183 |
+
ChoiceAI_Searchcore_Model_Config::FILTER);
|
184 |
+
$filters = array();
|
185 |
+
foreach($values as $value) {
|
186 |
+
$explodedValues = explode(ChoiceAI_Searchcore_Model_Config::FILTER_DELIMITER, $value);
|
187 |
+
if(sizeof($explodedValues) < 2) {
|
188 |
+
continue;
|
189 |
+
}
|
190 |
+
$filters[$explodedValues[0]] = $explodedValues[1];
|
191 |
+
}
|
192 |
+
return $filters;
|
193 |
+
}
|
194 |
+
|
195 |
+
public function saveGlobalConfig(Mage_Core_Model_Website $website, $values = array()) {
|
196 |
+
foreach($values as $key => $value ) {
|
197 |
+
}
|
198 |
+
}
|
199 |
+
|
200 |
+
public function deleteAll($websiteId) {
|
201 |
+
$write = Mage::getSingleton("core/resource")->getConnection("core_write");
|
202 |
+
$query = "DELETE FROM choiceai_recommendation_conf WHERE " . ChoiceAI_Searchcore_Model_Config::WEBSITE_ID . " = :website_id";
|
203 |
+
$binds = array(
|
204 |
+
'website_id' => $websiteId
|
205 |
+
);
|
206 |
+
$write->query($query, $binds);
|
207 |
+
}
|
208 |
+
|
209 |
+
public function getGlobalConfig(Mage_Core_Model_Website $website, $keys =array()) {
|
210 |
+
}
|
211 |
+
}
|
212 |
+
|
213 |
+
?>
|
app/code/local/ChoiceAI/Searchcore/Model/Resource/Config/Collection.php
ADDED
@@ -0,0 +1,21 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @category ChoiceAI
|
5 |
+
* @package ChoiceAI_Searchcore
|
6 |
+
* @copyright Copyright (c) MineWhat
|
7 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
*/
|
9 |
+
class ChoiceAI_Searchcore_Model_Resource_Config_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
|
10 |
+
{
|
11 |
+
/**
|
12 |
+
*/
|
13 |
+
public function _construct()
|
14 |
+
{
|
15 |
+
$this->_init('choiceai_searchcore/config');
|
16 |
+
}
|
17 |
+
|
18 |
+
|
19 |
+
}
|
20 |
+
|
21 |
+
?>
|
app/code/local/ChoiceAI/Searchcore/Model/Resource/Field.php
ADDED
@@ -0,0 +1,146 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @category ChoiceAI
|
5 |
+
* @package ChoiceAI_Searchcore
|
6 |
+
* @copyright Copyright (c) MineWhat
|
7 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
*/
|
9 |
+
class ChoiceAI_Searchcore_Model_Resource_Field extends Mage_Core_Model_Mysql4_Abstract
|
10 |
+
{
|
11 |
+
|
12 |
+
const CAT_LEVEL_1 = "categoryLevel1";
|
13 |
+
|
14 |
+
const CAT_LEVEL_2 = "categoryLevel2";
|
15 |
+
|
16 |
+
const CAT_LEVEL_3 = "categoryLevel3";
|
17 |
+
|
18 |
+
const CAT_LEVEL_4 = "categoryLevel4";
|
19 |
+
|
20 |
+
const CAT_LEVEL_1_NAME = "catlevel1Name";
|
21 |
+
|
22 |
+
const CAT_LEVEL_2_NAME = "catlevel2Name";
|
23 |
+
|
24 |
+
const CAT_LEVEL_3_NAME = "catlevel3Name";
|
25 |
+
|
26 |
+
const CAT_LEVEL_4_NAME = "catlevel4Name";
|
27 |
+
|
28 |
+
const CATEGORY_IDS_NAME = "categoryIds";
|
29 |
+
|
30 |
+
const CATEGORY_IDS = "category_ids";
|
31 |
+
|
32 |
+
const CATEGORY_NAME = "category";
|
33 |
+
|
34 |
+
const AVAILABILITY = 'availability';
|
35 |
+
|
36 |
+
const QTY_ASSOCIATED = "qtyAssociated";
|
37 |
+
|
38 |
+
const AVAILABILITY_ASSOCIATED = "availabilityAssociated";
|
39 |
+
|
40 |
+
const QTY_MANAGE_ASSOCIATED = "manage_stockAssociated";
|
41 |
+
|
42 |
+
const QTY_CONFIG_USE_MANAGE_STOCK = "use_config_manage_stock";
|
43 |
+
|
44 |
+
const QTY_CONFIG_USE_MANAGE_STOCK_ASSOCIATED = "use_config_manage_stockAssociated";
|
45 |
+
|
46 |
+
const QTY = "qty";
|
47 |
+
|
48 |
+
const QTY_MANAGE = "manage_stock";
|
49 |
+
/**
|
50 |
+
* ChoiceAI Field Config table Name
|
51 |
+
*
|
52 |
+
* @var string
|
53 |
+
*/
|
54 |
+
protected $_choiceaiFieldTable;
|
55 |
+
|
56 |
+
/**
|
57 |
+
* @return void
|
58 |
+
*/
|
59 |
+
protected function _construct()
|
60 |
+
{
|
61 |
+
$this->_init('choiceai_searchcore/field', 'id');
|
62 |
+
$this->_choiceaiFieldTable = $this->getTable('choiceai_searchcore/field');
|
63 |
+
}
|
64 |
+
|
65 |
+
public function getTableName() {
|
66 |
+
return $this->_choiceaiFieldTable;
|
67 |
+
}
|
68 |
+
|
69 |
+
public function getFieldByFeatureField($websiteId, $featureField){
|
70 |
+
$adapter = $this->_getReadAdapter();
|
71 |
+
|
72 |
+
$select = $adapter->select()
|
73 |
+
->from($this->_choiceaiFieldTable, ChoiceAI_Searchcore_Model_Field::field_name)
|
74 |
+
->where('`'.ChoiceAI_Searchcore_Model_Field::website_id.'` = ?', (int)$websiteId)
|
75 |
+
->where('`'.ChoiceAI_Searchcore_Model_Field::featured_field.'` = ?', $featureField);
|
76 |
+
|
77 |
+
$result = $adapter->fetchOne($select);
|
78 |
+
if($result == false) {
|
79 |
+
return null;
|
80 |
+
}
|
81 |
+
return $result;
|
82 |
+
}
|
83 |
+
|
84 |
+
public function getDisplayableFields(Mage_Core_Model_Website $website) {
|
85 |
+
$fields = $this->getDisplayableFieldCollection($website);
|
86 |
+
if(count($fields) == 0) {
|
87 |
+
return $this->setDefaultFields($website)
|
88 |
+
->getDisplayableFieldCollection($website);
|
89 |
+
}
|
90 |
+
return $fields;
|
91 |
+
}
|
92 |
+
|
93 |
+
protected function getDisplayableFieldCollection(Mage_Core_Model_Website $website) {
|
94 |
+
return Mage::getModel("choiceai_searchcore/field")
|
95 |
+
->getCollection()
|
96 |
+
->addFieldsDisplayFilter()
|
97 |
+
->addWebsiteFilter($website)
|
98 |
+
->load();
|
99 |
+
}
|
100 |
+
|
101 |
+
public function setDefaultFields(Mage_Core_Model_Website $website) {
|
102 |
+
$_writer = $this->_getWriteAdapter();
|
103 |
+
$_writer->query($this->getDefaultFieldInsertStatement($website));
|
104 |
+
return $this;
|
105 |
+
}
|
106 |
+
|
107 |
+
public function getDefaultFieldInsertStatement(Mage_Core_Model_Website $website) {
|
108 |
+
$websiteId = $website->getWebsiteId();
|
109 |
+
if(is_null($websiteId)) {
|
110 |
+
return "";
|
111 |
+
}
|
112 |
+
$fieldTable = Mage::getResourceModel('choiceai_searchcore/field')->getTableName();
|
113 |
+
return "
|
114 |
+
INSERT INTO `{$fieldTable}` (`website_id`, `field_name`, `datatype`, `autosuggest`, `featured_field`, `multivalued`, `displayed`)
|
115 |
+
VALUES
|
116 |
+
({$websiteId}, 'name', 'text', 1, 'title', 0, 1),
|
117 |
+
({$websiteId}, 'final_price', 'decimal', 0, 'price', 0, 1),
|
118 |
+
({$websiteId}, 'price', 'decimal', 0, NULL, 0, 1),
|
119 |
+
({$websiteId}, 'brand', 'text', 0, 'brand', 0, 1),
|
120 |
+
({$websiteId}, 'color', 'text', 0, 'color', 1, 1),
|
121 |
+
({$websiteId}, 'size', 'text', 0, 'size', 1, 1),
|
122 |
+
({$websiteId}, 'image', 'link', 0, 'imageUrl', 1, 1),
|
123 |
+
({$websiteId}, 'url_path', 'link', 0, 'productUrl', 0, 1),
|
124 |
+
({$websiteId}, 'gender', 'text', 0, 'gender', 0, 1),
|
125 |
+
({$websiteId}, 'description', 'longText', 0, 'description', 0, 1),
|
126 |
+
({$websiteId}, 'catlevel1Name', 'text', 0, 'catlevel1Name', 0, 0),
|
127 |
+
({$websiteId}, 'catlevel2Name', 'text', 0, 'catlevel2Name', 0, 0),
|
128 |
+
({$websiteId}, 'catlevel3Name', 'text', 0, 'catlevel3Name', 0, 0),
|
129 |
+
({$websiteId}, 'catlevel4Name', 'text', 0, 'catlevel4Name', 0, 0),
|
130 |
+
({$websiteId}, 'categoryLevel1', 'text', 0, NULL, 1, 0),
|
131 |
+
({$websiteId}, 'categoryLevel2', 'text', 0, NULL, 1, 0),
|
132 |
+
({$websiteId}, 'categoryLevel3', 'text', 0, NULL, 1, 0),
|
133 |
+
({$websiteId}, 'categoryLevel4', 'text', 0, NULL, 1, 0),
|
134 |
+
({$websiteId}, 'created_at', 'date', 0, NULL, 0, 1),
|
135 |
+
({$websiteId}, 'availability', 'bool', 0, 'availability', 0, 0),
|
136 |
+
({$websiteId}, 'status', 'number', 0, NULL, 0, 0),
|
137 |
+
({$websiteId}, 'visibility', 'number', 0, NULL, 0, 0),
|
138 |
+
({$websiteId}, 'qty', 'number', 0, NULL, 0, 0),
|
139 |
+
({$websiteId}, 'categoryIds', 'longText', 0, NULL, 1, 0),
|
140 |
+
({$websiteId}, 'category', 'text', 0, 'category', 1, 0),
|
141 |
+
({$websiteId}, 'uniqueId', 'longText', 0, NULL, 0, 0),
|
142 |
+
({$websiteId}, 'entity_id', 'longText', 0, NULL, 0, 0);";
|
143 |
+
}
|
144 |
+
}
|
145 |
+
|
146 |
+
?>
|
app/code/local/ChoiceAI/Searchcore/Model/Resource/Field/Collection.php
ADDED
@@ -0,0 +1,66 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @category ChoiceAI
|
5 |
+
* @package ChoiceAI_Searchcore
|
6 |
+
* @copyright Copyright (c) MineWhat
|
7 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
8 |
+
*/
|
9 |
+
class ChoiceAI_Searchcore_Model_Resource_Field_Collection extends Mage_Core_Model_Mysql4_Collection_Abstract
|
10 |
+
{
|
11 |
+
/**
|
12 |
+
*/
|
13 |
+
public function _construct()
|
14 |
+
{
|
15 |
+
$this->_init('choiceai_searchcore/field');
|
16 |
+
}
|
17 |
+
|
18 |
+
/**
|
19 |
+
* Method to add fields to display filter
|
20 |
+
*
|
21 |
+
* @return void
|
22 |
+
*/
|
23 |
+
public function addFieldsDisplayFilter() {
|
24 |
+
$this->addFieldToFilter(ChoiceAI_Searchcore_Model_Field::dislayable,1);
|
25 |
+
return $this;
|
26 |
+
}
|
27 |
+
|
28 |
+
public function addWebsiteFilter(Mage_Core_Model_Website $website) {
|
29 |
+
$this->addFieldToFilter(ChoiceAI_Searchcore_Model_Field::website_id, $website->getWebsiteId());
|
30 |
+
return $this;
|
31 |
+
}
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Method to get field collection as array
|
35 |
+
*
|
36 |
+
* @return array
|
37 |
+
*/
|
38 |
+
public function __asArray() {
|
39 |
+
$fields = array();
|
40 |
+
foreach($this->_items as $item) {
|
41 |
+
$field = array();
|
42 |
+
$field[ChoiceAI_Searchcore_Model_Field::field_name] = $item->getFieldName();
|
43 |
+
$field[ChoiceAI_Searchcore_Model_Field::datatype] = $item->getDatatype();
|
44 |
+
$field[ChoiceAI_Searchcore_Model_Field::autosuggest] = $item->getAutosuggest();
|
45 |
+
$featureField = $item->getFeaturedField();
|
46 |
+
if(isset($featureField)) {
|
47 |
+
$field[ChoiceAI_Searchcore_Model_Field::featured_field] = $featureField;
|
48 |
+
}
|
49 |
+
$fields[] = $field;
|
50 |
+
}
|
51 |
+
return $fields;
|
52 |
+
}
|
53 |
+
|
54 |
+
public function getFeatureFields(Mage_Core_Model_Website $website) {
|
55 |
+
$this->getSelect()->where(ChoiceAI_Searchcore_Model_Field::featured_field. " IS NOT NULL AND ".
|
56 |
+
ChoiceAI_Searchcore_Model_Field::website_id . " = " . $website->getWebsiteId());
|
57 |
+
return $this->load();
|
58 |
+
}
|
59 |
+
|
60 |
+
public function getFields(Mage_Core_Model_Website $website) {
|
61 |
+
$this->getSelect()->where(ChoiceAI_Searchcore_Model_Field::website_id . " = " . $website->getWebsiteId());
|
62 |
+
return $this->load();
|
63 |
+
}
|
64 |
+
}
|
65 |
+
|
66 |
+
?>
|
app/code/local/ChoiceAI/Searchcore/Model/Resource/Product/Collection.php
ADDED
@@ -0,0 +1,110 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @category ChoiceAI
|
4 |
+
* @package ChoiceAI_Searchcore
|
5 |
+
* @copyright Copyright (c) MineWhat
|
6 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
7 |
+
*/
|
8 |
+
class ChoiceAI_Searchcore_Model_Resource_Product_Collection extends
|
9 |
+
Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection{
|
10 |
+
|
11 |
+
protected function _construct()
|
12 |
+
{
|
13 |
+
parent::_construct();
|
14 |
+
}
|
15 |
+
|
16 |
+
public function isEnabledFlat()
|
17 |
+
{
|
18 |
+
return false;
|
19 |
+
}
|
20 |
+
|
21 |
+
/**
|
22 |
+
* Merge colle
|
23 |
+
* @param $collection1
|
24 |
+
* @param $collection2
|
25 |
+
* @return mixed
|
26 |
+
*/
|
27 |
+
public function mergeCollection($collection) {
|
28 |
+
foreach($collection as $product) {
|
29 |
+
if(!array_key_exists($product->getEntityId(), $this->_items)) {
|
30 |
+
$this->addItem($product);
|
31 |
+
}
|
32 |
+
}
|
33 |
+
return $this;
|
34 |
+
}
|
35 |
+
|
36 |
+
/**
|
37 |
+
* sets collection is loaded
|
38 |
+
* @return $this
|
39 |
+
*/
|
40 |
+
public function virtuallyLoad() {
|
41 |
+
$this->_setIsLoaded(true);
|
42 |
+
return $this;
|
43 |
+
}
|
44 |
+
|
45 |
+
public function addIncrementalUploadFiltersToAdd(Mage_Core_Model_Website $website, $fromDate,
|
46 |
+
$toDate, $productIds = array()) {
|
47 |
+
$this->_addBasicFilterToUpload($website);
|
48 |
+
$this->addAttributeToFilter(array(
|
49 |
+
array( 'attribute' => 'updated_at',
|
50 |
+
'from' => $fromDate,
|
51 |
+
'to' => $toDate,
|
52 |
+
'date' => true
|
53 |
+
),
|
54 |
+
array( 'attribute' => 'entity_id',
|
55 |
+
'in' => $productIds
|
56 |
+
)
|
57 |
+
));
|
58 |
+
Mage::helper('choiceai_searchcore')->log(Zend_Log::DEBUG, (string)$this->getSelect());
|
59 |
+
return $this;
|
60 |
+
}
|
61 |
+
|
62 |
+
public function addIncrementalUploadFiltersToDelete(Mage_Core_Model_Website $website, $fromDate, $toDate) {
|
63 |
+
$this->addAttributeToSelect('entity_id');
|
64 |
+
$this->addAttributeToFilter('status', Mage_Catalog_Model_Product_Status::STATUS_DISABLED);
|
65 |
+
$this->addAttributeToFilter(array(
|
66 |
+
array( 'attribute' => 'updated_at',
|
67 |
+
'from' => $fromDate,
|
68 |
+
'to' => $toDate,
|
69 |
+
'date' => true
|
70 |
+
)
|
71 |
+
));
|
72 |
+
return $this;
|
73 |
+
|
74 |
+
}
|
75 |
+
|
76 |
+
protected function _addBasicFilterToUpload(Mage_Core_Model_Website $website)
|
77 |
+
{
|
78 |
+
$adapter = Mage::getSingleton("core/resource");
|
79 |
+
$visiblityCondition = array('in' => array(2,3,4));
|
80 |
+
$_catalogInventoryTable = method_exists($adapter, 'getTableName')
|
81 |
+
? $adapter->getTableName('cataloginventory_stock_item') : 'cataloginventory_stock_item';
|
82 |
+
$stockfields = array("qty" => "qty", "manage_stock" => "manage_stock",
|
83 |
+
"use_config_manage_stock" => "use_config_manage_stock", "is_in_stock" => "is_in_stock");
|
84 |
+
|
85 |
+
$this
|
86 |
+
->addWebsiteFilter($website->getWebsiteId())
|
87 |
+
->addAttributeToSelect('*')
|
88 |
+
->joinTable($_catalogInventoryTable, 'product_id=entity_id', $stockfields, null, 'left')
|
89 |
+
->addAttributeToFilter('status',1)
|
90 |
+
->addCategoryIds()
|
91 |
+
->addAttributeToFilter('visibility',$visiblityCondition)
|
92 |
+
->addPriceData(Mage_Customer_Model_Group::NOT_LOGGED_IN_ID, $website->getWebsiteId());
|
93 |
+
|
94 |
+
Mage::getSingleton('catalog/product_status')->addVisibleFilterToCollection($this);
|
95 |
+
#Mage::getSingleton('catalog/product_visibility')->addVisibleInSiteFilterToCollection($this);
|
96 |
+
return $this;
|
97 |
+
}
|
98 |
+
|
99 |
+
|
100 |
+
/**
|
101 |
+
* method to get the catalog collection
|
102 |
+
*
|
103 |
+
*/
|
104 |
+
public function addFullUploadFilters(Mage_Core_Model_Website $website) {
|
105 |
+
$this->_addBasicFilterToUpload($website);
|
106 |
+
return $this;
|
107 |
+
}
|
108 |
+
}
|
109 |
+
|
110 |
+
?>
|
app/code/local/ChoiceAI/Searchcore/etc/config.xml
ADDED
@@ -0,0 +1,133 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<config>
|
2 |
+
<modules>
|
3 |
+
<ChoiceAI_Searchcore>
|
4 |
+
<version>0.0.9</version>
|
5 |
+
</ChoiceAI_Searchcore>
|
6 |
+
</modules>
|
7 |
+
<global>
|
8 |
+
<resources>
|
9 |
+
<choiceai_searchcore_setup>
|
10 |
+
<setup>
|
11 |
+
<module>ChoiceAI_Searchcore</module>
|
12 |
+
</setup>
|
13 |
+
</choiceai_searchcore_setup>
|
14 |
+
</resources>
|
15 |
+
<helpers>
|
16 |
+
<choiceai_searchcore>
|
17 |
+
<class>ChoiceAI_Searchcore_Helper</class>
|
18 |
+
</choiceai_searchcore>
|
19 |
+
</helpers>
|
20 |
+
<models>
|
21 |
+
<choiceai_searchcore>
|
22 |
+
<class>ChoiceAI_Searchcore_Model</class>
|
23 |
+
<resourceModel>choiceai_searchcore_resource</resourceModel>
|
24 |
+
</choiceai_searchcore>
|
25 |
+
<choiceai_searchcore_resource>
|
26 |
+
<class>ChoiceAI_Searchcore_Model_Resource</class>
|
27 |
+
<entities>
|
28 |
+
<config>
|
29 |
+
<table>choiceai_recommendation_conf</table>
|
30 |
+
</config>
|
31 |
+
<field>
|
32 |
+
<table>choiceai_field_conf</table>
|
33 |
+
</field>
|
34 |
+
<sync>
|
35 |
+
<table>choiceai_product_sync</table>
|
36 |
+
</sync>
|
37 |
+
</entities>
|
38 |
+
</choiceai_searchcore_resource>
|
39 |
+
</models>
|
40 |
+
<blocks>
|
41 |
+
<choiceai_searchcore>
|
42 |
+
<class>ChoiceAI_Searchcore_Block</class>
|
43 |
+
</choiceai_searchcore>
|
44 |
+
</blocks>
|
45 |
+
<events>
|
46 |
+
<controller_action_predispatch_choiceai_searchcore>
|
47 |
+
<observers>
|
48 |
+
<choiceai_searchcore_auth>
|
49 |
+
<type>singleton</type>
|
50 |
+
<class>choiceai_searchcore/auth</class>
|
51 |
+
<method>authorize</method>
|
52 |
+
</choiceai_searchcore_auth>
|
53 |
+
</observers>
|
54 |
+
</controller_action_predispatch_choiceai_searchcore>
|
55 |
+
<checkout_cart_add_product_complete>
|
56 |
+
<observers>
|
57 |
+
<choiceai_searchcore_cart_tracker>
|
58 |
+
<type>singleton</type>
|
59 |
+
<class>choiceai_searchcore/observer</class>
|
60 |
+
<method>trackAddToCart</method>
|
61 |
+
</choiceai_searchcore_cart_tracker>
|
62 |
+
</observers>
|
63 |
+
</checkout_cart_add_product_complete>
|
64 |
+
<sales_order_payment_place_end>
|
65 |
+
<observers>
|
66 |
+
<choiceai_searchcore_order_tracker>
|
67 |
+
<type>singleton</type>
|
68 |
+
<class>choiceai_searchcore/observer</class>
|
69 |
+
<method>trackOrder</method>
|
70 |
+
</choiceai_searchcore_order_tracker>
|
71 |
+
</observers>
|
72 |
+
</sales_order_payment_place_end>
|
73 |
+
<catalog_product_delete_before>
|
74 |
+
<observers>
|
75 |
+
<choiceai_searchcore_order_tracker>
|
76 |
+
<type>singleton</type>
|
77 |
+
<class>choiceai_searchcore/observer</class>
|
78 |
+
<method>trackDelete</method>
|
79 |
+
</choiceai_searchcore_order_tracker>
|
80 |
+
</observers>
|
81 |
+
</catalog_product_delete_before>
|
82 |
+
<catalog_product_delete_commit_after>
|
83 |
+
<observers>
|
84 |
+
<choiceai_searchcore_order_tracker>
|
85 |
+
<type>singleton</type>
|
86 |
+
<class>choiceai_searchcore/observer</class>
|
87 |
+
<method>trackDelete</method>
|
88 |
+
</choiceai_searchcore_order_tracker>
|
89 |
+
</observers>
|
90 |
+
</catalog_product_delete_commit_after>
|
91 |
+
<cataloginventory_stock_item_save_commit_after>
|
92 |
+
<observers>
|
93 |
+
<choiceai_searchcore_catalog_inventory_save>
|
94 |
+
<type>singleton</type>
|
95 |
+
<class>choiceai_searchcore/observer</class>
|
96 |
+
<method>catalogInventorySave</method>
|
97 |
+
</choiceai_searchcore_catalog_inventory_save>
|
98 |
+
</observers>
|
99 |
+
</cataloginventory_stock_item_save_commit_after>
|
100 |
+
<sales_order_item_cancel>
|
101 |
+
<observers>
|
102 |
+
<choiceai_searchcore_order_cancel>
|
103 |
+
<type>singleton</type>
|
104 |
+
<class>choiceai_searchcore/observer</class>
|
105 |
+
<method>catalogInventorySave</method>
|
106 |
+
</choiceai_searchcore_order_cancel>
|
107 |
+
</observers>
|
108 |
+
</sales_order_item_cancel>
|
109 |
+
</events>
|
110 |
+
</global>
|
111 |
+
<default>
|
112 |
+
<choiceai>
|
113 |
+
<general>
|
114 |
+
<price>final_price</price>
|
115 |
+
<productUrl>url_path</productUrl>
|
116 |
+
<max_feed_lock_feed>2</max_feed_lock_feed>
|
117 |
+
<include_out_of_stock>true</include_out_of_stock>
|
118 |
+
<include_child_product>true</include_child_product>
|
119 |
+
<include_taxonomy_nodes>false</include_taxonomy_nodes>
|
120 |
+
<include_taxonomy_mapping>false</include_taxonomy_mapping>
|
121 |
+
<include_out_of_stock_from_non_cache>false</include_out_of_stock_from_non_cache>
|
122 |
+
<include_only_enabled_child_product>true</include_only_enabled_child_product>
|
123 |
+
<include_out_of_stock_child_product>false</include_out_of_stock_child_product>
|
124 |
+
<field_conf>{}</field_conf>
|
125 |
+
<exclude_category>[]</exclude_category>
|
126 |
+
<tracker_url>https://tracker.choiceaiapi.com/</tracker_url>
|
127 |
+
<platform_url>https://accounts.choiceaiapi.com/admin/</platform_url>
|
128 |
+
<service_url>https://starwreck.choiceaiapi.com/</service_url>
|
129 |
+
<feed_url>https://feed.choiceaiapi.com/</feed_url>
|
130 |
+
</general>
|
131 |
+
</choiceai>
|
132 |
+
</default>
|
133 |
+
</config>
|
app/code/local/ChoiceAI/Searchcore/sql/choiceai_searchcore_setup/mysql4-install-1.0.0.php
ADDED
@@ -0,0 +1,91 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
|
4 |
+
$installer = $this;
|
5 |
+
/* @var $installer Mage_Searchcore_Model_Resource_Setup */
|
6 |
+
|
7 |
+
$installer->startSetup();
|
8 |
+
|
9 |
+
$configTable = $installer->getTable('choiceai_recommendation_conf');
|
10 |
+
$fieldTable = $installer->getTable('choiceai_field_conf');
|
11 |
+
$productSyncTable = $installer->getTable('choiceai_product_sync');
|
12 |
+
|
13 |
+
$installer->run("
|
14 |
+
|
15 |
+
CREATE TABLE IF NOT EXISTS `{$fieldTable}` (
|
16 |
+
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
17 |
+
`website_id` tinyint(5) unsigned NOT NULL,
|
18 |
+
`field_name` varchar(100) NOT NULL DEFAULT '',
|
19 |
+
`datatype` varchar(20) NOT NULL DEFAULT '',
|
20 |
+
`autosuggest` tinyint(1) NOT NULL DEFAULT '0',
|
21 |
+
`featured_field` varchar(100) DEFAULT NULL,
|
22 |
+
`multivalued` tinyint(1) NOT NULL DEFAULT '0',
|
23 |
+
`displayed` tinyint(1) NOT NULL DEFAULT '1',
|
24 |
+
PRIMARY KEY (`id`),
|
25 |
+
UNIQUE KEY `website_id` (`website_id`,`field_name`)
|
26 |
+
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
27 |
+
|
28 |
+
CREATE TABLE IF NOT EXISTS `{$configTable}` (
|
29 |
+
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
30 |
+
`website_id` smallint(5) unsigned NOT NULL,
|
31 |
+
`key` varchar(50) NOT NULL DEFAULT '',
|
32 |
+
`value` varchar(50) DEFAULT NULL,
|
33 |
+
PRIMARY KEY (`id`)
|
34 |
+
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
35 |
+
|
36 |
+
CREATE TABLE IF NOT EXISTS `{$productSyncTable}` (
|
37 |
+
`id` int(11) unsigned NOT NULL AUTO_INCREMENT,
|
38 |
+
`product_id` int(10) unsigned NOT NULL,
|
39 |
+
`website_id` smallint(5) unsigned NOT NULL,
|
40 |
+
`synced` tinyint(1) NOT NULL DEFAULT '0',
|
41 |
+
`updated_time` datetime DEFAULT NULL,
|
42 |
+
`sync_time` datetime DEFAULT NULL,
|
43 |
+
`operation` enum('ADD','DELETE') NOT NULL DEFAULT 'ADD',
|
44 |
+
PRIMARY KEY (`id`),
|
45 |
+
UNIQUE KEY `product_id` (`product_id`,`website_id`)
|
46 |
+
) ENGINE=InnoDB DEFAULT CHARSET=latin1;
|
47 |
+
");
|
48 |
+
|
49 |
+
$websiteCollection = Mage::getModel('core/website')->getCollection()->load();
|
50 |
+
foreach($websiteCollection as $website) {
|
51 |
+
$websiteId = $website->getWebsiteId();
|
52 |
+
if(is_null($websiteId)) {
|
53 |
+
continue;
|
54 |
+
}
|
55 |
+
$fieldTable = Mage::getResourceModel('choiceai_searchcore/field')->getTableName();
|
56 |
+
$insertQuery = "
|
57 |
+
INSERT INTO `{$fieldTable}` (`website_id`, `field_name`, `datatype`, `autosuggest`, `featured_field`, `multivalued`, `displayed`)
|
58 |
+
VALUES
|
59 |
+
({$websiteId}, 'name', 'text', 1, 'title', 0, 1),
|
60 |
+
({$websiteId}, 'final_price', 'decimal', 0, 'price', 0, 1),
|
61 |
+
({$websiteId}, 'price', 'decimal', 0, NULL, 0, 1),".
|
62 |
+
(Mage::helper('choiceai_searchcore/feedhelper')->isAttributePresent('brand')?"({$websiteId}, 'brand', 'text', 0, 'brand', 0, 1),":"").
|
63 |
+
(Mage::helper('choiceai_searchcore/feedhelper')->isAttributePresent('color')?"({$websiteId}, 'color', 'text', 0, 'color', 1, 1),":"").
|
64 |
+
(Mage::helper('choiceai_searchcore/feedhelper')->isAttributePresent('size')?"({$websiteId}, 'size', 'text', 0, 'size', 1, 1),":"").
|
65 |
+
"({$websiteId}, 'image', 'link', 0, 'imageUrl', 1, 1),
|
66 |
+
({$websiteId}, 'url_path', 'link', 0, 'productUrl', 0, 1),
|
67 |
+
({$websiteId}, 'gender', 'text', 0, 'gender', 0, 1),
|
68 |
+
({$websiteId}, 'description', 'longText', 0, 'description', 0, 1),
|
69 |
+
({$websiteId}, 'catlevel1Name', 'text', 0, 'catlevel1Name', 0, 0),
|
70 |
+
({$websiteId}, 'catlevel2Name', 'text', 0, 'catlevel2Name', 0, 0),
|
71 |
+
({$websiteId}, 'catlevel3Name', 'text', 0, 'catlevel3Name', 0, 0),
|
72 |
+
({$websiteId}, 'catlevel4Name', 'text', 0, 'catlevel4Name', 0, 0),
|
73 |
+
({$websiteId}, 'categoryLevel1', 'text', 0, NULL, 1, 0),
|
74 |
+
({$websiteId}, 'categoryLevel2', 'text', 0, NULL, 1, 0),
|
75 |
+
({$websiteId}, 'categoryLevel3', 'text', 0, NULL, 1, 0),
|
76 |
+
({$websiteId}, 'categoryLevel4', 'text', 0, NULL, 1, 0),
|
77 |
+
({$websiteId}, 'created_at', 'date', 0, NULL, 0, 1),
|
78 |
+
({$websiteId}, 'availability', 'bool', 0, 'availability', 0, 0),
|
79 |
+
({$websiteId}, 'status', 'number', 0, NULL, 0, 0),
|
80 |
+
({$websiteId}, 'visibility', 'number', 0, NULL, 0, 0),
|
81 |
+
({$websiteId}, 'qty', 'number', 0, NULL, 0, 0),
|
82 |
+
({$websiteId}, 'categoryIds', 'longText', 0, NULL, 1, 0),
|
83 |
+
({$websiteId}, 'category', 'text', 0, 'category', 1, 0),
|
84 |
+
({$websiteId}, 'uniqueId', 'longText', 0, NULL, 0, 0),
|
85 |
+
({$websiteId}, 'type_id', 'longText', 0, NULL, 0, 0),
|
86 |
+
({$websiteId}, 'entity_id', 'longText', 0, NULL, 0, 0)
|
87 |
+
ON DUPLICATE KEY UPDATE `field_name`=`field_name`;";
|
88 |
+
$installer->run($insertQuery);
|
89 |
+
}
|
90 |
+
$installer->endSetup();
|
91 |
+
?>
|
app/code/local/ChoiceAI/Searchcore/sql/choiceai_searchcore_setup/upgrade-1.0.21-1.0.22.php
ADDED
@@ -0,0 +1,46 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
$installer = $this;
|
3 |
+
/* @var $installer Mage_Searchcore_Model_Resource_Setup */
|
4 |
+
|
5 |
+
$installer->startSetup();
|
6 |
+
$fieldTable = $installer->getTable('choiceai_field_conf');
|
7 |
+
$configTable = $installer->getTable('choiceai_recommendation_conf');
|
8 |
+
try {
|
9 |
+
$installer->run("ALTER TABLE `{$configTable}` CHANGE `key` `choiceai_key` VARCHAR(50)");
|
10 |
+
} catch (Exception $e) {
|
11 |
+
//ignore the exceptions
|
12 |
+
}
|
13 |
+
|
14 |
+
$websiteCollection = Mage::getModel('core/website')->getCollection()->load();
|
15 |
+
foreach($websiteCollection as $website) {
|
16 |
+
$websiteId = $website->getWebsiteId();
|
17 |
+
if (is_null($websiteId)) {
|
18 |
+
continue;
|
19 |
+
}
|
20 |
+
$fieldTable = Mage::getResourceModel('choiceai_searchcore/field')->getTableName();
|
21 |
+
$insertQuery = "
|
22 |
+
INSERT INTO `{$fieldTable}` (`website_id`, `field_name`, `datatype`, `autosuggest`, `featured_field`, `multivalued`, `displayed`)
|
23 |
+
VALUES
|
24 |
+
({$websiteId}, '" . ChoiceAI_Searchcore_Model_Resource_Field::QTY_MANAGE_ASSOCIATED . "',
|
25 |
+
'" .ChoiceAI_Searchcore_Helper_Constants::CHOICEAI_DATATYPE_NUMBER . "', 0, NULL, 1, 0),
|
26 |
+
({$websiteId}, '" .ChoiceAI_Searchcore_Model_Resource_Field::QTY_ASSOCIATED . "',
|
27 |
+
'" .ChoiceAI_Searchcore_Helper_Constants::CHOICEAI_DATATYPE_NUMBER . "', 0, NULL, 1, 0),
|
28 |
+
({$websiteId}, '" .ChoiceAI_Searchcore_Model_Resource_Field::QTY_CONFIG_USE_MANAGE_STOCK_ASSOCIATED. "',
|
29 |
+
'" .ChoiceAI_Searchcore_Helper_Constants::CHOICEAI_DATATYPE_NUMBER . "', 0, NULL, 1, 0),
|
30 |
+
({$websiteId}, 'statusAssociated',
|
31 |
+
'" .ChoiceAI_Searchcore_Helper_Constants::CHOICEAI_DATATYPE_NUMBER . "', 0, NULL, 1, 0),
|
32 |
+
({$websiteId}, '" .ChoiceAI_Searchcore_Model_Resource_Field::AVAILABILITY_ASSOCIATED . "',
|
33 |
+
'" .ChoiceAI_Searchcore_Helper_Constants::CHOICEAI_DATATYPE_BOOL . "', 0, NULL, 1, 0),
|
34 |
+
({$websiteId}, '" .ChoiceAI_Searchcore_Model_Resource_Field::QTY_MANAGE . "',
|
35 |
+
'" .ChoiceAI_Searchcore_Helper_Constants::CHOICEAI_DATATYPE_NUMBER . "', 0, NULL, 0, 0),
|
36 |
+
({$websiteId}, '" .ChoiceAI_Searchcore_Model_Resource_Field::QTY_CONFIG_USE_MANAGE_STOCK . "',
|
37 |
+
'" .ChoiceAI_Searchcore_Helper_Constants::CHOICEAI_DATATYPE_NUMBER . "', 0, NULL, 0, 0),
|
38 |
+
({$websiteId}, '" .ChoiceAI_Searchcore_Model_Resource_Field::QTY . "',
|
39 |
+
'" .ChoiceAI_Searchcore_Helper_Constants::CHOICEAI_DATATYPE_NUMBER . "', 0, NULL, 0, 0),
|
40 |
+
({$websiteId}, 'type_id',
|
41 |
+
'" .ChoiceAI_Searchcore_Helper_Constants::CHOICEAI_DATATYPE_LONGTEXT . "', 0, NULL, 0, 1)
|
42 |
+
ON DUPLICATE KEY UPDATE `field_name`=`field_name`;";
|
43 |
+
$installer->run($insertQuery);
|
44 |
+
}
|
45 |
+
|
46 |
+
?>
|
app/design/frontend/base/default/template/choiceai/personalisation/base/script.phtml
CHANGED
@@ -34,5 +34,6 @@ foreach ($cart->getAllVisibleItems() as $item) {
|
|
34 |
<script type="text/javascript">
|
35 |
//<![CDATA[
|
36 |
window.CAI_CART_ITEMS = <?php echo json_encode($cart_items); ?>;
|
|
|
37 |
//]]>
|
38 |
</script>
|
34 |
<script type="text/javascript">
|
35 |
//<![CDATA[
|
36 |
window.CAI_CART_ITEMS = <?php echo json_encode($cart_items); ?>;
|
37 |
+
window.CAI_MAGENTO_ADDTOCART_FORM_KEY = '<?php echo Mage::getSingleton('core/session')->getFormKey()?>';
|
38 |
//]]>
|
39 |
</script>
|
app/design/frontend/base/default/template/choiceai/personalisation/event/checkout/onepage/success.phtml
DELETED
@@ -1,21 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @category ChoiceAI
|
4 |
-
* @package ChoiceAI_Personalisation
|
5 |
-
* @copyright Copyright (c) MineWhat
|
6 |
-
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
7 |
-
*/
|
8 |
-
?>
|
9 |
-
<?php if (($orderInfo = $this->getOrderInfo())) { ?>
|
10 |
-
<script type="text/javascript">
|
11 |
-
//<![CDATA[
|
12 |
-
var _caiapi = _caiapi || [];
|
13 |
-
var products = [];
|
14 |
-
<?php foreach ($orderInfo['items'] as $product) { ?>
|
15 |
-
products.push({pid: '<?php echo $product["id"] ?>', qty: '<?php echo intval($product["qty"]) ?>', sku: '<?php echo $product["sku"] ?>', price: '<?php echo $product["price"] ?>', parent_pid: '<?php echo $product["parentId"] ?>', bundle: '<?php echo json_encode($product["bundle"]) ?>'});
|
16 |
-
<?php } ?>
|
17 |
-
_caiapi.push(['trackEvent', 'buy', {products: products, order: {order_number: '<?php echo $orderInfo["orderId"] ?>', payment: '<?php echo $orderInfo["paymentMethod"] ?>', created_at: '<?php echo $orderInfo["createdAt"] ?>', email: '<?php echo $orderInfo["email"] ?>'}, platform: 'magento', currency: '<?php echo $orderInfo["currency"] ?>'}]);
|
18 |
-
|
19 |
-
//]]>
|
20 |
-
</script>
|
21 |
-
<?php } ?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app/design/frontend/default/default/template/choiceai/personalisation/base/script.phtml
CHANGED
@@ -34,5 +34,10 @@ foreach ($cart->getAllVisibleItems() as $item) {
|
|
34 |
<script type="text/javascript">
|
35 |
//<![CDATA[
|
36 |
window.CAI_CART_ITEMS = <?php echo json_encode($cart_items); ?>;
|
|
|
|
|
|
|
|
|
|
|
37 |
//]]>
|
38 |
</script>
|
34 |
<script type="text/javascript">
|
35 |
//<![CDATA[
|
36 |
window.CAI_CART_ITEMS = <?php echo json_encode($cart_items); ?>;
|
37 |
+
window.cai_magento_addtocart = function(id, selected_variant_params, qty) {
|
38 |
+
var form_key = '<?php echo Mage::getSingleton('core/session')->getFormKey()?>';
|
39 |
+
var url = '<?php echo Mage::getUrl('checkout/cart/add');?>'+'product/'+id+'/qty/'+qty+'/form_key/'+form_key;
|
40 |
+
window.location.assign(url);
|
41 |
+
}
|
42 |
//]]>
|
43 |
</script>
|
app/design/frontend/default/default/template/choiceai/personalisation/event/catalog/product/view.phtml
DELETED
@@ -1,61 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @category ChoiceAI
|
4 |
-
* @package ChoiceAI_Personalisation
|
5 |
-
* @copyright Copyright (c) MineWhat
|
6 |
-
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
7 |
-
*/
|
8 |
-
?>
|
9 |
-
<?php $_product = $this->getCurrentProduct() ?>
|
10 |
-
<?php if ($_product) { ?>
|
11 |
-
<?php
|
12 |
-
$_associated_products = $this->getAssociatedProducts($_product);
|
13 |
-
$associated_ids = array();
|
14 |
-
|
15 |
-
$mwdata = array();
|
16 |
-
$mwdata['product'] = array();
|
17 |
-
$mwdata['associated_products'] = array();
|
18 |
-
|
19 |
-
$mwdata['product']['id'] = $_product->getId();
|
20 |
-
$mwdata['product']['sku'] = $_product->getSku();
|
21 |
-
|
22 |
-
$categories = $_product->getCategoryCollection()->addAttributeToSelect('name');
|
23 |
-
|
24 |
-
$mwdata['product']['cat'] = array();
|
25 |
-
foreach($categories as $category) {
|
26 |
-
$mwdata['product']['cat'][] = $category->getName();
|
27 |
-
}
|
28 |
-
|
29 |
-
$mwdata['product']['price'] = $_product->getPrice();
|
30 |
-
|
31 |
-
foreach($_associated_products as $simple_product) {
|
32 |
-
$product_info = array();
|
33 |
-
$associated_ids[] = $simple_product->getId();
|
34 |
-
$product_info['id'] = $simple_product->getId();
|
35 |
-
$product_info['sku'] = $simple_product->getSku();
|
36 |
-
$product_info['price'] = $simple_product->getPrice();
|
37 |
-
$mwdata['associated_products'][] = $product_info;
|
38 |
-
}
|
39 |
-
|
40 |
-
?>
|
41 |
-
<script type="text/choiceai_data">
|
42 |
-
//<![CDATA[
|
43 |
-
|
44 |
-
<?php
|
45 |
-
try {
|
46 |
-
echo json_encode($mwdata);
|
47 |
-
} catch(Exception $exception) {
|
48 |
-
|
49 |
-
}
|
50 |
-
?>
|
51 |
-
|
52 |
-
//]]>
|
53 |
-
</script>
|
54 |
-
|
55 |
-
<script type="text/javascript">
|
56 |
-
//<![CDATA[
|
57 |
-
var _caiapi = _caiapi || [];
|
58 |
-
_caiapi.push(['trackEvent', 'product', {pid: '<?php echo $_product->getId() ?>', associated_ids: '<?php echo json_encode($associated_ids) ?>'}]);
|
59 |
-
//]]>
|
60 |
-
</script>
|
61 |
-
<?php } ?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app/design/frontend/default/default/template/choiceai/personalisation/event/checkout/cart/index.phtml
DELETED
@@ -1,17 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @category ChoiceAI
|
4 |
-
* @package ChoiceAI_Personalisation
|
5 |
-
* @copyright Copyright (c) MineWhat
|
6 |
-
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
7 |
-
*/
|
8 |
-
?>
|
9 |
-
<?php $_product = $this->getProductToShoppingCart() ?>
|
10 |
-
<?php if ($_product && $_product["id"]) { ?>
|
11 |
-
<script type="text/javascript">
|
12 |
-
//<![CDATA[
|
13 |
-
var _caiapi = _caiapi || [];
|
14 |
-
_caiapi.push(['trackEvent', 'addtocart', {pid: '<?php echo $_product["id"] ?>', sku: '<?php echo $_product["sku"] ?>', parent_pid: '<?php echo $_product["parentId"] ?>', qty: '<?php echo $_product["qty"] ?>', bundle: '<?php echo json_encode($_product["bundle"]) ?>'}]);
|
15 |
-
//]]>
|
16 |
-
</script>
|
17 |
-
<?php } ?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app/design/frontend/default/default/template/choiceai/personalisation/event/checkout/onepage/success.phtml
DELETED
@@ -1,20 +0,0 @@
|
|
1 |
-
<?php
|
2 |
-
/**
|
3 |
-
* @category ChoiceAI
|
4 |
-
* @package ChoiceAI_Personalisation
|
5 |
-
* @copyright Copyright (c) MineWhat
|
6 |
-
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
7 |
-
*/
|
8 |
-
?>
|
9 |
-
<?php if (($orderInfo = $this->getOrderInfo())) { ?>
|
10 |
-
<script type="text/javascript">
|
11 |
-
//<![CDATA[
|
12 |
-
var _caiapi = _caiapi || [];
|
13 |
-
var products = [];
|
14 |
-
<?php foreach ($orderInfo['items'] as $product) { ?>
|
15 |
-
products.push({pid: '<?php echo $product["id"] ?>', qty: '<?php echo intval($product["qty"]) ?>', sku: '<?php echo $product["sku"] ?>', price: '<?php echo $product["price"] ?>', parent_pid: '<?php echo $product["parentId"] ?>', bundle: '<?php echo json_encode($product["bundle"]) ?>'});
|
16 |
-
<?php } ?>
|
17 |
-
_caiapi.push(['trackEvent', 'buy', {products: products, order: {order_number: '<?php echo $orderInfo["orderId"] ?>', payment: '<?php echo $orderInfo["paymentMethod"] ?>', created_at: '<?php echo $orderInfo["createdAt"] ?>', email: '<?php echo $orderInfo["email"] ?>'}, platform: 'magento', currency: '<?php echo $orderInfo["currency"] ?>'}]);
|
18 |
-
//]]>
|
19 |
-
</script>
|
20 |
-
<?php } ?>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
app/etc/modules/ChoiceAI_Personalisation.xml
CHANGED
@@ -6,5 +6,13 @@
|
|
6 |
<active>true</active>
|
7 |
<codePool>community</codePool>
|
8 |
</ChoiceAI_Personalisation>
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
9 |
</modules>
|
10 |
</config>
|
6 |
<active>true</active>
|
7 |
<codePool>community</codePool>
|
8 |
</ChoiceAI_Personalisation>
|
9 |
+
<ChoiceAI_Searchcore>
|
10 |
+
<active>true</active>
|
11 |
+
<codePool>local</codePool>
|
12 |
+
</ChoiceAI_Searchcore>
|
13 |
+
<ChoiceAI_Search>
|
14 |
+
<active>true</active>
|
15 |
+
<codePool>local</codePool>
|
16 |
+
</ChoiceAI_Search>
|
17 |
</modules>
|
18 |
</config>
|
lib/ChoiceAI/Client.php
ADDED
@@ -0,0 +1,304 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
/**
|
3 |
+
* @copyright Copyright (c) MineWhat
|
4 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
5 |
+
*/
|
6 |
+
|
7 |
+
include("Service.php");
|
8 |
+
class ChoiceAI_Client {
|
9 |
+
/**
|
10 |
+
* Default ChoiceAIsearch ruleset
|
11 |
+
*/
|
12 |
+
const DEFAULT_RULESET = 'search';
|
13 |
+
|
14 |
+
/**
|
15 |
+
* Default transport
|
16 |
+
*
|
17 |
+
* @var string
|
18 |
+
*/
|
19 |
+
const DEFAULT_TRANSPORT = 'https';
|
20 |
+
|
21 |
+
protected $params = array(
|
22 |
+
'ruleset' => self::DEFAULT_RULESET,
|
23 |
+
'multiSelectFacet' => false,
|
24 |
+
'filter' => array(),
|
25 |
+
'rangeFilter' =>array(),
|
26 |
+
'cond' => array(),
|
27 |
+
'query' => '',
|
28 |
+
'category-id' => ''
|
29 |
+
);
|
30 |
+
|
31 |
+
protected $address = '';
|
32 |
+
|
33 |
+
/**
|
34 |
+
* Number of seconds after a timeout occurs for every request
|
35 |
+
* If using indexing of file large value necessary.
|
36 |
+
*/
|
37 |
+
const TIMEOUT = 300;
|
38 |
+
|
39 |
+
/**
|
40 |
+
* Config with defaults
|
41 |
+
*
|
42 |
+
* @var array
|
43 |
+
*/
|
44 |
+
protected $_config = array(
|
45 |
+
'ruleset' => self::DEFAULT_RULESET,
|
46 |
+
'transport' => self::DEFAULT_TRANSPORT,
|
47 |
+
'timeout' => self::TIMEOUT,
|
48 |
+
'headers' => array()
|
49 |
+
);
|
50 |
+
|
51 |
+
|
52 |
+
|
53 |
+
/**
|
54 |
+
* Creates a new ChoiceAI client
|
55 |
+
*
|
56 |
+
* @param array $config OPTIONAL Additional config options
|
57 |
+
*/
|
58 |
+
public function __construct(array $config = array()) {
|
59 |
+
$this->setConfig($config);
|
60 |
+
$this->address = $this->_config['transport'].'://datav3.choice.ai/widget/debug/personalisation/products/';
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Sets specific config values (updates and keeps default values)
|
65 |
+
*
|
66 |
+
* @param array $config Params
|
67 |
+
*/
|
68 |
+
public function setConfig(array $config) {
|
69 |
+
foreach ($config as $key => $value) {
|
70 |
+
$this->_config[$key] = $value;
|
71 |
+
}
|
72 |
+
|
73 |
+
return $this;
|
74 |
+
}
|
75 |
+
|
76 |
+
/**
|
77 |
+
* Returns a specific config key or the whole
|
78 |
+
* config array if not set
|
79 |
+
*
|
80 |
+
* @param string $key Config key
|
81 |
+
* @return array|string Config value
|
82 |
+
*/
|
83 |
+
public function getConfig($key = '') {
|
84 |
+
if (empty($key)) {
|
85 |
+
return $this->_config;
|
86 |
+
}
|
87 |
+
|
88 |
+
if (!array_key_exists($key, $this->_config)) {
|
89 |
+
throw new Exception('Config key is not set: ' . $key);
|
90 |
+
}
|
91 |
+
|
92 |
+
return $this->_config[$key];
|
93 |
+
}
|
94 |
+
|
95 |
+
/**
|
96 |
+
* Sets / overwrites a specific config value
|
97 |
+
*
|
98 |
+
* @param string $key Key to set
|
99 |
+
* @param mixed $value Value
|
100 |
+
* @return ChoiceAI_Client Client object
|
101 |
+
*/
|
102 |
+
public function setConfigValue($key, $value) {
|
103 |
+
return $this->setConfig(array($key => $value));
|
104 |
+
}
|
105 |
+
|
106 |
+
/**
|
107 |
+
* Returns connection port of this client
|
108 |
+
*
|
109 |
+
* @return int Connection port
|
110 |
+
*/
|
111 |
+
public function getContext() {
|
112 |
+
return $this->getConfig('context');
|
113 |
+
}
|
114 |
+
|
115 |
+
/**
|
116 |
+
* Returns transport type to user
|
117 |
+
*
|
118 |
+
* @return string Transport type
|
119 |
+
*/
|
120 |
+
public function getTransport() {
|
121 |
+
return $this->getConfig('transport');
|
122 |
+
}
|
123 |
+
|
124 |
+
|
125 |
+
/**
|
126 |
+
* sets the attribute filter
|
127 |
+
* @param mixed $filter array
|
128 |
+
* @return ChoiceAI_Client Client object
|
129 |
+
*/
|
130 |
+
public function setFilters($filter =array()){
|
131 |
+
if(isset($filter) && is_array($filter)){
|
132 |
+
$this->params['filter'] = $filter;
|
133 |
+
}
|
134 |
+
return $this;
|
135 |
+
}
|
136 |
+
|
137 |
+
/**
|
138 |
+
* sets the range filter
|
139 |
+
* @param mixed $rangeFilter array
|
140 |
+
* @return ChoiceAI_Client Client object
|
141 |
+
*/
|
142 |
+
public function setRangeFilters($rangeFilter =array()){
|
143 |
+
if(isset($rangeFilter) && is_array($rangeFilter)){
|
144 |
+
$this->params['rangeFilter'] = $rangeFilter;
|
145 |
+
}
|
146 |
+
return $this;
|
147 |
+
}
|
148 |
+
|
149 |
+
/**
|
150 |
+
* sets the offset
|
151 |
+
* @param mixed $pg integer
|
152 |
+
* @return ChoiceAI_Client Client object
|
153 |
+
*/
|
154 |
+
public function setOffset($pg = 0){
|
155 |
+
if(isset($pg)){
|
156 |
+
$this->params['start'] = $pg;
|
157 |
+
}else{
|
158 |
+
$this->params['start'] = 10;
|
159 |
+
}
|
160 |
+
return $this;
|
161 |
+
}
|
162 |
+
|
163 |
+
/**
|
164 |
+
* sets the limit
|
165 |
+
* @param mixed $limit integer
|
166 |
+
* @return ChoiceAI_Client Client object
|
167 |
+
*/
|
168 |
+
public function setLimit($limit = 20){
|
169 |
+
if(isset($limit)){
|
170 |
+
$this->params['limit'] = $limit;
|
171 |
+
}else{
|
172 |
+
$this->params['limit'] = 20;
|
173 |
+
}
|
174 |
+
|
175 |
+
return $this;
|
176 |
+
}
|
177 |
+
|
178 |
+
/**
|
179 |
+
* sets the ruleset
|
180 |
+
* @param mixed $ruleset string
|
181 |
+
* @return ChoiceAI_Client Client object
|
182 |
+
*/
|
183 |
+
public function setRuleset($ruleset = 'search'){
|
184 |
+
if(isset($ruleset)){
|
185 |
+
$this->params['ruleset'] = $ruleset;
|
186 |
+
}else{
|
187 |
+
$this->params['ruleset'] = 'search';
|
188 |
+
}
|
189 |
+
return $this;
|
190 |
+
}
|
191 |
+
|
192 |
+
/**
|
193 |
+
* sets the sort
|
194 |
+
* @param mixed $sorts array
|
195 |
+
* @return ChoiceAI_Client Client object
|
196 |
+
*/
|
197 |
+
public function setSort($sorts = array()){
|
198 |
+
if(isset($sorts) && is_array($sorts)){
|
199 |
+
$this->params['sort'] = $sorts;
|
200 |
+
}
|
201 |
+
return $this;
|
202 |
+
}
|
203 |
+
|
204 |
+
/**
|
205 |
+
* sets the facet fields, This is mainly used for
|
206 |
+
* @param mixed $sorts array
|
207 |
+
* @return ChoiceAI_Client Client object
|
208 |
+
*/
|
209 |
+
public function setFacetFields($facetField = array()){
|
210 |
+
if(isset($facetField) && is_array($facetField)){
|
211 |
+
$this->params['facets'] = $facetField;
|
212 |
+
}
|
213 |
+
return $this;
|
214 |
+
}
|
215 |
+
|
216 |
+
/**
|
217 |
+
* sets the other options which can be used
|
218 |
+
* @param mixed $options array
|
219 |
+
* @return ChoiceAI_Client Client object
|
220 |
+
*/
|
221 |
+
public function setOtherOptions($options =array()){
|
222 |
+
if(isset($options) && is_array($options)){
|
223 |
+
$this->params['others'] = $options;
|
224 |
+
}
|
225 |
+
return $this;
|
226 |
+
}
|
227 |
+
|
228 |
+
/**
|
229 |
+
* sets the search query
|
230 |
+
* @param mixed $query search
|
231 |
+
* @return ChoiceAI_Client Client object
|
232 |
+
*/
|
233 |
+
public function setQuery($query = ''){
|
234 |
+
if(isset($query)){
|
235 |
+
$this->params['query'] = $query;
|
236 |
+
}
|
237 |
+
return $this;
|
238 |
+
}
|
239 |
+
|
240 |
+
/**
|
241 |
+
* sets the Category Id
|
242 |
+
* @param mixed $query search
|
243 |
+
* @return ChoiceAI_Client Client object
|
244 |
+
*/
|
245 |
+
public function setCategoryId($query = ''){
|
246 |
+
if(isset($query)){
|
247 |
+
$this->params['category-id'] = $query;
|
248 |
+
}
|
249 |
+
return $this;
|
250 |
+
}
|
251 |
+
|
252 |
+
/**
|
253 |
+
* sets the Cond
|
254 |
+
* @param mixed $query search
|
255 |
+
* @return ChoiceAI_Client Client object
|
256 |
+
*/
|
257 |
+
public function setCond($query = ''){
|
258 |
+
if(isset($query)){
|
259 |
+
$this->params['cond'] = $query;
|
260 |
+
}
|
261 |
+
return $this;
|
262 |
+
}
|
263 |
+
|
264 |
+
/**
|
265 |
+
* sets the Cond
|
266 |
+
* @param mixed $query search
|
267 |
+
* @return ChoiceAI_Client Client object
|
268 |
+
*/
|
269 |
+
public function setDebug($debug = false){
|
270 |
+
if(isset($debug)){
|
271 |
+
$this->params['debug'] = $debug;
|
272 |
+
}
|
273 |
+
return $this;
|
274 |
+
}
|
275 |
+
|
276 |
+
/**
|
277 |
+
* sets the multiSelectFacet
|
278 |
+
* @param mixed $multiSelectFacet boolean
|
279 |
+
* @return ChoiceAI_Client Client object
|
280 |
+
*/
|
281 |
+
public function setMultiSelectFacet($multiSelectFacet = false){
|
282 |
+
if(isset($multiSelectFacet)){
|
283 |
+
$this->params['multiSelectFacet'] = $multiSelectFacet;
|
284 |
+
}
|
285 |
+
return $this;
|
286 |
+
|
287 |
+
}
|
288 |
+
|
289 |
+
|
290 |
+
/**
|
291 |
+
*
|
292 |
+
* Search through ChoiceAI api
|
293 |
+
*
|
294 |
+
* @return ChoiceAI_ResultSet object
|
295 |
+
*/
|
296 |
+
public function search() {
|
297 |
+
$service = new ChoiceAI_Service();
|
298 |
+
$this->params["context"] = $this->getContext();
|
299 |
+
return $service->search($this->params,$this->address);
|
300 |
+
|
301 |
+
}
|
302 |
+
|
303 |
+
|
304 |
+
}
|
lib/ChoiceAI/Response.php
ADDED
@@ -0,0 +1,45 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @copyright Copyright (c) MineWhat
|
5 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
6 |
+
*/
|
7 |
+
|
8 |
+
class ChoiceAIResponse
|
9 |
+
{
|
10 |
+
var $results=array();
|
11 |
+
|
12 |
+
public function __construct($results){
|
13 |
+
$this->results=$results;
|
14 |
+
}
|
15 |
+
|
16 |
+
/**
|
17 |
+
* function to get products
|
18 |
+
*/
|
19 |
+
|
20 |
+
public function getResults(){
|
21 |
+
return $this->results["response"]["products"];
|
22 |
+
}
|
23 |
+
|
24 |
+
|
25 |
+
/**
|
26 |
+
* get Number of search Results
|
27 |
+
*/
|
28 |
+
public function getNumberOfProducts(){
|
29 |
+
return $this->results["response"]["numberOfProducts"];
|
30 |
+
}
|
31 |
+
|
32 |
+
|
33 |
+
/**
|
34 |
+
* get facets
|
35 |
+
*
|
36 |
+
*/
|
37 |
+
public function getFacets(){
|
38 |
+
return $this->results["facets"];
|
39 |
+
}
|
40 |
+
|
41 |
+
|
42 |
+
|
43 |
+
}
|
44 |
+
|
45 |
+
?>
|
lib/ChoiceAI/Result.php
ADDED
@@ -0,0 +1,65 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @copyright Copyright (c) MineWhat
|
5 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
6 |
+
*/
|
7 |
+
|
8 |
+
class ChoiceAI_Result {
|
9 |
+
/**
|
10 |
+
* Hit array
|
11 |
+
*
|
12 |
+
* @var array Hit array
|
13 |
+
*/
|
14 |
+
protected $_hit = array();
|
15 |
+
|
16 |
+
/**
|
17 |
+
* Constructs a single results object
|
18 |
+
*
|
19 |
+
* @param array $hit Hit data
|
20 |
+
*/
|
21 |
+
public function __construct(array $hit) {
|
22 |
+
|
23 |
+
$this->_hit = $hit;
|
24 |
+
|
25 |
+
$this->_hit["uniqueId"] = $hit["_id"];
|
26 |
+
$this->_hit["entity_id"] = $hit["_id"];
|
27 |
+
|
28 |
+
if (strpos($this->_hit["image"], 'catalog/product') !== false) {
|
29 |
+
$this->_hit["image"] = "/" . implode("/", array_slice(explode ( "/", $this->_hit["image"]), -3, 3));
|
30 |
+
}
|
31 |
+
|
32 |
+
$this->_hit["small_image"] = $this->_hit["image"];
|
33 |
+
$this->_hit["thumbnail"] = $this->_hit["image"];
|
34 |
+
|
35 |
+
$this->_hit["final_price"] = $hit["price"];
|
36 |
+
if(!is_null($hit["oldPrice"]) && $hit["oldPrice"] > 0) {
|
37 |
+
$this->_hit["price"] = $hit["oldPrice"];
|
38 |
+
} else {
|
39 |
+
$this->_hit["price"] = $hit["price"];
|
40 |
+
}
|
41 |
+
|
42 |
+
}
|
43 |
+
|
44 |
+
/**
|
45 |
+
* Magic function to directly access keys inside the result
|
46 |
+
*
|
47 |
+
* Returns null if key does not exist
|
48 |
+
*
|
49 |
+
* @param string $key Key name
|
50 |
+
* @return mixed Key value
|
51 |
+
*/
|
52 |
+
public function __get($key) {
|
53 |
+
return array_key_exists($key, $this->_hit) ? $this->_hit[$key] : null;
|
54 |
+
}
|
55 |
+
|
56 |
+
|
57 |
+
/*
|
58 |
+
* Returns the raw hit array
|
59 |
+
*
|
60 |
+
* @return array Hit array
|
61 |
+
*/
|
62 |
+
public function getHit() {
|
63 |
+
return $this->_hit;
|
64 |
+
}
|
65 |
+
}
|
lib/ChoiceAI/ResultSet.php
ADDED
@@ -0,0 +1,229 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @copyright Copyright (c) MineWhat
|
5 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
6 |
+
*/
|
7 |
+
|
8 |
+
include("Result.php");
|
9 |
+
class ChoiceAI_ResultSet implements Iterator, Countable {
|
10 |
+
/**
|
11 |
+
* Results
|
12 |
+
*
|
13 |
+
* @var array Results
|
14 |
+
*/
|
15 |
+
protected $_results = array();
|
16 |
+
|
17 |
+
/**
|
18 |
+
* Current position
|
19 |
+
*
|
20 |
+
* @var int Current position
|
21 |
+
*/
|
22 |
+
protected $_position = 0;
|
23 |
+
|
24 |
+
/**
|
25 |
+
* Response
|
26 |
+
*
|
27 |
+
* @var array
|
28 |
+
*/
|
29 |
+
protected $_response = null;
|
30 |
+
protected $_took = 0;
|
31 |
+
|
32 |
+
protected $spellCheckQuery=null;
|
33 |
+
/**
|
34 |
+
* Constructs ResultSet object
|
35 |
+
*
|
36 |
+
* @param array $response
|
37 |
+
*/
|
38 |
+
public function __construct($response) {
|
39 |
+
$this->rewind();
|
40 |
+
$this->_init($response);
|
41 |
+
}
|
42 |
+
|
43 |
+
|
44 |
+
|
45 |
+
/**
|
46 |
+
* Loads all data into the results object (initalisation)
|
47 |
+
*
|
48 |
+
* @param array $response
|
49 |
+
*/
|
50 |
+
protected function _init($response) {
|
51 |
+
$this->_response = $response;
|
52 |
+
|
53 |
+
$result = $response;
|
54 |
+
$this->_totalHits = $result["data"]["total"];
|
55 |
+
$this->_took = isset($result["searchMetaData"]["queryTime"]) ? $result["searchMetaData"]['queryTime'] : 0;
|
56 |
+
if (isset($result["data"]["products"])) {
|
57 |
+
foreach ($result["data"]["products"] as $hit) {
|
58 |
+
$this->_results[] = new ChoiceAI_Result($hit);
|
59 |
+
}
|
60 |
+
}
|
61 |
+
}
|
62 |
+
|
63 |
+
/**
|
64 |
+
* Returns all results
|
65 |
+
*
|
66 |
+
* @return array Results
|
67 |
+
*/
|
68 |
+
public function getResults() {
|
69 |
+
return $this->_results;
|
70 |
+
}
|
71 |
+
|
72 |
+
/**
|
73 |
+
* Returns whether facets exist
|
74 |
+
*
|
75 |
+
* @return boolean Facet existence
|
76 |
+
*/
|
77 |
+
public function hasFacets() {
|
78 |
+
|
79 |
+
return isset($this->_response['facets']);
|
80 |
+
}
|
81 |
+
|
82 |
+
/**
|
83 |
+
* Returns all facets results
|
84 |
+
*
|
85 |
+
* @return array Facet results
|
86 |
+
*/
|
87 |
+
public function getFacets() {
|
88 |
+
//return isset($this->_response['facets']) ? $this->_response['facets'] : array();
|
89 |
+
return isset($this->_response['data']) && isset($this->_response['data']['facets']) ? $this->_response['data']['facets'] : array();
|
90 |
+
}
|
91 |
+
|
92 |
+
/**
|
93 |
+
* Returns the total number of found hits
|
94 |
+
*
|
95 |
+
* @return int Total hits
|
96 |
+
*/
|
97 |
+
public function getTotalHits() {
|
98 |
+
return (int) $this->_totalHits;
|
99 |
+
}
|
100 |
+
|
101 |
+
/**
|
102 |
+
* Returns the total number of ms for this search to complete
|
103 |
+
*
|
104 |
+
* @return int Total time
|
105 |
+
*/
|
106 |
+
public function getTotalTime() {
|
107 |
+
return (int) $this->_took;
|
108 |
+
}
|
109 |
+
|
110 |
+
/**
|
111 |
+
* Returns response object
|
112 |
+
*
|
113 |
+
* @return array object
|
114 |
+
*/
|
115 |
+
public function getResponse() {
|
116 |
+
return $this->_response;
|
117 |
+
}
|
118 |
+
|
119 |
+
/**
|
120 |
+
* Returns size of current set
|
121 |
+
*
|
122 |
+
* @return int Size of set
|
123 |
+
*/
|
124 |
+
public function count() {
|
125 |
+
return sizeof($this->_results);
|
126 |
+
}
|
127 |
+
|
128 |
+
|
129 |
+
/**
|
130 |
+
* Returns the current object of the set
|
131 |
+
*
|
132 |
+
* @return ChoiceAI_Result|bool Set object or false if not valid (no more entries)
|
133 |
+
*/
|
134 |
+
public function current() {
|
135 |
+
if ($this->valid()) {
|
136 |
+
return $this->_results[$this->key()];
|
137 |
+
} else {
|
138 |
+
return false;
|
139 |
+
}
|
140 |
+
}
|
141 |
+
|
142 |
+
/**
|
143 |
+
* Sets pointer (current) to the next item of the set
|
144 |
+
*/
|
145 |
+
public function next() {
|
146 |
+
$this->_position++;
|
147 |
+
return $this->current();
|
148 |
+
}
|
149 |
+
|
150 |
+
/**
|
151 |
+
* Returns the position of the current entry
|
152 |
+
*
|
153 |
+
* @return int Current position
|
154 |
+
*/
|
155 |
+
public function key() {
|
156 |
+
return $this->_position;
|
157 |
+
}
|
158 |
+
|
159 |
+
/**
|
160 |
+
* Check if an object exists at the current position
|
161 |
+
*
|
162 |
+
* @return bool True if object exists
|
163 |
+
*/
|
164 |
+
public function valid() {
|
165 |
+
return isset($this->_results[$this->key()]);
|
166 |
+
}
|
167 |
+
|
168 |
+
/**
|
169 |
+
* Resets position to 0, restarts iterator
|
170 |
+
*/
|
171 |
+
public function rewind() {
|
172 |
+
$this->_position = 0;
|
173 |
+
}
|
174 |
+
|
175 |
+
|
176 |
+
/**
|
177 |
+
* get Spell corrected query
|
178 |
+
*/
|
179 |
+
|
180 |
+
public function getSpellCheckQuery(){
|
181 |
+
return $this->spellCheckQuery;
|
182 |
+
}
|
183 |
+
|
184 |
+
/**
|
185 |
+
* set Spell corrected query
|
186 |
+
*/
|
187 |
+
|
188 |
+
public function setSpellCheckQuery($query){
|
189 |
+
$this->spellCheckQuery=$query;
|
190 |
+
}
|
191 |
+
|
192 |
+
|
193 |
+
/**
|
194 |
+
* get didYouMean results
|
195 |
+
*/
|
196 |
+
public function getSpellSuggestion(){
|
197 |
+
|
198 |
+
$suggests=isset($this->_response['didYouMean'])?$this->_response['didYouMean']:null;
|
199 |
+
|
200 |
+
if(is_null($suggests)||!is_array($suggests)||!sizeof($suggests)>0){
|
201 |
+
return null;
|
202 |
+
}
|
203 |
+
|
204 |
+
|
205 |
+
foreach($suggests as $suggestion){
|
206 |
+
foreach($suggestion as $suggest_key=>$suggest_value){
|
207 |
+
if($suggest_key=='suggestion'){
|
208 |
+
return $suggest_value;
|
209 |
+
}
|
210 |
+
}
|
211 |
+
}
|
212 |
+
|
213 |
+
}
|
214 |
+
|
215 |
+
/**
|
216 |
+
* get stats
|
217 |
+
*/
|
218 |
+
public function getStats(){
|
219 |
+
// echo json_encode($this->_response);
|
220 |
+
return isset($this->_response['stats'])?$this->_response['stats']:null;
|
221 |
+
}
|
222 |
+
|
223 |
+
public function getSpellcheckFrequency(){
|
224 |
+
if(isset($this->_response["didYouMean"]) && isset($this->_response["didYouMean"][0]['frequency'])){
|
225 |
+
return (int)$this->_response["didYouMean"][0]['frequency'];
|
226 |
+
}
|
227 |
+
}
|
228 |
+
}
|
229 |
+
?>
|
lib/ChoiceAI/Service.php
ADDED
@@ -0,0 +1,190 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
|
3 |
+
/**
|
4 |
+
* @copyright Copyright (c) MineWhat
|
5 |
+
* @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
|
6 |
+
*/
|
7 |
+
|
8 |
+
include("ResultSet.php");
|
9 |
+
class ChoiceAI_Service
|
10 |
+
{
|
11 |
+
|
12 |
+
public function getOptions($options){
|
13 |
+
if(!isset($options)){
|
14 |
+
return "";
|
15 |
+
}
|
16 |
+
$content = '';
|
17 |
+
foreach($options as $key=>$value){
|
18 |
+
$content = $content.'&'. rawurlencode($key).'='.rawurlencode($value);
|
19 |
+
}
|
20 |
+
|
21 |
+
return $content;
|
22 |
+
}
|
23 |
+
|
24 |
+
|
25 |
+
/**
|
26 |
+
* method to set sort fields
|
27 |
+
*
|
28 |
+
*/
|
29 |
+
public function getSorting($sorts){
|
30 |
+
|
31 |
+
$sortString='&sort=';
|
32 |
+
$startFlag=false;
|
33 |
+
|
34 |
+
if(is_null($sorts)||!isset($sorts)||!is_array($sorts)||!sizeof($sorts)>0){
|
35 |
+
return '';
|
36 |
+
}
|
37 |
+
|
38 |
+
foreach($sorts as $sort_key=>$sort_value){
|
39 |
+
if($startFlag) {
|
40 |
+
$sortString=$sortString.",";
|
41 |
+
}
|
42 |
+
$startFlag = true;
|
43 |
+
if($sort_value == 1) {
|
44 |
+
$sortString=$sortString.rawurlencode($sort_key." asc");
|
45 |
+
} else {
|
46 |
+
$sortString=$sortString.rawurlencode($sort_key." desc");
|
47 |
+
}
|
48 |
+
}
|
49 |
+
|
50 |
+
return $sortString;
|
51 |
+
}
|
52 |
+
|
53 |
+
|
54 |
+
|
55 |
+
public function getFacetFields($facets,$filters){
|
56 |
+
|
57 |
+
$facetString="";
|
58 |
+
|
59 |
+
if($facets==null){
|
60 |
+
$facets=array();
|
61 |
+
}
|
62 |
+
foreach($facets as $facet){
|
63 |
+
$facetString=$facetString."&facet.field=";
|
64 |
+
if(array_key_exists($facet,$filters)){
|
65 |
+
if(!is_array($stringFacets[$facet]) || !sizeof($stringFacets[$facet]) > 0){
|
66 |
+
$facetString=$facetString.rawurlencode("{!ex=\"".$facet."\"}");
|
67 |
+
}
|
68 |
+
}
|
69 |
+
$facetString=$facetString.rawurlencode($facet);
|
70 |
+
}
|
71 |
+
|
72 |
+
return $facetString;
|
73 |
+
}
|
74 |
+
|
75 |
+
|
76 |
+
/**
|
77 |
+
* function to get facets
|
78 |
+
* @param mixed $param array
|
79 |
+
* @return $facetstring string
|
80 |
+
*/
|
81 |
+
public function getFilters($filter =array()) {
|
82 |
+
$facetString = '&filter='.rawurlencode(json_encode($filter));
|
83 |
+
return $facetString;
|
84 |
+
}
|
85 |
+
|
86 |
+
/**
|
87 |
+
* function to set String facets
|
88 |
+
* @param $facetkey string
|
89 |
+
* @param mixed $facetvalue array
|
90 |
+
* @param $multiSelectFacet boolean
|
91 |
+
* @return $facetstring string
|
92 |
+
*/
|
93 |
+
public function getAttributeFacets($facetkey = "", $facetValue = array(),$multiSelectFacet = false ){
|
94 |
+
|
95 |
+
$facetString = "(";
|
96 |
+
|
97 |
+
if(!is_array($facetValue) || !sizeof($facetValue) > 0){
|
98 |
+
return "";
|
99 |
+
}
|
100 |
+
|
101 |
+
$flag = false;
|
102 |
+
if($multiSelectFacet)
|
103 |
+
$facetString = $facetString.("{!tag=\"".$facetkey."\"}")."(";
|
104 |
+
foreach($facetValue as $value){
|
105 |
+
$value = str_replace('"','\"',$value);
|
106 |
+
if($flag){
|
107 |
+
$facetString=$facetString." OR ";
|
108 |
+
}
|
109 |
+
$flag=true;
|
110 |
+
if(is_array($value)){
|
111 |
+
$from = isset($value["from"])?$value["from"]:"*";
|
112 |
+
$to = isset($value["to"])?$value["to"]:"*";
|
113 |
+
$facetString=$facetString.$facetkey.":"."[".$from.' TO '.$to."]";
|
114 |
+
} else{
|
115 |
+
$facetString=$facetString.$facetkey.":"."\"".$value."\"";
|
116 |
+
}
|
117 |
+
}
|
118 |
+
|
119 |
+
return $facetString.")";
|
120 |
+
|
121 |
+
}
|
122 |
+
|
123 |
+
|
124 |
+
/**
|
125 |
+
* function to get queryParam
|
126 |
+
* @param mixed $ruleset string
|
127 |
+
* @return String query
|
128 |
+
*/
|
129 |
+
function getQueryParam($params = array()) {
|
130 |
+
if($params['ruleset'] == 'browse') {
|
131 |
+
return 'catid='. rawurlencode($params['category-id']);
|
132 |
+
} else {
|
133 |
+
return 'q='.rawurlencode($params['query']);
|
134 |
+
}
|
135 |
+
}
|
136 |
+
|
137 |
+
/**
|
138 |
+
* function to prepare Url
|
139 |
+
* @param mixed $params array
|
140 |
+
* @param mixed $address string
|
141 |
+
* @return String url
|
142 |
+
*/
|
143 |
+
function prepare_url($params = array(), $address = "") {
|
144 |
+
$url = $address.$params['ruleset']."?c=".$params['context']."&start=".(isset($params['start'])?$params['start']:0)."&rows=".(isset($params['limit'])?$params['limit']:20);
|
145 |
+
$url = $url.'&'.$this->getQueryParam($params);
|
146 |
+
$filter = $this->getFilters($params['filter']);
|
147 |
+
if($filter != "")
|
148 |
+
$url = $url.$filter;
|
149 |
+
if(isset($params['sort']))
|
150 |
+
$url = $url.$this->getSorting($params['sort']);
|
151 |
+
if(isset($params['others']))
|
152 |
+
$url = $url.$this->getOptions($params['others']);
|
153 |
+
return $url;
|
154 |
+
}
|
155 |
+
|
156 |
+
/**
|
157 |
+
*
|
158 |
+
* function to fire search query
|
159 |
+
*
|
160 |
+
*/
|
161 |
+
public function search($params, $address, $spellcheck = false) {
|
162 |
+
$url = $this->prepare_url($params, $address);
|
163 |
+
$opts = array(
|
164 |
+
'http'=>array(
|
165 |
+
'timeout'=>30,
|
166 |
+
)
|
167 |
+
);
|
168 |
+
|
169 |
+
$context = stream_context_create($opts);
|
170 |
+
$response =file_get_contents($url, false, $context);
|
171 |
+
|
172 |
+
$choiceaiResponse=null;
|
173 |
+
if(isset($response)) {
|
174 |
+
$choiceaiResponse=new ChoiceAI_ResultSet(json_decode($response,true));
|
175 |
+
|
176 |
+
if($spellcheck) {
|
177 |
+
$choiceaiResponse->setSpellCheckQuery($params['query']);
|
178 |
+
}
|
179 |
+
|
180 |
+
if((!is_null($choiceaiResponse) && !$spellcheck && $choiceaiResponse->getTotalHits()==0 && !is_null($spellSuggest=$choiceaiResponse->getSpellSuggestion())) ||
|
181 |
+
(!$spellcheck && $choiceaiResponse->getSpellcheckFrequency()>20 && !is_null($spellSuggest=$choiceaiResponse->getSpellSuggestion()))){
|
182 |
+
$params['query'] = $spellSuggest;
|
183 |
+
return $this->search($params, $address, true);
|
184 |
+
}
|
185 |
+
}
|
186 |
+
|
187 |
+
return $choiceaiResponse;
|
188 |
+
}
|
189 |
+
}
|
190 |
+
?>
|
lib/ChoiceAI/test.php
ADDED
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<?php
|
2 |
+
include("Client.php");
|
3 |
+
$facetlist=array();
|
4 |
+
$facetValue=array("broad bangles");
|
5 |
+
|
6 |
+
|
7 |
+
$facetValue=array("April");
|
8 |
+
$facetlist["gemstone_month_fq"]=$facetValue;
|
9 |
+
|
10 |
+
|
11 |
+
$facets=array();
|
12 |
+
$facets[]="frame_shape_fq";
|
13 |
+
$facets[]="brand_name_fq";
|
14 |
+
$facets[]="primary_frame_color_fq";
|
15 |
+
$facets[]="price_fq";
|
16 |
+
$facets[]="frame_size_fq";
|
17 |
+
|
18 |
+
|
19 |
+
|
20 |
+
$rangelist=array();
|
21 |
+
$rangeValue=array(array("from"=>"0", "to" => "500000"),array("from"=>"50", "to" => "100"));
|
22 |
+
//$facetlist["price_fq"]=$rangeValue;
|
23 |
+
|
24 |
+
$sortlist=array();
|
25 |
+
$sortlist['name']=1;
|
26 |
+
|
27 |
+
$options = array();
|
28 |
+
$options["stats"] = "price";
|
29 |
+
|
30 |
+
$_config = array(
|
31 |
+
'sitename'=>'cl-sandbox-1375791452266',
|
32 |
+
'apikey'=>'ad93787f2f479e3e63b0161b3877ec7a',
|
33 |
+
);
|
34 |
+
|
35 |
+
|
36 |
+
$choiceai= new ChoiceAI_Client($_config);
|
37 |
+
|
38 |
+
$results = $choiceai->setCond()
|
39 |
+
->setRuleset("search")
|
40 |
+
->setOtherOptions(array('wt'=>'json'))
|
41 |
+
->setFilters($facetlist)
|
42 |
+
->setDebug(true)
|
43 |
+
->setQuery("diamond")
|
44 |
+
->search();
|
45 |
+
|
46 |
+
echo '<br/>'.$results->getTotalHits().'<br/>';
|
47 |
+
foreach($results as $result){
|
48 |
+
echo $result->__get('name')."<br/>";
|
49 |
+
}
|
50 |
+
|
51 |
+
|
52 |
+
|
53 |
+
?>
|
package.xml
CHANGED
@@ -1,7 +1,7 @@
|
|
1 |
<?xml version="1.0"?>
|
2 |
<package>
|
3 |
<name>choiceai</name>
|
4 |
-
<version>1.0.
|
5 |
<stability>stable</stability>
|
6 |
<license uri="http://opensource.org/licenses/osl-3.0.php">osl</license>
|
7 |
<channel>community</channel>
|
@@ -9,10 +9,10 @@
|
|
9 |
<summary>Choice AI</summary>
|
10 |
<description>Choice AI</description>
|
11 |
<notes>Initial Code</notes>
|
12 |
-
<authors><author><name>MineWhat Inc.</name><user>MineWhat</user><email>
|
13 |
-
<date>2017-
|
14 |
-
<time>
|
15 |
-
<contents><target name="
|
16 |
<compatible/>
|
17 |
<dependencies><required><php><min>5.2.5</min><max>6.0.0</max></php></required></dependencies>
|
18 |
</package>
|
1 |
<?xml version="1.0"?>
|
2 |
<package>
|
3 |
<name>choiceai</name>
|
4 |
+
<version>1.0.9</version>
|
5 |
<stability>stable</stability>
|
6 |
<license uri="http://opensource.org/licenses/osl-3.0.php">osl</license>
|
7 |
<channel>community</channel>
|
9 |
<summary>Choice AI</summary>
|
10 |
<description>Choice AI</description>
|
11 |
<notes>Initial Code</notes>
|
12 |
+
<authors><author><name>MineWhat Inc.</name><user>rahulb14</user><email>rahulb14@gmail.com</email></author><author><name>MineWhat Inc.</name><user>harkirat</user><email>harkirat1892@gmail.com</email></author></authors>
|
13 |
+
<date>2017-05-18</date>
|
14 |
+
<time>16:45:19</time>
|
15 |
+
<contents><target name="magecommunity"><dir name="ChoiceAI"><dir name="Personalisation"><dir name="Block"><dir name="Base"><file name="Script.php" hash="af614113dea10a0a6d88281f615f1929"/></dir><dir name="Event"><dir name="Catalog"><dir name="Product"><file name="View.php" hash="233ac45484c22ecdf7063071406f71e2"/></dir></dir><dir name="Checkout"><dir name="Cart"><file name="Index.php" hash="e3bc31a08a994d72223d78ebde8a74f0"/></dir><dir name="Onepage"><file name="Success.php" hash="cc242d118e6b06bb3817d95b2322167c"/></dir></dir></dir></dir><dir name="Helper"><file name="Data.php" hash="8ab9069ffe5aa66ef085124b8ff613d6"/></dir><dir name="Model"><file name="Observer.php" hash="2a275848f3c22c444fe8589e8afbff42"/></dir><dir name="controllers"><file name="ApiController.php" hash="beb56ca8579e8dde410c6a32e9ecd359"/></dir><dir name="etc"><file name="adminhtml.xml" hash="2fc12bb0874c8f39963f1593b3954d2e"/><file name="config.xml" hash="f743d8ead3776891503ff368ad7e7330"/><file name="system.xml" hash="6f4674088b4c392cc06f5a70f383fd54"/></dir></dir></dir></target><target name="magelocal"><dir name="ChoiceAI"><dir name="Search"><dir name="Block"><dir name="Catalog"><dir name="Layer"><dir name="Filter"><file name="Attribute.php" hash="7920f693a41c71120640e58e425774c4"/><file name="Boolean.php" hash="b4725e9e63c54a5f06e226b2ba07423c"/><file name="Category.php" hash="f9add3a866fd08695fb8541292e345b5"/><file name="Decimal.php" hash="90b1f1b0e78c9fb8192affd726306939"/><file name="Price.php" hash="8a5219290c7773300725e99931dd265e"/></dir><file name="View.php" hash="ff410b8a64a5faacbb238e5bf5cb1898"/></dir><dir name="Product"><dir name="List"><file name="Toolbar.php" hash="1d012fd8656f890193c78063dbdabd53"/></dir><file name="List.php" hash="3e0b59fca7f65b0d3f6a130eefb801b8"/></dir></dir><dir name="Catalogsearch"><dir name="Enterprise"><file name="Layer.php" hash="76d2e136cfd2bdb8336bebc3e949035b"/></dir><dir name="Layer"><dir name="Filter"><file name="Attribute.php" hash="5d8377049114d7114468d083a06ae574"/></dir></dir><file name="Layer.php" hash="8f5a960b4a2c013d27812b73a9892e35"/><file name="Result.php" hash="3f8d6bf9eaef398389b33185e7546a67"/></dir></dir><dir name="Helper"><file name="Catalogsearch.php" hash="b6b01a37d0bf6747ae3c110fecce9fb4"/><file name="Choiceaisearch.php" hash="b79b88bad5becfd8115fae0ee5900104"/><file name="Data.php" hash="e14515804571467567d953b4558807d2"/></dir><dir name="Model"><dir name="Catalog"><file name="Category.php" hash="019e70bbe4ce6ed950f0b4b9a748bdfd"/><file name="Config.php" hash="2aa3e7483d01ac58ba5f2903b57ed8c0"/><dir name="Layer"><dir name="Filter"><file name="Attribute.php" hash="67b32680a7471e7a5d2ea210b6c9d612"/><file name="Boolean.php" hash="4de1790d8a6355c512b0a1aee663b8aa"/><file name="Category.php" hash="597c8b4fc8c5ca892456a799302a09a4"/><file name="Decimal.php" hash="fe9ae194e4540352fc7953d6988b09bb"/><file name="Price.php" hash="3c1e0e58d4b6995c3ca66ba6ed9c5987"/></dir></dir><file name="Layer.php" hash="21673a913e8510804df7906f881d7054"/></dir><dir name="Catalogsearch"><dir name="Layer"><dir name="Filter"><file name="Attribute.php" hash="0c08443cd3a964853e2eea7eab7ee550"/></dir></dir><file name="Layer.php" hash="7eb444d700b64d9655d9f5228c995688"/></dir><dir name="Resource"><dir name="Catalog"><dir name="Product"><file name="Collection.php" hash="6bb56964c306b18b2ffce7672ed1fd06"/></dir></dir><dir name="Engine"><file name="Abstract.php" hash="f155c4cfe1af05068aa680f263fba5ff"/><dir name="Choiceaisearch"><file name="Client.php" hash="ac47d7c5dc8ebee6bb55e21c090073db"/></dir><file name="Choiceaisearch.php" hash="dd64746289b1b4e5b9c4d975ce8e757e"/></dir></dir></dir><dir name="etc"><file name="config.xml" hash="231670d8ff280239c1bd7574c425f6e5"/></dir></dir><dir name="Searchcore"><dir name="Helper"><file name="Confighelper.php" hash="f70c2079e901bb9acf195c7e78113a03"/><file name="Constants.php" hash="c5dca3829a90713a3f249f1d2c89cf65"/><file name="Data.php" hash="ae8bd70f3e03d42111d1b3da8eb94748"/><file name="Feedhelper.php" hash="7d13d86a2f259133c4c2fe11d5f1b98f"/></dir><dir name="Model"><dir name="Api"><file name="Request.php" hash="6f9290ffb2a73c672f7aa00e32e70823"/><file name="Response.php" hash="c5b6dbdb19d6680e194b18bb55d8a424"/><dir name="Task"><file name="Analyticsimpression.php" hash="edc174dc4ed1a8feb1d95eb68cd99e68"/><file name="Autosuggestindex.php" hash="30b43a41efd48220b2b77e0b602889b6"/><file name="Feeddetails.php" hash="448ff57822069872b7159d411fd93fa4"/><file name="Searchimpression.php" hash="6fb8a25b40bf65ce693cc9061c010306"/><file name="Searchsetup.php" hash="1327009152d3f9ce1740e6cae53af00e"/><file name="Supportmail.php" hash="546294ea20cfe53a4013fdd28bf526a9"/><file name="Trackcart.php" hash="84d16939ecc2ba064ad7259ad953aa63"/><file name="Trackorder.php" hash="6365a64de8c6fa7f5cb427d9c360aa6f"/><file name="Triggerfeedupload.php" hash="0a7e0485b5153303736dd27a53655123"/><file name="Updatefeaturefields.php" hash="2f16846479decc9f90b9c379417664a5"/><file name="Validatekeys.php" hash="97dd25c5f23be74b5df043492801d2db"/></dir><file name="Task.php" hash="b9b712543c6c81e391ae348e13029227"/></dir><file name="Config.php" hash="88fab6725b14eaa8fb76ec7bb5c1f6d5"/><file name="Field.php" hash="1cb5f9208578bca7c964e62f765601e3"/><file name="Observer.php" hash="8b8400a55108e41dcc93e9ec49fcd44c"/><dir name="Resource"><file name="Attribute.php" hash="f4038c20e72085bae0cee6d0b8a9de1a"/><dir name="Config"><file name="Collection.php" hash="94c4b8ef674a6ee30021e7c77ecfe788"/></dir><file name="Config.php" hash="ab778a3ed12b38af778b51d653761daf"/><dir name="Field"><file name="Collection.php" hash="99c3377b97422d86e5628f62bfd9fa10"/></dir><file name="Field.php" hash="c081feab58c874ea51cc2621cc477b53"/><dir name="Product"><file name="Collection.php" hash="ec23c88a9028db1cf1e59475d97e844a"/></dir></dir></dir><dir name="etc"><file name="config.xml" hash="6f3734712ad2f84d4ace141c66199287"/></dir><dir name="sql"><dir name="choiceai_searchcore_setup"><file name="mysql4-install-1.0.0.php" hash="5fdda62bdcd455f1f0e3ee7f4438add4"/><file name="upgrade-1.0.21-1.0.22.php" hash="55d5ffc866caa8f18045aa1168b94680"/></dir></dir></dir></dir></target><target name="magelib"><dir name="ChoiceAI"><file name="Client.php" hash="085a6fdbd1a94be420960c184ad3bc7d"/><file name="Response.php" hash="c21f18e8988ffee234367da25986a390"/><file name="Result.php" hash="d9a1221f5223511e6af1e7f806c10ca4"/><file name="ResultSet.php" hash="30950b116d2f926ab89c17707bfe4da2"/><file name="Service.php" hash="9e4cdef2f33ea87166691f8e50be9045"/><file name="test.php" hash="9f12f4391b70fcbee541a96f2bdd2b80"/></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="choiceai_personalisation.xml" hash="95d72912f3b13c5a399e3b2e5b89dba9"/></dir><dir name="template"><dir name="choiceai"><dir name="personalisation"><dir name="base"><file name="script.phtml" hash="60b414f870c4b5bd761bfa2466d73707"/></dir><dir name="event"><dir name="catalog"><dir name="product"><file name="view.phtml" hash="9513eaaa0bda55931dacb6d90b698f31"/></dir></dir><dir name="checkout"><dir name="cart"><file name="index.phtml" hash="6a27ac509cc1c8c78515b025479f135b"/></dir></dir></dir></dir></dir></dir></dir></dir><dir name="default"><dir name="default"><dir name="layout"><file name="choiceai_personalisation.xml" hash="95d72912f3b13c5a399e3b2e5b89dba9"/></dir><dir name="template"><dir name="choiceai"><dir name="personalisation"><dir name="base"><file name="script.phtml" hash="ea2860493a07315af34ba80f8c282a84"/></dir></dir></dir></dir></dir></dir></dir></target><target name="mageetc"><dir name="modules"><file name="ChoiceAI_Personalisation.xml" hash="4bca20179604835e2e0e08298142c8bb"/></dir></target></contents>
|
16 |
<compatible/>
|
17 |
<dependencies><required><php><min>5.2.5</min><max>6.0.0</max></php></required></dependencies>
|
18 |
</package>
|