Antidot_Antidot - Version 1.1.1

Version Notes

Fix facet with ampersand configuration for search engine > facets
Replace "-" with "&afs:feed" to separate feeds in url (compatibility with AFS 7.7)
Fix empty facet id sent when performing an empty query to afs to get facets list
Add description node for variants
Add cdata for variant name
Prevent to export empty categories node
Add cdata for variant name
Add variant details for grouped products

Download this release

Release Info

Developer Antidot
Extension Antidot_Antidot
Version 1.1.1
Comparing to
See all releases


Code changes from version 1.1.0 to 1.1.1

Files changed (86) hide show
  1. app/code/community/MDN/Antidot/Block/Catalogsearch/Result.php +1 -1
  2. app/code/community/MDN/Antidot/Block/System/Config/Button/AfsStore.php +2 -3
  3. app/code/community/MDN/Antidot/Helper/Data.php +45 -0
  4. app/code/community/MDN/Antidot/Model/Catalogsearch/Layer.php +1 -1
  5. app/code/community/MDN/Antidot/Model/Export/Product.php +54 -28
  6. app/code/community/MDN/Antidot/Model/Search/Suggest.php +21 -17
  7. app/code/community/MDN/Antidot/Model/System/Config/Facet.php +5 -1
  8. app/code/community/MDN/Antidot/Model/System/Config/Sort.php +4 -4
  9. app/code/community/MDN/Antidot/Test/Helper/CatalogSearch/Data.php +35 -0
  10. app/code/community/MDN/Antidot/Test/Helper/Data.php +28 -0
  11. app/code/community/MDN/Antidot/Test/Helper/Data/providers/testTranslateFacetlabel.yaml +16 -0
  12. app/code/community/MDN/Antidot/Test/Model/Export/Product.php +84 -0
  13. app/code/community/MDN/Antidot/Test/Model/Export/Product/fixtures/testWritePricesFixedtax.yaml +90 -0
  14. app/code/community/MDN/Antidot/Test/Model/Export/Product/fixtures/testWriteProductNoVariant.yaml +84 -0
  15. app/code/community/MDN/Antidot/Test/Model/Search/Suggest.php +40 -0
  16. app/code/community/MDN/Antidot/Test/Model/Search/Suggest/fixtures/testSuggest.yaml +35 -0
  17. app/code/community/MDN/Antidot/controllers/Front/SearchController.php +1 -1
  18. app/code/community/MDN/Antidot/etc/config.xml +24 -3
  19. app/locale/de_AT/MDN_Antidot.csv +1 -0
  20. app/locale/de_CH/MDN_Antidot.csv +1 -0
  21. app/locale/de_DE/MDN_Antidot.csv +1 -0
  22. lib/antidot/.gitignore +2 -0
  23. lib/antidot/.travis.yml +14 -0
  24. lib/antidot/AFS/ACP/afs_acp_connector.php +10 -0
  25. lib/antidot/AFS/SEARCH/FILTER/afs_filter.php +1 -0
  26. lib/antidot/AFS/SEARCH/FILTER/afs_native_function_filter.php +30 -0
  27. lib/antidot/AFS/SEARCH/TEST/clientDataHelperTest.php +176 -1
  28. lib/antidot/AFS/SEARCH/TEST/facetHelperTest.php +88 -0
  29. lib/antidot/AFS/SEARCH/TEST/facetTest.php +21 -0
  30. lib/antidot/AFS/SEARCH/TEST/headerHelperTest.php +691 -70
  31. lib/antidot/AFS/SEARCH/TEST/pagerHelperTest.php +27 -27
  32. lib/antidot/AFS/SEARCH/TEST/promoteBannerReplyHelper.php +101 -0
  33. lib/antidot/AFS/SEARCH/TEST/promoteRedirectReplyHelper.php +59 -0
  34. lib/antidot/AFS/SEARCH/TEST/promoteReplysetHelperTest.php +5 -2
  35. lib/antidot/AFS/SEARCH/TEST/queryCoderTest.php +9 -0
  36. lib/antidot/AFS/SEARCH/TEST/queryTest.php +245 -0
  37. lib/antidot/AFS/SEARCH/TEST/replyHelperTest.php +207 -0
  38. lib/antidot/AFS/SEARCH/TEST/replysetHelperTest.php +4 -4
  39. lib/antidot/AFS/SEARCH/TEST/responseHelperTest.php +1 -0
  40. lib/antidot/AFS/SEARCH/TEST/searchQueryManagerTest.php +35 -0
  41. lib/antidot/AFS/SEARCH/TEST/searchTest.php +47 -0
  42. lib/antidot/AFS/SEARCH/afs_base_reply_helper.php +0 -1
  43. lib/antidot/AFS/SEARCH/afs_client_data_helper.php +317 -36
  44. lib/antidot/AFS/SEARCH/afs_cluster_parameter.php +26 -0
  45. lib/antidot/AFS/SEARCH/afs_facet.php +46 -2
  46. lib/antidot/AFS/SEARCH/afs_facet_helper.php +82 -27
  47. lib/antidot/AFS/SEARCH/afs_facet_manager.php +33 -2
  48. lib/antidot/AFS/SEARCH/afs_facet_mode.php +33 -1
  49. lib/antidot/AFS/SEARCH/afs_feed_coder.php +4 -0
  50. lib/antidot/AFS/SEARCH/afs_filter_coder.php +4 -0
  51. lib/antidot/AFS/SEARCH/afs_filter_parameter.php +24 -0
  52. lib/antidot/AFS/SEARCH/afs_fts_mode.php +18 -0
  53. lib/antidot/AFS/SEARCH/afs_pager_helper.php +5 -3
  54. lib/antidot/AFS/SEARCH/afs_promote_banner_reply_helper.php +43 -0
  55. lib/antidot/AFS/SEARCH/afs_promote_redirect_reply_helper.php +34 -0
  56. lib/antidot/AFS/SEARCH/afs_promote_reply_helper.php +28 -26
  57. lib/antidot/AFS/SEARCH/afs_query.php +518 -94
  58. lib/antidot/AFS/SEARCH/afs_query_coder.php +117 -92
  59. lib/antidot/AFS/SEARCH/afs_reply_helper.php +21 -0
  60. lib/antidot/AFS/SEARCH/afs_reply_helper_factory.php +29 -1
  61. lib/antidot/AFS/SEARCH/afs_replyset_helper.php +3 -2
  62. lib/antidot/AFS/SEARCH/afs_response_helper.php +28 -15
  63. lib/antidot/AFS/SEARCH/afs_search.php +19 -0
  64. lib/antidot/AFS/SEARCH/afs_search_query_manager.php +55 -13
  65. lib/antidot/AFS/SEARCH/afs_sort_coder.php +4 -0
  66. lib/antidot/AFS/SEARCH/afs_sort_parameter.php +25 -0
  67. lib/antidot/AFS/afs_connector.php +7 -4
  68. lib/antidot/AFS/afs_feed.php +309 -0
  69. lib/antidot/AFS/afs_multiple_values_parameter.php +71 -0
  70. lib/antidot/AFS/afs_query_base.php +196 -54
  71. lib/antidot/AFS/afs_query_parameter.php +27 -0
  72. lib/antidot/AFS/afs_single_value_parameter.php +45 -0
  73. lib/antidot/AIF/afs_document.php +25 -25
  74. lib/antidot/COMMON/afs_exception.php +11 -1
  75. lib/antidot/COMMON/afs_versions.php +1 -1
  76. lib/antidot/COMMON/lib/JsonPath/JsonPath.php +279 -0
  77. lib/antidot/COMMON/lib/JsonPath/JsonStore.php +223 -0
  78. lib/antidot/COMMON/php-SAI/.gitignore +10 -10
  79. lib/antidot/README.md +6 -0
  80. lib/antidot/afs_lib.doxygen +19 -1
  81. lib/antidot/afs_lib.php +1 -0
  82. lib/antidot/afs_version.php +2 -2
  83. lib/antidot/composer.json +8 -0
  84. lib/antidot/doc/data/raw_example.php +205 -214
  85. lib/antidot/rules.mk +3 -3
  86. package.xml +4 -4
app/code/community/MDN/Antidot/Block/Catalogsearch/Result.php CHANGED
@@ -74,7 +74,7 @@ class MDN_Antidot_Block_CatalogSearch_Result extends Mage_CatalogSearch_Block_Re
74
$availableOrders = array();
75
foreach($availableSortable as $sort) {
76
list($field, $label) = explode('|', $sort['sort']);
77
- $availableOrders[$field] = $label;
78
}
79
80
return $availableOrders;
74
$availableOrders = array();
75
foreach($availableSortable as $sort) {
76
list($field, $label) = explode('|', $sort['sort']);
77
+ $availableOrders[$field] = Mage::helper('Antidot')->translateFacetlabel($label);
78
}
79
80
return $availableOrders;
app/code/community/MDN/Antidot/Block/System/Config/Button/AfsStore.php CHANGED
@@ -33,9 +33,8 @@ class MDN_Antidot_Block_System_Config_Button_AfsStore extends Mage_Adminhtml_Blo
33
* we get the magento back-office session language to determine
34
* the locale of the AfsStore Back-office link
35
*/
36
- $locale = Mage::getSingleton('adminhtml/session')->getLocale();
37
- $locArr = explode('_',$locale);
38
- $urlLocale = array_shift($locArr);
39
if (in_array($urlLocale, $this->afsStoreLocales)) {
40
$url .= $urlLocale;
41
} else {
33
* we get the magento back-office session language to determine
34
* the locale of the AfsStore Back-office link
35
*/
36
+ $codeLocale = Mage::getSingleton('adminhtml/session')->getLocale();
37
+ $urlLocale = Mage::helper('Antidot')->getLanguageFromCodeLocale($codeLocale);
38
if (in_array($urlLocale, $this->afsStoreLocales)) {
39
$url .= $urlLocale;
40
} else {
app/code/community/MDN/Antidot/Helper/Data.php CHANGED
@@ -203,6 +203,9 @@ class MDN_Antidot_Helper_Data extends Mage_Core_Helper_Abstract
203
/**
204
* Translate facet name
205
*
206
* @param $facetcode
207
* @param $defaultValue
208
* @return mixed
@@ -217,6 +220,48 @@ class MDN_Antidot_Helper_Data extends Mage_Core_Helper_Abstract
217
return $label;
218
}
219
220
/**
221
* Round a number
222
*
203
/**
204
* Translate facet name
205
*
206
+ * This one is used in FO, to display the facet name in the result page, it is based
207
+ * on the label returned by the previous search ws search call
208
+ *
209
* @param $facetcode
210
* @param $defaultValue
211
* @return mixed
220
return $label;
221
}
222
223
+ /*
224
+ * MCNX-217 : Translate facet label on front office :
225
+ * - The facet labels stemming from hard-coded module sorting (Relevance, Name, etc...) are
226
+ * stored in English and translated by the magento module translation files
227
+ * - the facet labels stemming from the AFS WS facets, are stored in a serialized array
228
+ * contained all the translated labels, we change the one corresponding to the current language
229
+ *
230
+ * @param $label
231
+ * @return string
232
+ */
233
+ public function translateFacetlabel($label)
234
+ {
235
+ Mage::log($label, null, 'antidot.log');
236
+ if ($labels = @unserialize($label)) {
237
+ $magentoLocale = Mage::app()->getLocale()->getLocaleCode();
238
+ $antidotLanguage = $this->getLanguageFromCodeLocale($magentoLocale);
239
+ if (isset($labels[$antidotLanguage])) {
240
+ $label = $labels[$antidotLanguage];
241
+ } elseif (isset($labels[0])) {
242
+ $label = $labels[0];
243
+ } elseif (isset($labels['EN'])) {
244
+ $label = $labels['EN']; //default language
245
+ }
246
+ } else {
247
+ $label = Mage::helper('Antidot')->__($label);
248
+ }
249
+ return $label;
250
+ }
251
+
252
+ /*
253
+ * Get the language code (ex: en) from a locale code (ex: en_US)
254
+ *
255
+ * @param $codeLocale
256
+ * @return string
257
+ */
258
+ public function getLanguageFromCodeLocale($codeLocale)
259
+ {
260
+ $arr = explode('_', $codeLocale);
261
+ $antidotLanguage = array_shift($arr);
262
+ return $antidotLanguage;
263
+ }
264
+
265
/**
266
* Round a number
267
*
app/code/community/MDN/Antidot/Model/Catalogsearch/Layer.php CHANGED
@@ -52,7 +52,7 @@ class MDN_Antidot_Model_Catalogsearch_Layer extends Mage_CatalogSearch_Model_Lay
52
foreach($config as $facet) {
53
list($id, $label) = explode('|', $facet['facet']);
54
$key = sprintf('%02d', $facet['order']).'_'.$id; //sptrinf to ensure order : 10 is after 09
55
- $facets[$key] = array('id' => $id, 'label' => $label);
56
}
57
}
58
ksort($facets);
52
foreach($config as $facet) {
53
list($id, $label) = explode('|', $facet['facet']);
54
$key = sprintf('%02d', $facet['order']).'_'.$id; //sptrinf to ensure order : 10 is after 09
55
+ $facets[$key] = array('id' => $id, 'label' => Mage::helper('Antidot')->translateFacetlabel($label));
56
}
57
}
58
ksort($facets);
app/code/community/MDN/Antidot/Model/Export/Product.php CHANGED
@@ -43,7 +43,7 @@ class MDN_Antidot_Model_Export_Product extends MDN_Antidot_Model_Export_Abstract
43
protected $propertyLabel = array();
44
45
protected $productsWithOperation = null;
46
-
47
protected $productVisible = array(
48
Mage_Catalog_Model_Product_Visibility::VISIBILITY_IN_SEARCH,
49
Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH,
@@ -223,6 +223,35 @@ class MDN_Antidot_Model_Export_Product extends MDN_Antidot_Model_Export_Abstract
223
if (count($stores) == 0)
224
return;
225
226
$this->xml->push('product', array('id' => $product->getId(), 'xml:lang' => $this->lang, 'autocomplete' => $this->autoCompleteProducts));
227
228
$this->xml->push('websites');
@@ -259,7 +288,7 @@ class MDN_Antidot_Model_Export_Product extends MDN_Antidot_Model_Export_Abstract
259
$this->writeGenders($product);
260
$this->writeMisc($product);
261
262
- $this->writeVariants($product, $stores);
263
264
$this->xml->pop();
265
}
@@ -783,15 +812,28 @@ class MDN_Antidot_Model_Export_Product extends MDN_Antidot_Model_Export_Abstract
783
*/
784
protected function writePrices($product, $parentProduct, $context, $store)
785
{
786
$prices = ($this->getPrices($parentProduct->getId(), $store->getWebsiteId()));
787
788
- $price = Mage::helper('tax')->getPrice($product, $prices['price'], true);
789
790
//try to get price & pricecut
791
if ($prices['final_price'] < $prices['price'])
792
{
793
- $priceCut = Mage::helper('tax')->getPrice($product, $prices['price'], true);
794
- $price = Mage::helper('tax')->getPrice($product, $prices['final_price'], true);
795
}
796
797
$price = Mage::helper('directory')->currencyConvert($price, Mage::app()->getStore()->getCurrentCurrencyCode(), $store->getCurrentCurrencyCode());
@@ -987,12 +1029,13 @@ class MDN_Antidot_Model_Export_Product extends MDN_Antidot_Model_Export_Abstract
987
}
988
989
/**
990
- * Write variants produt
991
*
992
* @param Product $product
993
* @param array $stores
994
*/
995
- protected function writeVariants($product, $stores)
996
{
997
$this->xml->push('variants');
998
@@ -1000,28 +1043,11 @@ class MDN_Antidot_Model_Export_Product extends MDN_Antidot_Model_Export_Abstract
1000
$this->writeVariant($product, $product, $stores);
1001
$this->xml->pop();
1002
1003
- $variantProducts = array();
1004
- switch($product->getTypeID())
1005
- {
1006
- case Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE:
1007
- $variantProducts = $product->getTypeInstance(true)->getUsedProducts(null, $product);
1008
- break;
1009
- case Mage_Catalog_Model_Product_Type::TYPE_GROUPED:
1010
- $variantProducts = $product->getTypeInstance(true)->getAssociatedProducts($product);
1011
- break;
1012
- }
1013
-
1014
- if(count($variantProducts) > 0) {
1015
- foreach($variantProducts as $variantProduct) {
1016
1017
- //Do not include product if status is not enabled
1018
- if (!$variantProduct->getstatus() == 1)
1019
- continue;
1020
-
1021
- $this->xml->push('variant', array('id' => $variantProduct->getId()));
1022
- $this->writeVariant($variantProduct, $product, $stores);
1023
- $this->xml->pop();
1024
- }
1025
}
1026
1027
$this->xml->pop();
43
protected $propertyLabel = array();
44
45
protected $productsWithOperation = null;
46
+
47
protected $productVisible = array(
48
Mage_Catalog_Model_Product_Visibility::VISIBILITY_IN_SEARCH,
49
Mage_Catalog_Model_Product_Visibility::VISIBILITY_BOTH,
223
if (count($stores) == 0)
224
return;
225
226
+ /**
227
+ * MCNX-211 : check if grouped/configurables product has variant before begin export product
228
+ */
229
+ $variantProducts = array();
230
+ if ($product->getTypeID() == Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE
231
+ || $product->getTypeID() == Mage_Catalog_Model_Product_Type::TYPE_GROUPED) {
232
+
233
+ switch ($product->getTypeID()) {
234
+ case Mage_Catalog_Model_Product_Type::TYPE_CONFIGURABLE:
235
+ $variantProductsColl = $product->getTypeInstance(true)->getUsedProducts(null, $product);
236
+ break;
237
+ case Mage_Catalog_Model_Product_Type::TYPE_GROUPED:
238
+ $variantProductsColl = $product->getTypeInstance(true)->getAssociatedProducts($product);
239
+ break;
240
+ }
241
+
242
+ foreach ($variantProductsColl as $variantProduct) {
243
+ //Do not include product if status is not enabled
244
+ if ($variantProduct->getStatus() == 1) {
245
+ $variantProducts[] = $variantProduct;
246
+ }
247
+ }
248
+
249
+ //skip product if it has no active variant, but is a "variant" type
250
+ if (count($variantProducts) == 0) {
251
+ return;
252
+ }
253
+ }
254
+
255
$this->xml->push('product', array('id' => $product->getId(), 'xml:lang' => $this->lang, 'autocomplete' => $this->autoCompleteProducts));
256
257
$this->xml->push('websites');
288
$this->writeGenders($product);
289
$this->writeMisc($product);
290
291
+ $this->writeVariants($product, $variantProducts, $stores);
292
293
$this->xml->pop();
294
}
812
*/
813
protected function writePrices($product, $parentProduct, $context, $store)
814
{
815
+
816
+ /**
817
+ * MCNX-222 : Add Fixed Taxs to prices
818
+ */
819
+ $weeHelper = Mage::helper('weee');
820
+ $weeeAmount = 0;
821
+ if ($weeHelper->isEnabled($store)) {
822
+ $address = Mage::getModel('customer/address');
823
+ $address->setCountryId(Mage::helper('core')->getDefaultCountry($store));
824
+ $address->setQuote(Mage::getSingleton('sales/quote'));
825
+ $weeeAmount = $weeHelper->getAmount($product, $address, $address, $store->getWebsiteId(), false);
826
+ }
827
+
828
$prices = ($this->getPrices($parentProduct->getId(), $store->getWebsiteId()));
829
830
+ $price = Mage::helper('tax')->getPrice($product, $prices['price'] + $weeeAmount, true);
831
832
//try to get price & pricecut
833
if ($prices['final_price'] < $prices['price'])
834
{
835
+ $priceCut = Mage::helper('tax')->getPrice($product, $prices['price'] + $weeeAmount, true);
836
+ $price = Mage::helper('tax')->getPrice($product, $prices['final_price'] + $weeeAmount, true);
837
}
838
839
$price = Mage::helper('directory')->currencyConvert($price, Mage::app()->getStore()->getCurrentCurrencyCode(), $store->getCurrentCurrencyCode());
1029
}
1030
1031
/**
1032
+ * Write variants product
1033
*
1034
* @param Product $product
1035
+ * @param array $variantProducts
1036
* @param array $stores
1037
*/
1038
+ protected function writeVariants($product, $variantProducts, $stores)
1039
{
1040
$this->xml->push('variants');
1041
1043
$this->writeVariant($product, $product, $stores);
1044
$this->xml->pop();
1045
1046
+ foreach($variantProducts as $variantProduct) {
1047
1048
+ $this->xml->push('variant', array('id' => $variantProduct->getId()));
1049
+ $this->writeVariant($variantProduct, $product, $stores);
1050
+ $this->xml->pop();
1051
}
1052
1053
$this->xml->pop();
app/code/community/MDN/Antidot/Model/Search/Suggest.php CHANGED
@@ -90,7 +90,7 @@ class MDN_Antidot_Model_Search_Suggest extends MDN_Antidot_Model_Search_Abstract
90
list($lang) = explode('_', Mage::getStoreConfig('general/locale/code', Mage::app()->getStore()->getId()));
91
foreach($this->feed as $key => $feed) {
92
//take the storeId for product feed, website for others
93
- $id = ($key == 'products') ? Mage::app()->getStore()->getWebsiteId() : Mage::app()->getStore()->getId();
94
$this->feed[$key]['name'] = sprintf($feed['tpl'], $id, $lang);
95
}
96
@@ -104,13 +104,15 @@ class MDN_Antidot_Model_Search_Suggest extends MDN_Antidot_Model_Search_Abstract
104
protected function loadFacetAutocomplete()
105
{
106
$facets = @unserialize(Mage::getStoreConfig('antidot/fields_product/properties'));
107
- foreach($facets as $facet) {
108
- if($facet['autocomplete'] === '1') {
109
- $this->feed['property_'.$facet['value']] = array(
110
- 'tpl' => 'property_'.$facet['value'].'_%d_%s',
111
- 'number' => self::DEFAULT_REPLIES_NUMBER,
112
- 'order' => (count($this->feed)+1),
113
- );
114
}
115
}
116
}
@@ -121,15 +123,17 @@ class MDN_Antidot_Model_Search_Suggest extends MDN_Antidot_Model_Search_Abstract
121
*/
122
protected function loadAdditionalFeeds()
123
{
124
- $additionalFeeds = @unserialize(Mage::getStoreConfig('antidot/suggest/additionnal_feed'));
125
- foreach($additionalFeeds as $feed) {
126
- $addFeed = $feed['value'];
127
- $this->feed[$addFeed] = array(
128
- 'tpl' => $addFeed,
129
- 'number' => self::DEFAULT_REPLIES_NUMBER,
130
- 'order' => (count($this->feed)+1),
131
- );
132
- }
133
}
134
135
90
list($lang) = explode('_', Mage::getStoreConfig('general/locale/code', Mage::app()->getStore()->getId()));
91
foreach($this->feed as $key => $feed) {
92
//take the storeId for product feed, website for others
93
+ $id = ($key == 'products') ? Mage::app()->getStore()->getId() : Mage::app()->getStore()->getWebsiteId();
94
$this->feed[$key]['name'] = sprintf($feed['tpl'], $id, $lang);
95
}
96
104
protected function loadFacetAutocomplete()
105
{
106
$facets = @unserialize(Mage::getStoreConfig('antidot/fields_product/properties'));
107
+ if (is_array($facets)) {
108
+ foreach ($facets as $facet) {
109
+ if ($facet['autocomplete'] === '1') {
110
+ $this->feed['property_'.$facet['value']] = array(
111
+ 'tpl' => 'property_'.$facet['value'].'_%d_%s',
112
+ 'number' => self::DEFAULT_REPLIES_NUMBER,
113
+ 'order' => (count($this->feed) + 1),
114
+ );
115
+ }
116
}
117
}
118
}
123
*/
124
protected function loadAdditionalFeeds()
125
{
126
+ $additionalFeeds = @unserialize(Mage::getStoreConfig('antidot/suggest/additionnal_feed'));
127
+ if (is_array($additionalFeeds)) {
128
+ foreach ($additionalFeeds as $feed) {
129
+ $addFeed = $feed['value'];
130
+ $this->feed[$addFeed] = array(
131
+ 'tpl' => $addFeed,
132
+ 'number' => self::DEFAULT_REPLIES_NUMBER,
133
+ 'order' => (count($this->feed) + 1),
134
+ );
135
+ }
136
+ }
137
}
138
139
app/code/community/MDN/Antidot/Model/System/Config/Facet.php CHANGED
@@ -30,7 +30,11 @@ class MDN_Antidot_Model_System_Config_Facet
30
$this->options = array();
31
foreach($search->getFacets() as $facetId => $facet) {
32
if($typeExclude === null || $facet->get_type() !== $typeExclude) {
33
- $this->options[] = array('value' => $facetId.'|'.$facet->label, 'label' => $facetId.' ('.$facet->get_type().')');
34
}
35
}
36
30
$this->options = array();
31
foreach($search->getFacets() as $facetId => $facet) {
32
if($typeExclude === null || $facet->get_type() !== $typeExclude) {
33
+ /*
34
+ * MCNX-217 : we store all the labels returned by the afsstore WS in a serialized array
35
+ * it will be used in front office using the current language
36
+ */
37
+ $this->options[] = array('value' => $facetId.'|'.serialize($facet->get_labels()), 'label' => $facetId.' ('.$facet->get_type().')');
38
}
39
}
40
app/code/community/MDN/Antidot/Model/System/Config/Sort.php CHANGED
@@ -43,7 +43,7 @@ class MDN_Antidot_Model_System_Config_Sort
43
44
foreach($this->marketingFields as $field => $label) {
45
if(Mage::getStoreConfig('antidot/fields_product/'.$field) != '') {
46
- $options[] = array('value' => $field.'|'.$label, 'label' => $label);
47
}
48
}
49
@@ -64,9 +64,9 @@ class MDN_Antidot_Model_System_Config_Sort
64
public function initMarketingFields()
65
{
66
$this->marketingFields = array(
67
- 'is_new' => Mage::helper('Antidot')->__('Is new'),
68
- 'is_best_sale' => Mage::helper('Antidot')->__('Is top sale'),
69
- 'is_featured' => Mage::helper('Antidot')->__('Is featured'),
70
);
71
}
72
43
44
foreach($this->marketingFields as $field => $label) {
45
if(Mage::getStoreConfig('antidot/fields_product/'.$field) != '') {
46
+ $options[] = array('value' => $field.'|'.$label, 'label' => Mage::helper('Antidot')->__($label));
47
}
48
}
49
64
public function initMarketingFields()
65
{
66
$this->marketingFields = array(
67
+ 'is_new' => 'Is new',
68
+ 'is_best_sale' => 'Is top sale',
69
+ 'is_featured' => 'Is featured',
70
);
71
}
72
app/code/community/MDN/Antidot/Test/Helper/CatalogSearch/Data.php ADDED
@@ -0,0 +1,35 @@
1
+ <?php
2
+
3
+ /**
4
+ * Magento
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Open Software License (OSL 3.0)
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @copyright Copyright (c) 2015 Antidot (http://www.antidot.net)
13
+ * @author : Antidot devmagento@antidot.net
14
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
15
+ */
16
+ class MDN_Antidot_Test_Helper_CatalogSearch_Data extends EcomDev_PHPUnit_Test_Case {
17
+
18
+
19
+ /**
20
+ * MCNX-210 : make get helper work with this "wrong" case : catalogSearch instead of catalgsearch
21
+ *
22
+ * @test
23
+ */
24
+ public function testCase() {
25
+
26
+ $helper = Mage::helper('catalogSearch');
27
+
28
+ $this->assertEquals(
29
+ 'MDN_Antidot_Helper_CatalogSearch_Data',
30
+ get_class($helper)
31
+ );
32
+
33
+ }
34
+
35
+ }
app/code/community/MDN/Antidot/Test/Helper/Data.php ADDED
@@ -0,0 +1,28 @@
1
+ <?php
2
+
3
+
4
+ class MDN_Antidot_Test_Helper_Data extends EcomDev_PHPUnit_Test_Case
5
+ {
6
+
7
+ /**
8
+ * MCNX-217 : Test translation of facet fields
9
+ *
10
+ * @test
11
+ * @dataProvider dataProvider
12
+ */
13
+ public function testTranslateFacetlabel($label, $locale, $expected)
14
+ {
15
+
16
+ /** @var $helper MDN_Antidot_Helper_Data */
17
+ $helper = Mage::helper('Antidot');
18
+
19
+ Mage::app()->getLocale()->setLocale($locale);
20
+ $translatedLabel = $helper->translateFacetlabel($label);
21
+
22
+ $this->assertEquals(
23
+ $expected,
24
+ $translatedLabel
25
+ );
26
+
27
+ }
28
+ }
app/code/community/MDN/Antidot/Test/Helper/Data/providers/testTranslateFacetlabel.yaml ADDED
@@ -0,0 +1,16 @@
1
+ -
2
+ - Relevance
3
+ - en_US
4
+ - Relevance
5
+ -
6
+ - a:3:{s:2:"de";s:14:"Verfügbarkeit";s:2:"en";s:12:"Availability";s:2:"fr";s:14:"Disponibilité";}
7
+ - en_US
8
+ - Availability
9
+ -
10
+ - a:3:{s:2:"de";s:14:"Verfügbarkeit";s:2:"en";s:12:"Availability";s:2:"fr";s:14:"Disponibilité";}
11
+ - fr_FR
12
+ - Disponibilité
13
+ -
14
+ - a:3:{s:2:"de";s:14:"Verfügbarkeit";s:2:"en";s:12:"Availability";s:2:"fr";s:14:"Disponibilité";}
15
+ - de_DE
16
+ - Verfügbarkeit
app/code/community/MDN/Antidot/Test/Model/Export/Product.php CHANGED
@@ -371,6 +371,90 @@ class MDN_Antidot_Test_Model_Export_Product extends EcomDev_PHPUnit_Test_Case
371
372
}
373
374
/**
375
*
376
* @param $productId
371
372
}
373
374
+ /**
375
+ * MCNX-221 : test variant product without variant is not exported
376
+ * @test
377
+ * @loadFixture
378
+ */
379
+ public function testWriteProductNoVariant() {
380
+
381
+ /* @var $export \MDN_Antidot_Model_Export_Product */
382
+ $export = Mage::getModel('Antidot/export_product');
383
+
384
+ //Load a grouped product on store french, this product has no associated product
385
+ $storeId = 3;
386
+ Mage::app()->setCurrentStore($storeId);
387
+ $product = $this->loadProduct(1, $storeId);
388
+
389
+ MDN_Antidot_Test_PHPUnitUtil::callPrivateMethod($export,'initXml', array('product'));
390
+ /* @var $export \MDN_Antidot_Helper_Xml_Writer */
391
+ $xmlWriter = MDN_Antidot_Test_PHPUnitUtil::getPrivateProperty($export, 'xml');
392
+ $xmlWriter->flush();
393
+
394
+ /*
395
+ * The writeProduct method is called with the "empty" grouped product
396
+ */
397
+ MDN_Antidot_Test_PHPUnitUtil::callPrivateMethod($export,'writeProduct', array($product, array(Mage::app()->getStore())));
398
+
399
+ $this->assertEquals('', $xmlWriter->getXml());
400
+
401
+
402
+ }
403
+
404
+ /**
405
+ * MCNX-222 : test Write prices : Fixed tax prices
406
+ * @test
407
+ * @loadFixture
408
+ */
409
+ public function testWritePricesFixedtax() {
410
+
411
+ /* @var $export \MDN_Antidot_Model_Export_Product */
412
+ $export = Mage::getModel('Antidot/export_product');
413
+
414
+ $storeId = 3;
415
+ $store = Mage::getModel('core/store')->load($storeId);
416
+ $product = $this->loadProduct(1, $storeId);
417
+ $context = array('currency'=>'EUR', 'country'=>'FR');
418
+
419
+ MDN_Antidot_Test_PHPUnitUtil::callPrivateMethod($export,'initXml', array('product'));
420
+ /* @var $export \MDN_Antidot_Helper_Xml_Writer */
421
+ $xmlWriter = MDN_Antidot_Test_PHPUnitUtil::getPrivateProperty($export, 'xml');
422
+ $xmlWriter->flush();
423
+
424
+ /*
425
+ * The writePrices is called without fixed tax price activated
426
+ * expected data also in dataProvider
427
+ */
428
+ MDN_Antidot_Test_PHPUnitUtil::callPrivateMethod($export,'writePrices', array($product, $product, $context, $store));
429
+
430
+ $expected='<prices><price currency="EUR" type="PRICE_FINAL" vat_included="true" country="FR">12.99</price></prices>';
431
+ $this->assertEquals($expected, $xmlWriter->getXml());
432
+ $xmlWriter->flush();
433
+
434
+ /*
435
+ * The writePrices is called witout fixed tax price activated
436
+ * expected data also in dataProvider
437
+ */
438
+ $mockHelper = $this->getHelperMock('weee', array('isEnabled', 'getAmount'));
439
+ $mockHelper->expects($this->any())
440
+ ->method('isEnabled')
441
+ ->will($this->returnValue(true)); //activate fixed tax in the mock helper
442
+ $mockHelper->expects($this->any())
443
+ ->method('getAmount')
444
+ ->will($this->returnValue(3)); //Set a fixed tax price of 3 EUR in the mock helper
445
+ $this->replaceByMock('helper', 'weee', $mockHelper);
446
+
447
+ /*
448
+ * The writePrices is called with fixed tax price activated
449
+ * expected data also in dataProvider
450
+ */
451
+ MDN_Antidot_Test_PHPUnitUtil::callPrivateMethod($export,'writePrices', array($product, $product, $context, $store));
452
+
453
+ $expected='<prices><price currency="EUR" type="PRICE_FINAL" vat_included="true" country="FR">15.99</price></prices>';
454
+ $this->assertEquals($expected, $xmlWriter->getXml());
455
+
456
+
457
+ }
458
/**
459
*
460
* @param $productId
app/code/community/MDN/Antidot/Test/Model/Export/Product/fixtures/testWritePricesFixedtax.yaml ADDED
@@ -0,0 +1,90 @@
1
+ scope:
2
+ website: # Initialize websites
3
+ - website_id: 2
4
+ code: usa_website
5
+ name: USA Website
6
+ default_group_id: 2
7
+ - website_id: 3
8
+ code: french_website
9
+ name: French Website
10
+ default_group_id: 3
11
+ - website_id: 4
12
+ code: german_website
13
+ name: German Website
14
+ default_group_id: 4
15
+ group: # Initializes store groups
16
+ - group_id: 2
17
+ website_id: 2
18
+ name: USA Store Group
19
+ default_store_id: 2
20
+ root_category_id: 2 # Default Category
21
+ - group_id: 3
22
+ website_id: 3
23
+ name: French Store Group
24
+ default_store_id: 3
25
+ root_category_id: 2 # Default Category
26
+ - group_id: 4
27
+ website_id: 4
28
+ name: German Store Group
29
+ default_store_id: 4
30
+ root_category_id: 2 # Default Category
31
+ store: # Initializes store views
32
+ - store_id: 2
33
+ website_id: 2
34
+ group_id: 2
35
+ code: usa
36
+ name: USA Store
37
+ is_active: 1
38
+ - store_id: 3
39
+ website_id: 3
40
+ group_id: 3
41
+ code: france
42
+ name: France Store
43
+ is_active: 1
44
+ - store_id: 4
45
+ website_id: 4
46
+ group_id: 4
47
+ code: germany
48
+ name: Germany Store
49
+ is_active: 1
50
+ config:
51
+ default/antidot/fields_product/properties: a:2:{s:18:"_1426953698813_813";a:2:{s:5:"value";s:7:"authors";s:12:"autocomplete";s:1:"0";}s:18:"_1426953714346_346";a:2:{s:5:"value";s:6:"editor";s:12:"autocomplete";s:1:"0";}}
52
+ default/web/secure/base_url: http://www.mywebsite.com/
53
+ default/web/unsecure/base_url: http://www.mywebsite.com/
54
+ stores/usa/web/secure/base_url: http://www.mywebsite.com/
55
+ stores/france/web/secure/base_url: http://www.monsiteweb.fr/
56
+ stores/germany/web/secure/base_url: http://www.meinwebseite.de/
57
+ stores/usa/web/unsecure/base_url: http://www.mywebsite.com/
58
+ stores/france/web/unsecure/base_url: http://www.monsiteweb.fr/
59
+ stores/germany/web/unsecure/base_url: http://www.meinwebseite.de/
60
+ eav:
61
+ catalog_product:
62
+ - entity_id: 1
63
+ type_id: simple
64
+ attribute_set_id: 4 # Default
65
+ sku: book
66
+ name: Book
67
+ short_description: Book
68
+ description: Book
69
+ url_key: book
70
+ image: b/o/book.jpg
71
+ thumbnail: b/o/book_small.jpg
72
+ stock:
73
+ qty: 100.00
74
+ is_in_stock: 1
75
+ website_ids:
76
+ - usa_website
77
+ - french_website
78
+ - german_website
79
+ category_ids:
80
+ - 2 # Default Category
81
+ price: 12.99
82
+ tax_class_id: 2 # Taxable Goods
83
+ status: 1 # Enabled
84
+ visibility: 4 # Visible in Catalog & Search
85
+ /websites: # Set different prices per website
86
+ usa_website:
87
+ special_price: 9.99
88
+ german_website:
89
+ price: 9.99
90
+ special_price: 5.99
app/code/community/MDN/Antidot/Test/Model/Export/Product/fixtures/testWriteProductNoVariant.yaml ADDED
@@ -0,0 +1,84 @@
1
+ scope:
2
+ website: # Initialize websites
3
+ - website_id: 2
4
+ code: usa_website
5
+ name: USA Website
6
+ default_group_id: 2
7
+ - website_id: 3
8
+ code: french_website
9
+ name: French Website
10
+ default_group_id: 3
11
+ - website_id: 4
12
+ code: german_website
13
+ name: German Website
14
+ default_group_id: 4
15
+ group: # Initializes store groups
16
+ - group_id: 2
17
+ website_id: 2
18
+ name: USA Store Group
19
+ default_store_id: 2
20
+ root_category_id: 2 # Default Category
21
+ - group_id: 3
22
+ website_id: 3
23
+ name: French Store Group
24
+ default_store_id: 3
25
+ root_category_id: 2 # Default Category
26
+ - group_id: 4
27
+ website_id: 4
28
+ name: German Store Group
29
+ default_store_id: 4
30
+ root_category_id: 2 # Default Category
31
+ store: # Initializes store views
32
+ - store_id: 2
33
+ website_id: 2
34
+ group_id: 2
35
+ code: usa
36
+ name: USA Store
37
+ is_active: 1
38
+ - store_id: 3
39
+ website_id: 3
40
+ group_id: 3
41
+ code: france
42
+ name: France Store
43
+ is_active: 1
44
+ - store_id: 4
45
+ website_id: 4
46
+ group_id: 4
47
+ code: germany
48
+ name: Germany Store
49
+ is_active: 1
50
+ config:
51
+ default/antidot/fields_product/properties: a:2:{s:18:"_1426953698813_813";a:2:{s:5:"value";s:7:"authors";s:12:"autocomplete";s:1:"0";}s:18:"_1426953714346_346";a:2:{s:5:"value";s:6:"editor";s:12:"autocomplete";s:1:"0";}}
52
+ default/web/secure/base_url: http://www.mywebsite.com/
53
+ default/web/unsecure/base_url: http://www.mywebsite.com/
54
+ stores/usa/web/secure/base_url: http://www.mywebsite.com/
55
+ stores/france/web/secure/base_url: http://www.monsiteweb.fr/
56
+ stores/germany/web/secure/base_url: http://www.meinwebseite.de/
57
+ stores/usa/web/unsecure/base_url: http://www.mywebsite.com/
58
+ stores/france/web/unsecure/base_url: http://www.monsiteweb.fr/
59
+ stores/germany/web/unsecure/base_url: http://www.meinwebseite.de/
60
+ eav:
61
+ catalog_product:
62
+ - entity_id: 1
63
+ type_id: grouped
64
+ attribute_set_id: 4 # Default
65
+ sku: books
66
+ name: Books
67
+ short_description: Books
68
+ description: Books
69
+ url_key: books
70
+ image: b/o/books.jpg
71
+ thumbnail: b/o/books_small.jpg
72
+ stock:
73
+ qty: 0
74
+ is_in_stock: 0
75
+ website_ids:
76
+ - usa_website
77
+ - french_website
78
+ - german_website
79
+ category_ids:
80
+ - 2 # Default Category
81
+ price: 0
82
+ tax_class_id: 2 # Taxable Goods
83
+ status: 1 # Enabled
84
+ visibility: 4 # Visible in Catalog & Search
app/code/community/MDN/Antidot/Test/Model/Search/Suggest.php ADDED
@@ -0,0 +1,40 @@
1
+ <?php
2
+
3
+ /**
4
+ * Magento
5
+ *
6
+ * NOTICE OF LICENSE
7
+ *
8
+ * This source file is subject to the Open Software License (OSL 3.0)
9
+ * It is also available through the world-wide-web at this URL:
10
+ * http://opensource.org/licenses/osl-3.0.php
11
+ *
12
+ * @copyright Copyright (c) 2015 Antidot (http://www.antidot.net)
13
+ * @author : Antidot devmagento@antidot.net
14
+ * @license http://opensource.org/licenses/osl-3.0.php Open Software License (OSL 3.0)
15
+ */
16
+ class MDN_Antidot_Test_Model_Search_Suggest extends EcomDev_PHPUnit_Test_Case
17
+ {
18
+
19
+ /**
20
+ * MCNX-226 and MCNX-227 : inverted storeid and websiteid on acp ws url cause no results
21
+ *
22
+ * @test
23
+ * @loadFixture
24
+ */
25
+ public function testSuggest() {
26
+
27
+ Mage::app()->setCurrentStore(5);
28
+
29
+ /** @var $observer MDN_Antidot_Model_Search_Suggest */
30
+ $suggest = Mage::getModel('Antidot/search_suggest');
31
+
32
+ $feeds = MDN_Antidot_Test_PHPUnitUtil::callPrivateMethod($suggest, 'getFeeds', array('products'));
33
+
34
+ $this->assertEquals(
35
+ 'featured_products_5_fr&afs:feed=categories_3_fr&afs:feed=brands_3_fr&afs:feed=articles_3_fr&afs:feed=stores_3_fr',
36
+ $feeds
37
+ );
38
+
39
+ }
40
+ }
app/code/community/MDN/Antidot/Test/Model/Search/Suggest/fixtures/testSuggest.yaml ADDED
@@ -0,0 +1,35 @@
1
+ scope:
2
+ website: # Initialize websites
3
+ - website_id: 3
4
+ code: french_website
5
+ name: French Website
6
+ default_group_id: 3
7
+ group: # Initializes store groups
8
+ - group_id: 3
9
+ website_id: 3
10
+ name: French Store Group
11
+ default_store_id: 3
12
+ root_category_id: 2 # Default Category
13
+ - group_id: 5
14
+ website_id: 3
15
+ name: French Store Group Discount
16
+ default_store_id: 5
17
+ root_category_id: 2 # Default Category
18
+ store: # Initializes store views
19
+ - store_id: 3
20
+ website_id: 3
21
+ group_id: 3
22
+ code: france
23
+ name: France Store
24
+ is_active: 1
25
+ - store_id: 5
26
+ website_id: 3
27
+ group_id: 5
28
+ code: france_discount
29
+ name: France Store Discount
30
+ is_active: 1
31
+
32
+ config:
33
+ default/general/locale/code: zz
34
+ stores/france/general/locale/code: fr
35
+ stores/france_discount/general/locale/code: fr
app/code/community/MDN/Antidot/controllers/Front/SearchController.php CHANGED
@@ -30,6 +30,6 @@ class MDN_Antidot_Front_SearchController extends Mage_Core_Controller_Front_Acti
30
$format = $formatParam;
31
}
32
33
- $this->getResponse()->setBody(Mage::getModel('Antidot/Search_Suggest')->get($query, $format));
34
}
35
}
30
$format = $formatParam;
31
}
32
33
+ $this->getResponse()->setBody(Mage::getModel('Antidot/search_suggest')->get($query, $format));
34
}
35
}
app/code/community/MDN/Antidot/etc/config.xml CHANGED
@@ -18,7 +18,7 @@
18
</crontab>
19
<modules>
20
<MDN_Antidot>
21
- <version>1.1.0</version>
22
</MDN_Antidot>
23
</modules>
24
<global>
@@ -31,6 +31,12 @@
31
<data>MDN_Antidot_Helper_CatalogSearch_Data</data>
32
</rewrite>
33
</catalogsearch>
34
<enterprise_search>
35
<rewrite>
36
<data>MDN_Antidot_Helper_Enterprise_Search_Data</data>
@@ -129,6 +135,16 @@
129
</adminhtml>
130
131
<frontend>
132
<routers>
133
<Antidot>
134
<use>standard</use>
@@ -192,7 +208,7 @@
192
<xsl:variable name="categories-title">Categories</xsl:variable>
193
<xsl:variable name="brands-title">Brands</xsl:variable>
194
<!-- Thumbnail settings -->
195
- <xsl:variable name="thumbnail_width">35</xsl:variable>
196
<!-- Price settings -->
197
<xsl:variable name="display_price" select="true()"/>
198
<xsl:variable name="decimal-separator">,</xsl:variable>
@@ -390,8 +406,13 @@
390
<xsl:attribute name="class">image</xsl:attribute>
391
<xsl:attribute name="style">float: left; margin-right:5px;</xsl:attribute>
392
<xsl:element name="img">
393
- <xsl:attribute name="width">
394
<xsl:value-of select="$thumbnail_width"/>
395
</xsl:attribute>
396
<xsl:attribute name="src">
397
<xsl:apply-templates select="@value"/>
18
</crontab>
19
<modules>
20
<MDN_Antidot>
21
+ <version>1.1.1</version>
22
</MDN_Antidot>
23
</modules>
24
<global>
31
<data>MDN_Antidot_Helper_CatalogSearch_Data</data>
32
</rewrite>
33
</catalogsearch>
34
+ <!-- MCNX mcnx-210 : compatibility case : catalagSearch (solutionlevage), we duplicate the rewrite definition for this "special" case -->
35
+ <catalogSearch>
36
+ <rewrite>
37
+ <data>MDN_Antidot_Helper_CatalogSearch_Data</data>
38
+ </rewrite>
39
+ </catalogSearch>
40
<enterprise_search>
41
<rewrite>
42
<data>MDN_Antidot_Helper_Enterprise_Search_Data</data>
135
</adminhtml>
136
137
<frontend>
138
+ <!-- Antidot module translation are needed in front for the sort labels -->
139
+ <translate>
140
+ <modules>
141
+ <MDN_Antidot>
142
+ <files>
143
+ <default>MDN_Antidot.csv</default>
144
+ </files>
145
+ </MDN_Antidot>
146
+ </modules>
147
+ </translate>
148
<routers>
149
<Antidot>
150
<use>standard</use>
208
<xsl:variable name="categories-title">Categories</xsl:variable>
209
<xsl:variable name="brands-title">Brands</xsl:variable>
210
<!-- Thumbnail settings -->
211
+ <xsl:variable name="thumbnail_width">40</xsl:variable>
212
<!-- Price settings -->
213
<xsl:variable name="display_price" select="true()"/>
214
<xsl:variable name="decimal-separator">,</xsl:variable>
406
<xsl:attribute name="class">image</xsl:attribute>
407
<xsl:attribute name="style">float: left; margin-right:5px;</xsl:attribute>
408
<xsl:element name="img">
409
+ <xsl:attribute name="style">
410
+ <xsl:text>max-width:</xsl:text>
411
+ <xsl:value-of select="$thumbnail_width"/>
412
+ <xsl:text>px;</xsl:text>
413
+ <xsl:text>max-height:</xsl:text>
414
<xsl:value-of select="$thumbnail_width"/>
415
+ <xsl:text>px;</xsl:text>
416
</xsl:attribute>
417
<xsl:attribute name="src">
418
<xsl:apply-templates select="@value"/>
app/locale/de_AT/MDN_Antidot.csv CHANGED
@@ -127,6 +127,7 @@ Relevance,Relevanz
127
Position,Position
128
Name,Name
129
Price,Preis
130
"Is promotional",Förgerung
131
"Is new",Neuigkeiten
132
"Is top sale",Spitzenverkaufs
127
Position,Position
128
Name,Name
129
Price,Preis
130
+ "Stock","Lager"
131
"Is promotional",Förgerung
132
"Is new",Neuigkeiten
133
"Is top sale",Spitzenverkaufs
app/locale/de_CH/MDN_Antidot.csv CHANGED
@@ -127,6 +127,7 @@ Relevance,Relevanz
127
Position,Position
128
Name,Name
129
Price,Preis
130
"Is promotional",Förgerung
131
"Is new",Neuigkeiten
132
"Is top sale",Spitzenverkaufs
127
Position,Position
128
Name,Name
129
Price,Preis
130
+ "Stock","Lager"
131
"Is promotional",Förgerung
132
"Is new",Neuigkeiten
133
"Is top sale",Spitzenverkaufs
app/locale/de_DE/MDN_Antidot.csv CHANGED
@@ -127,6 +127,7 @@ Relevance,Relevanz
127
Position,Position
128
Name,Name
129
Price,Preis
130
"Is promotional",Förgerung
131
"Is new",Neuigkeiten
132
"Is top sale",Spitzenverkaufs
127
Position,Position
128
Name,Name
129
Price,Preis
130
+ "Stock","Lager"
131
"Is promotional",Förgerung
132
"Is new",Neuigkeiten
133
"Is top sale",Spitzenverkaufs
lib/antidot/.gitignore CHANGED
@@ -3,3 +3,5 @@ doc/html
3
*.bak
4
*.swp
5
*#*
3
*.bak
4
*.swp
5
*#*
6
+ .idea
7
+ coverage
lib/antidot/.travis.yml ADDED
@@ -0,0 +1,14 @@
1
+ language: php
2
+
3
+ php:
4
+ - 5.5
5
+ - 5.4
6
+ - 5.3
7
+
8
+ before_install:
9
+ - sudo apt-get update > /dev/null
10
+
11
+ install:
12
+ - sudo apt-get install -y --force-yes make
13
+
14
+ script: make
lib/antidot/AFS/ACP/afs_acp_connector.php CHANGED
@@ -37,4 +37,14 @@ class AfsAcpConnector extends AfsConnector
37
{
38
return array('error' => $message, 'details' => $details);
39
}
40
}
37
{
38
return array('error' => $message, 'details' => $details);
39
}
40
+
41
+ /** @internal
42
+ * @brief Overloads default implementation by setting json version to 1 in order to make it work with the API.
43
+ * @param $parameters [in-out] List of parameters to update with standard parameters.
44
+ */
45
+ protected function update_with_defaults(array& $parameters)
46
+ {
47
+ parent::update_with_defaults($parameters);
48
+ $parameters['afs:output'] = 'json,1';
49
+ }
50
}
lib/antidot/AFS/SEARCH/FILTER/afs_filter.php CHANGED
@@ -2,6 +2,7 @@
2
/** @file afs_filter.php */
3
4
require_once 'AFS/SEARCH/FILTER/afs_operator_filter.php';
5
6
/** @brief Helper function to create new AfsFilter instance.
7
* @param $id [in] Filter identifier.
2
/** @file afs_filter.php */
3
4
require_once 'AFS/SEARCH/FILTER/afs_operator_filter.php';
5
+ require_once 'AFS/SEARCH/FILTER/afs_native_function_filter.php';
6
7
/** @brief Helper function to create new AfsFilter instance.
8
* @param $id [in] Filter identifier.
lib/antidot/AFS/SEARCH/FILTER/afs_native_function_filter.php ADDED
@@ -0,0 +1,30 @@
1
+ <?php
2
+ /**
3
+ * Created by PhpStorm.
4
+ * User: ct
5
+ * Date: 11/4/14
6
+ * Time: 8:21 AM
7
+ */
8
+
9
+ function native_function_filter($function_name, $function_params) {
10
+ return new AfsFilterWrapper(null, new AfsNativeFunctionFilter($function_name, $function_params));
11
+ }
12
+
13
+ class AfsNativeFunctionFilter extends AfsFilter {
14
+ private $function_name = null;
15
+ private $function_params = array();
16
+
17
+ public function __construct($function_name, $function_params) {
18
+ $this->function_name = $function_name;
19
+ $this->function_params = $function_params;
20
+ }
21
+
22
+ public function to_string() {
23
+ return $this->function_name . '(' . implode(',', $this->function_params) . ')';
24
+ }
25
+ }
26
+
27
+ abstract class AfsNativeFunction {
28
+
29
+ const Geo_dist = "geo:dist";
30
+ }
lib/antidot/AFS/SEARCH/TEST/clientDataHelperTest.php CHANGED
@@ -168,7 +168,7 @@ class ClientDataHelperTest extends PHPUnit_Framework_TestCase
168
$this->assertEquals($helper->mime_type, 'application/json');
169
}
170
171
- public function testRetrieveSimpleJSONDataAsText()
172
{
173
$input = json_decode('{
174
"clientData": [
@@ -302,4 +302,179 @@ class ClientDataHelperTest extends PHPUnit_Framework_TestCase
302
$doc = new DOMDocument();
303
$doc->loadXML($data);
304
}
305
}
168
$this->assertEquals($helper->mime_type, 'application/json');
169
}
170
171
+ public function testRetrieveSimpleJSONDataAsText2()
172
{
173
$input = json_decode('{
174
"clientData": [
302
$doc = new DOMDocument();
303
$doc->loadXML($data);
304
}
305
+
306
+ public function testJsonCltDataGetValueJsonClientDataHelper() {
307
+ $input = json_decode('
308
+ {
309
+ "contents": { "data1": "value1",
310
+ "data2": [ { "k": "v" } ] },
311
+ "id": "id1",
312
+ "mimeType": "application/json"
313
+ }');
314
+
315
+
316
+ $json_clientdata = new AfsJsonClientDataHelper($input);
317
+ $this->assertEquals('value1', $json_clientdata->get_node("$.data1"));
318
+ $this->assertEquals('v', $json_clientdata->get_node("$.data2[0].k"));
319
+
320
+ $expected_result = array("data1" => "value1", "data2" => array(array("k" => "v")));
321
+ $this->assertEquals(array($expected_result),
322
+ $json_clientdata->get_nodes(""));
323
+ $this->assertEquals(array($expected_result),
324
+ $json_clientdata->get_nodes());
325
+ $this->assertEquals($expected_result,
326
+ $json_clientdata->get_node(""));
327
+ $this->assertEquals($expected_result,
328
+ $json_clientdata->get_node());
329
+ }
330
+
331
+ public function testJsonCltDataFirstElementReturnedByGetNode() {
332
+ $input = json_decode('
333
+ {
334
+ "contents": {
335
+ "data1": [ { "k": "v" } ], "data1": "value1" },
336
+ "id": "id1",
337
+ "mimeType": "application/json"
338
+ }');
339
+
340
+ $json_clientdata = new AfsJsonClientDataHelper($input);
341
+ $this->assertEquals('value1', $json_clientdata->get_node("$.data1"));
342
+ }
343
+
344
+ public function testJsonCltDataMultipleElementsReturnedByGetNodes() {
345
+ $input = json_decode('
346
+ {
347
+ "contents": { "data1": "value1",
348
+ "data": { "data1": [ { "k": "v" } ] }},
349
+ "id": "id1",
350
+ "mimeType": "application/json"
351
+ }');
352
+
353
+ $json_clientdata = new AfsJsonClientDataHelper($input);
354
+ $this->assertTrue(in_array('value1', $json_clientdata->get_nodes("$..data1")));
355
+ $this->assertTrue(in_array(array(array("k" => "v")), $json_clientdata->get_nodes("$..data1")));
356
+ }
357
+
358
+ /**
359
+ * @expectedException AfsNoResultException
360
+ */
361
+ public function testJsonCltDataNoElementFoundGetNode() {
362
+ $input = json_decode('
363
+ {
364
+ "contents": { "dataa1": "value1",
365
+ "dataa2": [ { "k": "v" } ] },
366
+ "id": "id1",
367
+ "mimeType": "application/json"
368
+ }');
369
+ $json_clientdata = new AfsJsonClientDataHelper($input);
370
+ $json_clientdata->get_node("$.data1");
371
+ }
372
+
373
+ /**
374
+ * @expectedException AfsNoResultException
375
+ */
376
+ public function testJsonCltDataNoElementFoundgetNodes() {
377
+ $input = json_decode('
378
+ {
379
+ "contents": { "data1": "value1",
380
+ "data2": [ { "k": "v" } ] },
381
+ "id": "id1",
382
+ "mimeType": "application/json"
383
+ }');
384
+
385
+ $input = json_decode('
386
+ {
387
+ "contents": { "dataa1": "value1",
388
+ "dataa2": [ { "k": "v" } ] },
389
+ "id": "id1",
390
+ "mimeType": "application/json"
391
+ }');
392
+ $json_clientdata = new AfsJsonClientDataHelper($input);
393
+ $json_clientdata->get_nodes("$.data1");
394
+ }
395
+
396
+ public function testXmlCltDataGetNodeDataHelper() {
397
+ $xml_client_data = '<clientData><data1 attr=\"foo\">value1</data1><data2><data1>value2</data1></data2></clientData>';
398
+ $input = json_decode('
399
+ {
400
+ "contents": "' . $xml_client_data . '",
401
+ "id": "id1",
402
+ "mimeType": "application/json"
403
+ }');
404
+
405
+
406
+ $xml_clientdata = new AfsXmlClientDataHelper($input);
407
+ $this->assertEquals(array("data1" => array('attributes' => array( 'attr' => 'foo'), "value1")), $xml_clientdata->get_node("/clientData/data1"));
408
+ $this->assertEquals(array("data2" => array("data1" => "value2")), $xml_clientdata->get_node("/clientData/data2"));
409
+
410
+ $expected_result =array('clientData' => array("data1" => array('attributes' => array( 'attr' => 'foo'), "value1"), "data2" => array("data1" => "value2")));
411
+ $this->assertEquals(array($expected_result),
412
+ $xml_clientdata->get_nodes(""));
413
+ $this->assertEquals(array($expected_result),
414
+ $xml_clientdata->get_nodes());
415
+ $this->assertEquals($expected_result,
416
+ $xml_clientdata->get_node(""));
417
+ $this->assertEquals($expected_result,
418
+ $xml_clientdata->get_node());
419
+ }
420
+
421
+ public function testXmlCltDataFirstElementReturnedByGetNode() {
422
+ $xml_client_data = '<clientData><data1>value1</data1><data1><k>v</k></data1></clientData>';
423
+ $input = json_decode('
424
+ {
425
+ "contents": "' . $xml_client_data . '",
426
+ "id": "id1",
427
+ "mimeType": "application/json"
428
+ }');
429
+
430
+ $xml_clientdata = new AfsXmlClientDataHelper($input);
431
+ $this->assertEquals(array('data1' => 'value1'), $xml_clientdata->get_node("/clientData/data1"));
432
+ }
433
+
434
+ public function testXmlCltDataMultipleElementsReturnedByGetNodes() {
435
+ $xml_client_data = '<clientData><data1 attr=\"bidule\">value1</data1><data1><k>v</k></data1></clientData>';
436
+ $input = json_decode('
437
+ {
438
+ "contents": "' . $xml_client_data . '",
439
+ "id": "id1",
440
+ "mimeType": "application/json"
441
+ }');
442
+
443
+ $xml_clientdata = new AfsXmlClientDataHelper($input);
444
+ $this->assertTrue(in_array(array('attr' => 'bidule'), $xml_clientdata->get_nodes("//data1/@attr")));
445
+ $this->assertTrue(in_array(array("data1" => array("attributes" => array('attr' => 'bidule'), "value1")), $xml_clientdata->get_nodes("//data1")));
446
+ $this->assertTrue(in_array(array("data1" => array("k" => "v")), $xml_clientdata->get_nodes("//data1")));
447
+ }
448
+
449
+ /**
450
+ * @expectedException AfsNoResultException
451
+ */
452
+ public function testXmlCltDataNoElementFoundGetNode() {
453
+ $xml_client_data = '<clientData><data1>value1</data1><data1><k>v</k></data1></clientData>';
454
+ $input = json_decode('
455
+ {
456
+ "contents": "' . $xml_client_data . '",
457
+ "id": "id1",
458
+ "mimeType": "application/json"
459
+ }');
460
+
461
+ $xml_clientdata = new AfsXmlClientDataHelper($input);
462
+ $xml_clientdata->get_node("/foo");
463
+ }
464
+
465
+ /**
466
+ * @expectedException AfsNoResultException
467
+ */
468
+ public function testXmlCltDataNoElementFoundgetNodes() {
469
+ $xml_client_data = '<clientData><data1>value1</data1><data1><k>v</k></data1></clientData>';
470
+ $input = json_decode('
471
+ {
472
+ "contents": "' . $xml_client_data . '",
473
+ "id": "id1",
474
+ "mimeType": "application/json"
475
+ }');
476
+
477
+ $xml_clientdata = new AfsXmlClientDataHelper($input);
478
+ $xml_clientdata->get_node("/foo");
479
+ }
480
}
lib/antidot/AFS/SEARCH/TEST/facetHelperTest.php CHANGED
@@ -54,6 +54,94 @@ class FacetHelperTest extends PHPUnit_Framework_TestCase
54
$this->assertEquals(AfsFacetType::BOOL_TYPE, $helper->get_type());
55
$this->assertEquals(AfsFacetLayout::TREE, $helper->get_layout());
56
$this->assertEquals(false, $helper->is_sticky());
57
}
58
59
public function testRetrieveStickyness()
54
$this->assertEquals(AfsFacetType::BOOL_TYPE, $helper->get_type());
55
$this->assertEquals(AfsFacetLayout::TREE, $helper->get_layout());
56
$this->assertEquals(false, $helper->is_sticky());
57
+
58
+ $labels = $helper->get_labels();
59
+ $this->assertEquals(array("ES" => "Faceta booleana", "FR" => "Facette booléenne", "Boolean facet"), $labels);
60
+ }
61
+
62
+ public function testRetrieveLabelsWhenNoLabelsExists() {
63
+ $input = json_decode('{
64
+ "afs:t": "FacetTree",
65
+ "node": [
66
+ {
67
+ "key": "false",
68
+ "labels": [
69
+ {
70
+ "label": "BAD"
71
+ }
72
+ ],
73
+ "items": 67
74
+ }
75
+ ],
76
+ "layout": "TREE",
77
+ "type": "BOOL",
78
+ "id": "FOO",
79
+ "sticky": "true" }');
80
+
81
+ $config = new AfsHelperConfiguration();
82
+ $helper = new AfsFacetHelper($input, new AfsQuery(), $config);
83
+ $labels = $helper->get_labels();
84
+ $this->assertEquals(array("FOO"), $labels);
85
+ $this->assertEquals("FOO", $helper->get_label());
86
+ }
87
+
88
+ public function testRetrieveTags() {
89
+ $input = json_decode('{
90
+ "afs:t": "FacetTree",
91
+ "tags": "tag1 tag2 tag3",
92
+ "node": [
93
+ {
94
+ "key": "false",
95
+ "labels": [
96
+ {
97
+ "label": "BAD"
98
+ }
99
+ ],
100
+ "items": 67
101
+ }
102
+ ],
103
+ "layout": "TREE",
104
+ "type": "BOOL",
105
+ "id": "FOO",
106
+ "labels": [
107
+ {
108
+ "label": "String facet"
109
+ }
110
+ ],
111
+ "sticky": "true" }');
112
+
113
+ $config = new AfsHelperConfiguration();
114
+ $helper = new AfsFacetHelper($input, new AfsQuery(), $config);
115
+ $this->assertEquals(array('tag1', 'tag2', 'tag3'), $helper->get_tags());
116
+ }
117
+
118
+ public function testNotags() {
119
+ $input = json_decode('{
120
+ "afs:t": "FacetTree",
121
+ "node": [
122
+ {
123
+ "key": "false",
124
+ "labels": [
125
+ {
126
+ "label": "BAD"
127
+ }
128
+ ],
129
+ "items": 67
130
+ }
131
+ ],
132
+ "layout": "TREE",
133
+ "type": "BOOL",
134
+ "id": "FOO",
135
+ "labels": [
136
+ {
137
+ "label": "String facet"
138
+ }
139
+ ],
140
+ "sticky": "true" }');
141
+
142
+ $config = new AfsHelperConfiguration();
143
+ $helper = new AfsFacetHelper($input, new AfsQuery(), $config);
144
+ $this->assertEquals(array(), $helper->get_tags());
145
}
146
147
public function testRetrieveStickyness()
lib/antidot/AFS/SEARCH/TEST/facetTest.php CHANGED
@@ -15,6 +15,27 @@ class FacetTest extends PHPUnit_Framework_TestCase
15
$this->assertFalse($facet->has_single_mode());
16
}
17
18
public function testFailOnBadTypeValue()
19
{
20
try {
15
$this->assertFalse($facet->has_single_mode());
16
}
17
18
+ public function testFailOnBadIdentifier()
19
+ {
20
+ try {
21
+ $facet = new AfsFacet(NULL);
22
+ $this->fail('Should have failed on invalid identifier');
23
+ } catch (InvalidArgumentException $e) { }
24
+ try {
25
+ $facet = new AfsFacet('');
26
+ $this->fail('Should have failed on invalid identifier');
27
+ } catch (InvalidArgumentException $e) { }
28
+ try {
29
+ $facet = new AfsFacet('4foo');
30
+ $this->fail('Should have failed on invalid identifier');
31
+ } catch (InvalidArgumentException $e) { }
32
+ try {
33
+ $facet = new AfsFacet('foo bar');
34
+ $this->fail('Should have failed on invalid identifier');
35
+ } catch (InvalidArgumentException $e) { }
36
+
37
+ }
38
+
39
public function testFailOnBadTypeValue()
40
{
41
try {
lib/antidot/AFS/SEARCH/TEST/headerHelperTest.php CHANGED
@@ -1,81 +1,702 @@
1
<?php ob_start();
2
- require_once "AFS/SEARCH/afs_header_helper.php";
3
4
- class HeaderHelperTest extends PHPUnit_Framework_TestCase
5
{
6
- public function testError()
7
{
8
$input = json_decode('{
9
- "header": {
10
- "query": {
11
- "userId": "?",
12
- "sessionId": "?",
13
- "date": "2014-01-10T16:04:32+0000",
14
- "queryParam": [ ],
15
- "mainCtx": {
16
- "textQuery": ""
17
},
18
- "textQuery": ""
19
- },
20
- "user": {
21
- "requestMethod": "GET",
22
- "agent": "Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0 Iceweasel/24.0",
23
- "address": "10.61.8.236",
24
- "output": {
25
- "format": "JSON",
26
- "encoding": "gzip",
27
- "charset": "UTF-8"
28
- }
29
- },
30
- "info": { },
31
- "error": {
32
- "message": [
33
- "errorMsg"
34
- ]
35
- }
36
- }
37
- }');
38
- $header = new AfsHeaderHelper($input->header);
39
- $this->assertTrue($header->in_error());
40
- $this->assertEquals('errorMsg', $header->get_error());
41
- }
42
-
43
- public function testNotInError()
44
{
45
$input = json_decode('{
46
- "header": {
47
- "query": {
48
- "userId": "e3eddaff-5a3d-4807-8fb2-09e13baf78e1",
49
- "sessionId": "4c0f28d1-bb67-469b-86bf-54f83432914e",
50
- "date": "2014-01-10T16:17:44+0000",
51
- "queryParam": [ ],
52
- "mainCtx": {
53
- "textQuery": ""
54
},
55
- "textQuery": ""
56
- },
57
- "user": {
58
- "requestMethod": "GET",
59
- "agent": "Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Firefox/24.0 Iceweasel/24.0",
60
- "address": "10.61.8.236",
61
- "output": {
62
- "format": "JSON",
63
- "encoding": "gzip",
64
- "charset": "UTF-8"
65
- }
66
- },
67
- "performance": {
68
- "durationMs": 204
69
- },
70
- "info": { }
71
- }
72
- }');
73
- $header = new AfsHeaderHelper($input->header);
74
- $this->assertFalse($header->in_error());
75
- $this->assertEquals('e3eddaff-5a3d-4807-8fb2-09e13baf78e1', $header->get_user_id());
76
- $this->assertEquals('4c0f28d1-bb67-469b-86bf-54f83432914e', $header->get_session_id());
77
- $this->assertEquals(204, $header->get_duration());
78
- }
79
- }
80
81
1
<?php ob_start();
2
+ require_once "AFS/SEARCH/afs_facet_helper.php";
3
+ require_once "AFS/SEARCH/afs_query.php";
4
+ require_once "AFS/SEARCH/afs_response_helper.php";
5
6
+ class FacetHelperTest extends PHPUnit_Framework_TestCase
7
{
8
+ public function testRetrieveFacetLabel()
9
{
10
$input = json_decode('{
11
+ "afs:t": "FacetTree",
12
+ "node": [
13
+ {
14
+ "key": "false",
15
+ "labels": [
16
+ {
17
+ "label": "BAD"
18
+ }
19
+ ],
20
+ "items": 67
21
+ },
22
+ {
23
+ "key": "true",
24
+ "labels": [
25
+ {
26
+ "label": "GOOD"
27
+ }
28
+ ],
29
+ "items": 133
30
+ }
31
+ ],
32
+ "layout": "TREE",
33
+ "type": "BOOL",
34
+ "id": "BOOL",
35
+ "labels": [
36
+ {
37
+ "lang": "ES",
38
+ "region": "ES",
39
+ "label": "Faceta booleana"
40
+ },
41
+ {
42
+ "lang": "FR",
43
+ "label": "Facette booléenne"
44
+ },
45
+ {
46
+ "label": "Boolean facet"
47
+ }
48
+ ] }');
49
+
50
+ $config = new AfsHelperConfiguration();
51
+ $helper = new AfsFacetHelper($input, new AfsQuery(), $config);
52
+ $this->assertEquals($helper->get_label(), "Faceta booleana");
53
+ $this->assertEquals('BOOL', $helper->get_id());
54
+ $this->assertEquals(AfsFacetType::BOOL_TYPE, $helper->get_type());
55
+ $this->assertEquals(AfsFacetLayout::TREE, $helper->get_layout());
56
+ $this->assertEquals(false, $helper->is_sticky());
57
+
58
+ $labels = $helper->get_labels();
59
+ $this->assertEquals(array("es" => "Faceta booleana", "fr" => "Facette booléenne", "Boolean facet"), $labels);
60
+ }
61
+
62
+ public function testRetrieveLabelsWhenNoLabelsExists() {
63
+ $input = json_decode('{
64
+ "afs:t": "FacetTree",
65
+ "node": [
66
+ {
67
+ "key": "false",
68
+ "labels": [
69
+ {
70
+ "label": "BAD"
71
+ }
72
+ ],
73
+ "items": 67
74
+ }
75
+ ],
76
+ "layout": "TREE",
77
+ "type": "BOOL",
78
+ "id": "FOO",
79
+ "sticky": "true" }');
80
+
81
+ $config = new AfsHelperConfiguration();
82
+ $helper = new AfsFacetHelper($input, new AfsQuery(), $config);
83
+ $labels = $helper->get_labels();
84
+ $this->assertEquals(array("FOO"), $labels);
85
+ $this->assertEquals("FOO", $helper->get_label());
86
+ }
87
+
88
+ public function testRetrieveTags() {
89
+ $input = json_decode('{
90
+ "afs:t": "FacetTree",
91
+ "tags": "tag1 tag2 tag3",
92
+ "node": [
93
+ {
94
+ "key": "false",
95
+ "labels": [
96
+ {
97
+ "label": "BAD"
98
+ }
99
+ ],
100
+ "items": 67
101
+ }
102
+ ],
103
+ "layout": "TREE",
104
+ "type": "BOOL",
105
+ "id": "FOO",
106
+ "labels": [
107
+ {
108
+ "label": "String facet"
109
+ }
110
+ ],
111
+ "sticky": "true" }');
112
+
113
+ $config = new AfsHelperConfiguration();
114
+ $helper = new AfsFacetHelper($input, new AfsQuery(), $config);
115
+ $this->assertEquals(array('tag1', 'tag2', 'tag3'), $helper->get_tags());
116
+ }
117
+
118
+ public function testNotags() {
119
+ $input = json_decode('{
120
+ "afs:t": "FacetTree",
121
+ "node": [
122
+ {
123
+ "key": "false",
124
+ "labels": [
125
+ {
126
+ "label": "BAD"
127
+ }
128
+ ],
129
+ "items": 67
130
+ }
131
+ ],
132
+ "layout": "TREE",
133
+ "type": "BOOL",
134
+ "id": "FOO",
135
+ "labels": [
136
+ {
137
+ "label": "String facet"
138
+ }
139
+ ],
140
+ "sticky": "true" }');
141
+
142
+ $config = new AfsHelperConfiguration();
143
+ $helper = new AfsFacetHelper($input, new AfsQuery(), $config);
144
+ $this->assertEquals(array(), $helper->get_tags());
145
+ }
146
+
147
+ public function testRetrieveStickyness()
148
+ {
149
+ $input = json_decode('{
150
+ "afs:t": "FacetTree",
151
+ "node": [
152
+ {
153
+ "key": "false",
154
+ "labels": [
155
+ {
156
+ "label": "BAD"
157
+ }
158
+ ],
159
+ "items": 67
160
+ }
161
+ ],
162
+ "layout": "TREE",
163
+ "type": "BOOL",
164
+ "id": "FOO",
165
+ "labels": [
166
+ {
167
+ "label": "String facet"
168
+ }
169
+ ],
170
+ "sticky": "true" }');
171
+
172
+ $config = new AfsHelperConfiguration();
173
+ $helper = new AfsFacetHelper($input, new AfsQuery(), $config);
174
+ $this->assertEquals($helper->get_label(), "String facet");
175
+ $this->assertEquals('FOO', $helper->get_id());
176
+ $this->assertEquals(AfsFacetType::BOOL_TYPE, $helper->get_type());
177
+ $this->assertEquals(AfsFacetLayout::TREE, $helper->get_layout());
178
+ $this->assertEquals(true, $helper->is_sticky());
179
+ }
180
+
181
+ public function testFacetValueNoMetaAvailable()
182
+ {
183
+ $input = json_decode('{
184
+ "afs:t": "FacetTree",
185
+ "node": [ {
186
+ "key": "false",
187
+ "labels": [ { "label": "BAD" } ],
188
+ "items": 67
189
+ } ],
190
+ "layout": "TREE",
191
+ "type": "BOOL",
192
+ "id": "BOOL",
193
+ "labels": [ { "label": "Boolean facet" } ] }');
194
+
195
+ $config = new AfsHelperConfiguration();
196
+ $config->set_helper_format(AfsHelperFormat::HELPERS);
197
+ $helper = new AfsFacetHelper($input, new AfsQuery(), $config);
198
+ $elems = $helper->get_elements();
199
+ $this->assertEquals(1, count($elems));
200
+ $this->assertEquals(0, count($elems[0]->get_meta()));
201
+ }
202
+
203
+ public function testFacetValueOneMetaAvailable()
204
+ {
205
+ $input = json_decode('{
206
+ "afs:t": "FacetTree",
207
+ "node": [ {
208
+ "key": "false",
209
+ "labels": [ { "label": "BAD" } ],
210
+ "items": 67,
211
+ "meta": [ {
212
+ "key": "meta_id",
213
+ "value": "meta_value"
214
+ } ]
215
+ } ],
216
+ "layout": "TREE",
217
+ "type": "BOOL",
218
+ "id": "BOOL",
219
+ "labels": [ { "label": "Boolean facet" } ]
220
+ }');
221
+
222
+ $config = new AfsHelperConfiguration();
223
+ $config->set_helper_format(AfsHelperFormat::HELPERS);
224
+ $helper = new AfsFacetHelper($input, new AfsQuery(), $config);
225
+ $elems = $helper->get_elements();
226
+
227
+ $this->assertEquals(1, count($elems));
228
+ $metas = $elems[0]->get_meta();
229
+ $this->assertEquals(1, count($metas));
230
+ foreach ($metas as $meta_key => $meta_value) {
231
+ $this->assertEquals('meta_id', $meta_key);
232
+ $this->assertEquals('meta_value', $meta_value);
233
+ }
234
+ $this->assertEquals('meta_value', $elems[0]->get_meta('meta_id'));
235
+ }
236
+
237
+ public function testFacetValueMultipleMetaAvailable()
238
+ {
239
+ $input = json_decode('{
240
+ "afs:t": "FacetTree",
241
+ "node": [ {
242
+ "key": "false",
243
+ "labels": [ { "label": "BAD" } ],
244
+ "items": 67,
245
+ "meta": [
246
+ {
247
+ "key": "meta_id_1",
248
+ "value": "meta_value_1"
249
},
250
+ {
251
+ "key": "meta_id_2",
252
+ "value": "meta_value_2"
253
+ } ]
254
+ } ],
255
+ "layout": "TREE",
256
+ "type": "BOOL",
257
+ "id": "BOOL",
258
+ "labels": [ { "label": "Boolean facet" } ]
259
+ }');
260
+
261
+ $config = new AfsHelperConfiguration();
262
+ $config->set_helper_format(AfsHelperFormat::HELPERS);
263
+ $helper = new AfsFacetHelper($input, new AfsQuery(), $config);
264
+ $elems = $helper->get_elements();
265
+
266
+ $this->assertEquals(1, count($elems));
267
+ $metas = $elems[0]->get_meta();
268
+ $this->assertEquals(2, count($metas));
269
+ for ($i = 1; $i < 2; $i++) {
270
+ $res = each($metas);
271
+ $this->assertEquals('meta_id_' . $i, $res['key']);
272
+ $this->assertEquals('meta_value_' . $i, $res['value']);
273
+ }
274
+ $this->assertEquals('meta_value_1', $elems[0]->get_meta('meta_id_1'));
275
+ $this->assertEquals('meta_value_2', $elems[0]->get_meta('meta_id_2'));
276
+ }
277
+
278
+ public function testFacetValueWrongMetaRequested()
279
+ {
280
+ $input = json_decode('{
281
+ "afs:t": "FacetTree",
282
+ "node": [ {
283
+ "key": "false",
284
+ "labels": [ { "label": "BAD" } ],
285
+ "items": 67,
286
+ "meta": [
287
+ {
288
+ "key": "meta_id_1",
289
+ "value": "meta_value_1"
290
+ },
291
+ {
292
+ "key": "meta_id_2",
293
+ "value": "meta_value_2"
294
+ } ]
295
+ } ],
296
+ "layout": "TREE",
297
+ "type": "BOOL",
298
+ "id": "BOOL",
299
+ "labels": [ { "label": "Boolean facet" } ]
300
+ }');
301
+
302
+ $config = new AfsHelperConfiguration();
303
+ $config->set_helper_format(AfsHelperFormat::HELPERS);
304
+ $helper = new AfsFacetHelper($input, new AfsQuery(), $config);
305
+ $elems = $helper->get_elements();
306
+
307
+ $this->assertEquals(1, count($elems));
308
+ $metas = $elems[0]->get_meta();
309
+ $this->assertEquals(2, count($metas));
310
+ try {
311
+ $elems[0]->get_meta('unknown_meta_id');
312
+ $this->fail('Should have raised an exception on unknown meta id');
313
+ } catch (OutOfBoundsException $e) { }
314
+ }
315
+
316
+ public function testFacetValueMultipleMetaAvailableInArrayFormat()
317
{
318
$input = json_decode('{
319
+ "afs:t": "FacetTree",
320
+ "node": [ {
321
+ "key": "false",
322
+ "labels": [ { "label": "BAD" } ],
323
+ "items": 67,
324
+ "meta": [
325
+ {
326
+ "key": "meta_id_1",
327
+ "value": "meta_value_1"
328
},
329
+ {
330
+ "key": "meta_id_2",
331
+ "value": "meta_value_2"
332
+ } ]
333
+ } ],
334
+ "layout": "TREE",
335
+ "type": "BOOL",
336
+ "id": "BOOL",
337
+ "labels": [ { "label": "Boolean facet" } ]
338
+ }');
339
340
+ $config = new AfsHelperConfiguration();
341
+ $helper = new AfsFacetHelper($input, new AfsQuery(), $config);
342
+ $elems = $helper->get_elements();
343
344
+ $this->assertEquals(1, count($elems));
345
+ $metas = $elems[0]->meta;
346
+ $this->assertEquals(2, count($metas));
347
+ for ($i = 1; $i < 2; $i++) {
348
+ $res = each($metas);
349
+ $this->assertEquals('meta_id_' . $i, $res['key']);
350
+ $this->assertEquals('meta_value_' . $i, $res['value']);
351
+ }
352
+ }
353
+
354
+
355
+ public function testFacetElementBuilderOnInterval()
356
+ {
357
+ $input = json_decode('{
358
+ "afs:t": "FacetInterval",
359
+ "interval": [
360
+ {
361
+ "key": "[\"2009-10-02\" .. \"2013-10-01\"[",
362
+ "items": 109
363
+ },
364
+ {
365
+ "key": "[\"2010-10-02\" .. \"2013-10-01\"[",
366
+ "items": 97
367
+ }
368
+ ],
369
+ "layout": "INTERVAL",
370
+ "type": "DATE",
371
+ "id": "ADVANCED_INTERVAL_DATE",
372
+ "labels": [
373
+ {
374
+ "label": "Advanced date interval"
375
+ }
376
+ ]
377
+ }');
378
+
379
+ $query = new AfsQuery();
380
+ $config = new AfsHelperConfiguration();
381
+ $config->set_helper_format(AfsHelperFormat::HELPERS);
382
+ $facet_mgr = $query->get_facet_manager();
383
+ $facet_mgr->add_facet(new AfsFacet('ADVANCED_INTERVAL_DATE', AfsFacetType::DATE_TYPE, AfsFacetLayout::INTERVAL));
384
+ $builder = new AfsFacetElementBuilder($facet_mgr, $query);
385
+ $elems = $builder->create_elements('ADVANCED_INTERVAL_DATE', $input, $config);
386
+
387
+ $this->assertEquals(count($elems), 2);
388
+ $elem = reset($elems);
389
+ $this->assertEquals($elem->label, '["2009-10-02" .. "2013-10-01"[');
390
+ $this->assertEquals('["2009-10-02" .. "2013-10-01"[', $elem->key);
391
+ $this->assertEquals($elem->count, 109);
392
+ $this->assertFalse($elem->active);
393
+ $this->assertTrue($elem->query->has_filter('ADVANCED_INTERVAL_DATE', '["2009-10-02" .. "2013-10-01"['));
394
+ $this->assertEquals(count($elem->values), 0);
395
+ next($elems);
396
+ $elem = current($elems);
397
+ $this->assertEquals($elem->label, '["2010-10-02" .. "2013-10-01"[');
398
+ $this->assertEquals('["2010-10-02" .. "2013-10-01"[', $elem->key);
399
+ $this->assertEquals($elem->count, 97);
400
+ $this->assertFalse($elem->active);
401
+ $this->assertTrue($elem->query->has_filter('ADVANCED_INTERVAL_DATE', '["2010-10-02" .. "2013-10-01"['));
402
+ $this->assertEquals(count($elem->values), 0);
403
+ }
404
+
405
+ public function testFacetElementBuilderOnNode()
406
+ {
407
+ $input = json_decode('{
408
+ "afs:t": "FacetTree",
409
+ "node": [
410
+ {
411
+ "key": "false",
412
+ "labels": [
413
+ {
414
+ "label": "BAD"
415
+ }
416
+ ],
417
+ "items": 67
418
+ },
419
+ {
420
+ "key": "true",
421
+ "labels": [
422
+ {
423
+ "label": "GOOD"
424
+ }
425
+ ],
426
+ "items": 133
427
+ }
428
+ ],
429
+ "layout": "TREE",
430
+ "type": "BOOL",
431
+ "id": "BOOL",
432
+ "labels": [
433
+ {
434
+ "label": "Boolean facet"
435
+ }
436
+ ]
437
+ }');
438
+
439
+ $query = new AfsQuery();
440
+ $config = new AfsHelperConfiguration();
441
+ $config->set_helper_format(AfsHelperFormat::HELPERS);
442
+ $facet_mgr = $query->get_facet_manager();
443
+ $facet_mgr->add_facet(new AfsFacet('BOOL', AfsFacetType::BOOL_TYPE));
444
+ $builder = new AfsFacetElementBuilder($facet_mgr, $query);
445
+ $elems = $builder->create_elements('BOOL', $input, $config);
446
+
447
+ $this->assertEquals(count($elems), 2);
448
+ $elem = reset($elems);
449
+ $this->assertEquals($elem->label, 'BAD');
450
+ $this->assertEquals($elem->count, 67);
451
+ $this->assertFalse($elem->active);
452
+ $this->assertTrue($elem->query->has_filter('BOOL', 'false'));