algoliasearch - Version 1.4.6

Version Notes

- UPDATED: Price handling, no template update required anymore + correct handling of special price + correct handling of tax
- UPDATED: indexing process has been optimized
- FIX: add emulation for pages to have correct urls
- UPDATED: Separate category and product indexer

Download this release

Release Info

Developer Algolia Team
Extension algoliasearch
Version 1.4.6
Comparing to
See all releases


Code changes from version 1.4.5 to 1.4.6

app/code/community/Algolia/Algoliasearch/Helper/Config.php CHANGED
@@ -2,55 +2,54 @@
2
 
3
  class Algolia_Algoliasearch_Helper_Config extends Mage_Core_Helper_Abstract
4
  {
5
- const XML_PATH_MINIMAL_QUERY_LENGTH = 'algoliasearch/ui/minimal_query_length';
6
- const XML_PATH_SEARCH_DELAY = 'algoliasearch/ui/search_delay';
7
-
8
- const XML_PATH_IS_POPUP_ENABLED = 'algoliasearch/credentials/is_popup_enabled';
9
- const XML_PATH_APPLICATION_ID = 'algoliasearch/credentials/application_id';
10
- const XML_PATH_API_KEY = 'algoliasearch/credentials/api_key';
11
- const XML_PATH_SEARCH_ONLY_API_KEY = 'algoliasearch/credentials/search_only_api_key';
12
- const XML_PATH_INDEX_PREFIX = 'algoliasearch/credentials/index_prefix';
13
- const XML_PATH_IS_INSTANT_ENABLED = 'algoliasearch/credentials/is_instant_enabled';
14
-
15
- const XML_PATH_REPLACE_CATEGORIES = 'algoliasearch/instant/replace_categories';
16
- const XML_PATH_INSTANT_SELECTOR = 'algoliasearch/instant/instant_selector';
17
- const XML_PATH_FACETS = 'algoliasearch/instant/facets';
18
- const XML_PATH_SORTING_INDICES = 'algoliasearch/instant/sorts';
19
-
20
- const XML_PATH_AUTOCOMPLETE_ADD_SECTIONS = 'algoliasearch/autocomplete/additional_sections';
21
-
22
- const XML_PATH_PRODUCT_ATTRIBUTES = 'algoliasearch/products/product_additional_attributes';
23
- const XML_PATH_PRODUCT_CUSTOM_RANKING = 'algoliasearch/products/custom_ranking_product_attributes';
24
- const XML_PATH_RESULTS_LIMIT = 'algoliasearch/products/results_limit';
25
-
26
- const XML_PATH_CATEGORY_ATTRIBUTES = 'algoliasearch/categories/category_additional_attributes2';
27
- const XML_PATH_INDEX_PRODUCT_COUNT = 'algoliasearch/categories/index_product_count';
28
- const XML_PATH_CATEGORY_CUSTOM_RANKING = 'algoliasearch/categories/custom_ranking_category_attributes';
29
-
30
- const XML_PATH_EXCLUDED_PAGES = 'algoliasearch/pages/excluded_pages';
31
-
32
- const XML_PATH_MIN_POPULARITY = 'algoliasearch/suggestions/min_popularity';
33
- const XML_PATH_MIN_NUMBER_OF_RESULTS = 'algoliasearch/suggestions/min_number_of_results';
34
-
35
- const XML_PATH_REMOVE_IF_NO_RESULT = 'algoliasearch/relevance/remove_words_if_no_result';
36
-
37
- const XML_PATH_NUMBER_OF_PRODUCT_SUGGESTIONS = 'algoliasearch/ui/number_product_suggestions';
38
- const XML_PATH_NUMBER_OF_PRODUCT_RESULTS = 'algoliasearch/ui/number_product_results';
39
- const XML_PATH_NUMBER_OF_CATEGORY_SUGGESTIONS = 'algoliasearch/ui/number_category_suggestions';
40
- const XML_PATH_NUMBER_OF_PAGE_SUGGESTIONS = 'algoliasearch/ui/number_page_suggestions';
41
- const XML_PATH_NUMBER_QUERY_SUGGESTIONS = 'algoliasearch/ui/number_query_suggestions';
42
- const XML_PATH_MAX_VALUES_PER_FACET = 'algoliasearch/ui/max_values_per_facet';
43
- const XML_PATH_REMOVE_BRANDING = 'algoliasearch/ui/remove_branding';
44
- const XML_ADD_TO_CART_ENABLE = 'algoliasearch/ui/add_to_cart_enable';
45
-
46
- const XML_PATH_MAX_RETRIES = 'algoliasearch/queue/retries';
47
- const XML_PATH_IS_ACTIVE = 'algoliasearch/queue/active';
48
- const XML_PATH_NUMBER_OF_ELEMENT_BY_PAGE = 'algoliasearch/queue/number_of_element_by_page';
49
- const XML_PATH_NUMBER_OF_JOB_TO_RUN = 'algoliasearch/queue/number_of_job_to_run';
50
- const XML_PATH_NO_PROCESS = 'algoliasearch/queue/noprocess';
51
-
52
- const XML_PATH_PARTIAL_UPDATES = 'algoliasearch/advanced/partial_update';
53
- const XML_PATH_CUSTOMER_GROUPS_ENABLE = 'algoliasearch/advanced/customer_groups_enable';
54
 
55
  public function noProcess($storeId = null)
56
  {
@@ -134,22 +133,22 @@ class Algolia_Algoliasearch_Helper_Config extends Mage_Core_Helper_Abstract
134
 
135
  public function getNumberOfProductSuggestions($storeId = NULL)
136
  {
137
- return Mage::getStoreConfig(self::XML_PATH_NUMBER_OF_PRODUCT_SUGGESTIONS, $storeId);
138
  }
139
 
140
  public function getNumberOfProductResults($storeId = NULL)
141
  {
142
- return Mage::getStoreConfig(self::XML_PATH_NUMBER_OF_PRODUCT_RESULTS, $storeId);
143
  }
144
 
145
  public function getNumberOfCategorySuggestions($storeId = NULL)
146
  {
147
- return Mage::getStoreConfig(self::XML_PATH_NUMBER_OF_CATEGORY_SUGGESTIONS, $storeId);
148
  }
149
 
150
  public function getNumberOfPageSuggestions($storeId = NULL)
151
  {
152
- return Mage::getStoreConfig(self::XML_PATH_NUMBER_OF_PAGE_SUGGESTIONS, $storeId);
153
  }
154
 
155
  public function getResultsLimit($storeId = NULL)
@@ -208,11 +207,18 @@ class Algolia_Algoliasearch_Helper_Config extends Mage_Core_Helper_Abstract
208
  {
209
  $suffix_index_name = 'group_' . $group_id;
210
 
211
- $attr['index_name'] = $product_helper->getIndexName($storeId) . '_' . $suffix_index_name . '_' .$attr['attribute'].'_'.$attr['sort'];
212
  }
 
 
213
  }
214
  else
215
- $attr['index_name'] = $product_helper->getIndexName($storeId) . '_' . 'default' . '_' .$attr['attribute'].'_'.$attr['sort'];
 
 
 
 
 
216
  }
217
 
218
  if (is_array($attrs))
2
 
3
  class Algolia_Algoliasearch_Helper_Config extends Mage_Core_Helper_Abstract
4
  {
5
+ const XML_PATH_MINIMAL_QUERY_LENGTH = 'algoliasearch/ui/minimal_query_length';
6
+ const XML_PATH_SEARCH_DELAY = 'algoliasearch/ui/search_delay';
7
+
8
+ const XML_PATH_IS_POPUP_ENABLED = 'algoliasearch/credentials/is_popup_enabled';
9
+ const XML_PATH_APPLICATION_ID = 'algoliasearch/credentials/application_id';
10
+ const XML_PATH_API_KEY = 'algoliasearch/credentials/api_key';
11
+ const XML_PATH_SEARCH_ONLY_API_KEY = 'algoliasearch/credentials/search_only_api_key';
12
+ const XML_PATH_INDEX_PREFIX = 'algoliasearch/credentials/index_prefix';
13
+ const XML_PATH_IS_INSTANT_ENABLED = 'algoliasearch/credentials/is_instant_enabled';
14
+
15
+ const XML_PATH_REPLACE_CATEGORIES = 'algoliasearch/instant/replace_categories';
16
+ const XML_PATH_INSTANT_SELECTOR = 'algoliasearch/instant/instant_selector';
17
+ const XML_PATH_FACETS = 'algoliasearch/instant/facets';
18
+ const XML_PATH_MAX_VALUES_PER_FACET = 'algoliasearch/instant/max_values_per_facet';
19
+ const XML_PATH_SORTING_INDICES = 'algoliasearch/instant/sorts';
20
+ const XML_ADD_TO_CART_ENABLE = 'algoliasearch/instant/add_to_cart_enable';
21
+
22
+ const XML_PATH_AUTOCOMPLETE_ADD_SECTIONS = 'algoliasearch/autocomplete/additional_sections';
23
+
24
+ const XML_PATH_NUMBER_OF_PRODUCT_SUGGESTIONS = 'algoliasearch/products/number_product_suggestions';
25
+ const XML_PATH_NUMBER_OF_PRODUCT_RESULTS = 'algoliasearch/products/number_product_results';
26
+ const XML_PATH_PRODUCT_ATTRIBUTES = 'algoliasearch/products/product_additional_attributes';
27
+ const XML_PATH_PRODUCT_CUSTOM_RANKING = 'algoliasearch/products/custom_ranking_product_attributes';
28
+ const XML_PATH_RESULTS_LIMIT = 'algoliasearch/products/results_limit';
29
+
30
+ const XML_PATH_NUMBER_OF_CATEGORY_SUGGESTIONS = 'algoliasearch/categories/number_category_suggestions';
31
+ const XML_PATH_CATEGORY_ATTRIBUTES = 'algoliasearch/categories/category_additional_attributes2';
32
+ const XML_PATH_INDEX_PRODUCT_COUNT = 'algoliasearch/categories/index_product_count';
33
+ const XML_PATH_CATEGORY_CUSTOM_RANKING = 'algoliasearch/categories/custom_ranking_category_attributes';
34
+
35
+ const XML_PATH_NUMBER_OF_PAGE_SUGGESTIONS = 'algoliasearch/pages/number_page_suggestions';
36
+ const XML_PATH_EXCLUDED_PAGES = 'algoliasearch/pages/excluded_pages';
37
+
38
+ const XML_PATH_NUMBER_QUERY_SUGGESTIONS = 'algoliasearch/suggestions/number_query_suggestions';
39
+ const XML_PATH_MIN_POPULARITY = 'algoliasearch/suggestions/min_popularity';
40
+ const XML_PATH_MIN_NUMBER_OF_RESULTS = 'algoliasearch/suggestions/min_number_of_results';
41
+
42
+ const XML_PATH_REMOVE_IF_NO_RESULT = 'algoliasearch/relevance/remove_words_if_no_result';
43
+
44
+ const XML_PATH_MAX_RETRIES = 'algoliasearch/queue/retries';
45
+ const XML_PATH_IS_ACTIVE = 'algoliasearch/queue/active';
46
+ const XML_PATH_NUMBER_OF_ELEMENT_BY_PAGE = 'algoliasearch/queue/number_of_element_by_page';
47
+ const XML_PATH_NUMBER_OF_JOB_TO_RUN = 'algoliasearch/queue/number_of_job_to_run';
48
+ const XML_PATH_NO_PROCESS = 'algoliasearch/queue/noprocess';
49
+
50
+ const XML_PATH_PARTIAL_UPDATES = 'algoliasearch/advanced/partial_update';
51
+ const XML_PATH_CUSTOMER_GROUPS_ENABLE = 'algoliasearch/advanced/customer_groups_enable';
52
+ const XML_PATH_REMOVE_BRANDING = 'algoliasearch/advanced/remove_branding';
 
53
 
54
  public function noProcess($storeId = null)
55
  {
133
 
134
  public function getNumberOfProductSuggestions($storeId = NULL)
135
  {
136
+ return (int) Mage::getStoreConfig(self::XML_PATH_NUMBER_OF_PRODUCT_SUGGESTIONS, $storeId);
137
  }
138
 
139
  public function getNumberOfProductResults($storeId = NULL)
140
  {
141
+ return (int) Mage::getStoreConfig(self::XML_PATH_NUMBER_OF_PRODUCT_RESULTS, $storeId);
142
  }
143
 
144
  public function getNumberOfCategorySuggestions($storeId = NULL)
145
  {
146
+ return (int) Mage::getStoreConfig(self::XML_PATH_NUMBER_OF_CATEGORY_SUGGESTIONS, $storeId);
147
  }
148
 
149
  public function getNumberOfPageSuggestions($storeId = NULL)
150
  {
151
+ return (int) Mage::getStoreConfig(self::XML_PATH_NUMBER_OF_PAGE_SUGGESTIONS, $storeId);
152
  }
153
 
154
  public function getResultsLimit($storeId = NULL)
207
  {
208
  $suffix_index_name = 'group_' . $group_id;
209
 
210
+ $attr['index_name'] = $product_helper->getIndexName($storeId) . '_' . $attr['attribute'] . '_' .$suffix_index_name.'_'.$attr['sort'];
211
  }
212
+ else
213
+ $attr['index_name'] = $product_helper->getIndexName($storeId). '_' .$attr['attribute'] . '_'.$attr['sort'];
214
  }
215
  else
216
+ {
217
+ if (strpos($attr['attribute'], 'price') !== false)
218
+ $attr['index_name'] = $product_helper->getIndexName($storeId). '_' .$attr['attribute'].'_' . 'default' . '_'.$attr['sort'];
219
+ else
220
+ $attr['index_name'] = $product_helper->getIndexName($storeId). '_' .$attr['attribute'] . '_'.$attr['sort'];
221
+ }
222
  }
223
 
224
  if (is_array($attrs))
app/code/community/Algolia/Algoliasearch/Helper/Data.php CHANGED
@@ -23,7 +23,7 @@ class Algolia_Algoliasearch_Helper_Data extends Mage_Core_Helper_Abstract
23
 
24
  public function __construct()
25
  {
26
- \AlgoliaSearch\Version::$custom_value = " Magento (1.4.5)";
27
 
28
  $this->algolia_helper = Mage::helper('algoliasearch/algoliahelper');
29
 
@@ -36,9 +36,13 @@ class Algolia_Algoliasearch_Helper_Data extends Mage_Core_Helper_Abstract
36
  $this->config = Mage::helper('algoliasearch/config');
37
  }
38
 
39
- public function deleteProductsAndCategoriesStoreIndices($storeId = null)
40
  {
41
  $this->algolia_helper->deleteIndex($this->product_helper->getIndexName($storeId));
 
 
 
 
42
  $this->algolia_helper->deleteIndex($this->category_helper->getIndexName($storeId));
43
  }
44
 
@@ -152,6 +156,8 @@ class Algolia_Algoliasearch_Helper_Data extends Mage_Core_Helper_Abstract
152
 
153
  public function rebuildStorePageIndex($storeId)
154
  {
 
 
155
  $index_name = $this->page_helper->getIndexName($storeId);
156
 
157
  $pages = $this->page_helper->getPages($storeId);
@@ -162,6 +168,8 @@ class Algolia_Algoliasearch_Helper_Data extends Mage_Core_Helper_Abstract
162
  $this->algolia_helper->moveIndex($index_name.'_tmp', $index_name);
163
 
164
  $this->algolia_helper->setSettings($index_name, $this->page_helper->getIndexSettings($storeId));
 
 
165
  }
166
 
167
  public function rebuildStoreCategoryIndex($storeId, $categoryIds = null)
@@ -361,9 +369,12 @@ class Algolia_Algoliasearch_Helper_Data extends Mage_Core_Helper_Abstract
361
 
362
  $collection = clone $collectionDefault;
363
  $collection->setCurPage($page)->setPageSize($pageSize);
364
- $collection->load();
365
  $collection->addCategoryIds();
366
  $collection->addUrlRewrite();
 
 
 
 
367
 
368
  $index_name = $this->product_helper->getIndexName($storeId);
369
 
23
 
24
  public function __construct()
25
  {
26
+ \AlgoliaSearch\Version::$custom_value = " Magento (1.4.6)";
27
 
28
  $this->algolia_helper = Mage::helper('algoliasearch/algoliahelper');
29
 
36
  $this->config = Mage::helper('algoliasearch/config');
37
  }
38
 
39
+ public function deleteProductsStoreIndices($storeId = null)
40
  {
41
  $this->algolia_helper->deleteIndex($this->product_helper->getIndexName($storeId));
42
+ }
43
+
44
+ public function deleteCategoriesStoreIndices($storeId = null)
45
+ {
46
  $this->algolia_helper->deleteIndex($this->category_helper->getIndexName($storeId));
47
  }
48
 
156
 
157
  public function rebuildStorePageIndex($storeId)
158
  {
159
+ $emulationInfo = $this->startEmulation($storeId);
160
+
161
  $index_name = $this->page_helper->getIndexName($storeId);
162
 
163
  $pages = $this->page_helper->getPages($storeId);
168
  $this->algolia_helper->moveIndex($index_name.'_tmp', $index_name);
169
 
170
  $this->algolia_helper->setSettings($index_name, $this->page_helper->getIndexSettings($storeId));
171
+
172
+ $this->stopEmulation($emulationInfo);
173
  }
174
 
175
  public function rebuildStoreCategoryIndex($storeId, $categoryIds = null)
369
 
370
  $collection = clone $collectionDefault;
371
  $collection->setCurPage($page)->setPageSize($pageSize);
 
372
  $collection->addCategoryIds();
373
  $collection->addUrlRewrite();
374
+ $collection->joinField('stock_qty', 'cataloginventory/stock_item', 'qty', 'product_id=entity_id', '{{table}}.stock_id=1', 'left');
375
+ $collection->getSelect()->columns('sku, (SELECT SUM(qty_ordered) FROM sales_flat_order_item WHERE sales_flat_order_item.sku = e.sku) as ordered_qty');
376
+ $collection->getSelect()->columns('(SELECT rating_summary FROM review_entity_summary WHERE review_entity_summary.entity_pk_value = e.entity_id AND review_entity_summary.store_id='.$storeId.') as rating_summary');
377
+ $collection->load();
378
 
379
  $index_name = $this->product_helper->getIndexName($storeId);
380
 
app/code/community/Algolia/Algoliasearch/Helper/Entity/Helper.php CHANGED
@@ -68,17 +68,6 @@ abstract class Algolia_Algoliasearch_Helper_Entity_Helper
68
  return trim(strip_tags($s));
69
  }
70
 
71
- public function getProductActiveCategories(Mage_Catalog_Model_Product $product, $storeId = null)
72
- {
73
- $activeCategories = array();
74
-
75
- foreach ($product->getCategoryIds() as $categoryId)
76
- if ($this->isCategoryActive($categoryId, $storeId))
77
- $activeCategories[] = $categoryId;
78
-
79
- return $activeCategories;
80
- }
81
-
82
  public function isCategoryActive($categoryId, $storeId = null)
83
  {
84
  $storeId = intval($storeId);
68
  return trim(strip_tags($s));
69
  }
70
 
 
 
 
 
 
 
 
 
 
 
 
71
  public function isCategoryActive($categoryId, $storeId = null)
72
  {
73
  $storeId = intval($storeId);
app/code/community/Algolia/Algoliasearch/Helper/Entity/Producthelper.php CHANGED
@@ -22,7 +22,7 @@ class Algolia_Algoliasearch_Helper_Entity_Producthelper extends Algolia_Algolias
22
 
23
  $allAttributes = $config->getEntityAttributeCodes('catalog_product');
24
 
25
- $productAttributes = array_merge(array('name', 'path', 'categories', 'categories_without_path', 'description', 'ordered_qty', 'stock_qty', 'price_with_tax', 'rating_summary'), $allAttributes);
26
 
27
  $excludedAttributes = array(
28
  'all_children', 'available_sort_by', 'children', 'children_count', 'custom_apply_to_products',
@@ -53,13 +53,13 @@ class Algolia_Algoliasearch_Helper_Entity_Producthelper extends Algolia_Algolias
53
  protected function isAttributeEnabled($additionalAttributes, $attr_name)
54
  {
55
  foreach ($additionalAttributes as $attr)
56
- if ($attr['attribute'] == $attr_name)
57
  return true;
58
 
59
  return false;
60
  }
61
 
62
- public function getProductCollectionQuery($storeId, $productIds = null, $only_visible = true)
63
  {
64
  /** @var $products Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection */
65
  $products = Mage::getResourceModel('catalog/product_collection');
@@ -77,10 +77,13 @@ class Algolia_Algoliasearch_Helper_Entity_Producthelper extends Algolia_Algolias
77
 
78
  $additionalAttr = $this->config->getProductAdditionalAttributes($storeId);
79
 
80
- foreach ($additionalAttr as &$attr)
81
- $attr = $attr['attribute'];
 
 
82
 
83
- $products = $products->addAttributeToSelect(array_values(array_merge(static::$_predefinedProductAttributes, $additionalAttr)));
 
84
 
85
  if ($productIds && count($productIds) > 0)
86
  $products = $products->addAttributeToFilter('entity_id', array('in' => $productIds));
@@ -117,7 +120,25 @@ class Algolia_Algoliasearch_Helper_Entity_Producthelper extends Algolia_Algolias
117
  $facets = $this->config->getFacets();
118
 
119
  foreach($facets as $facet)
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
120
  $attributesForFaceting[] = $facet['attribute'];
 
 
121
 
122
  foreach ($customRankings as $ranking)
123
  $customRankingsArr[] = $ranking['order'] . '(' . $ranking['attribute'] . ')';
@@ -153,7 +174,7 @@ class Algolia_Algoliasearch_Helper_Entity_Producthelper extends Algolia_Algolias
153
  {
154
  if ($this->config->isCustomerGroupsEnabled($storeId))
155
  {
156
- if (strpos($values['attribute'], 'price') !== false)
157
  {
158
  foreach ($groups = Mage::getModel('customer/group')->getCollection() as $group)
159
  {
@@ -161,13 +182,16 @@ class Algolia_Algoliasearch_Helper_Entity_Producthelper extends Algolia_Algolias
161
 
162
  $suffix_index_name = 'group_' . $group_id;
163
 
164
- $slaves[] = $this->getIndexName($storeId) . '_' . $suffix_index_name . '_' .$values['attribute'].'_'.$values['sort'];
165
  }
166
  }
167
  }
168
  else
169
  {
170
- $slaves[] = $this->getIndexName($storeId) . '_' . 'default' . '_' .$values['attribute'].'_'.$values['sort'];
 
 
 
171
  }
172
  }
173
 
@@ -183,12 +207,13 @@ class Algolia_Algoliasearch_Helper_Entity_Producthelper extends Algolia_Algolias
183
  {
184
  $group_id = (int)$group->getData('customer_group_id');
185
 
186
- $suffix_index_name = '_group_' . $group_id;
 
 
187
 
188
- $sort_attribute = strpos($values['attribute'], 'price') !== false ? $values['attribute'].'.'.$group_id : $values['attribute'];
189
  $mergeSettings['ranking'] = array($values['sort'].'('.$sort_attribute.')', 'typo', 'geo', 'words', 'proximity', 'attribute', 'exact', 'custom');
190
 
191
- $this->algolia_helper->setSettings($this->getIndexName($storeId).$suffix_index_name.'_'.$values['attribute'].'_'.$values['sort'], $mergeSettings);
192
  }
193
  }
194
  }
@@ -198,57 +223,149 @@ class Algolia_Algoliasearch_Helper_Entity_Producthelper extends Algolia_Algolias
198
 
199
  $mergeSettings['ranking'] = array($values['sort'].'('.$sort_attribute.')', 'typo', 'geo', 'words', 'proximity', 'attribute', 'exact', 'custom');
200
 
201
- $this->algolia_helper->setSettings($this->getIndexName($storeId) . '_' . 'default' . '_' .$values['attribute'].'_'.$values['sort'], $mergeSettings);
202
  }
203
  }
204
  }
205
  }
206
 
207
- private function handlePrice(&$product, &$customData, $group_id = null)
208
  {
209
- $key = $group_id === null ? 'default' : $group_id;
 
 
 
 
 
 
 
 
 
210
 
211
- $customData['price'][$key] = (double) $product->getPrice();
212
- $customData['price_with_tax'][$key] = (double) Mage::helper('tax')->getPrice($product, $product->getPrice(), true, null, null, null, null, false);
 
 
213
 
214
  $special_price = null;
215
 
216
- if ($group_id !== null) // If fetch special price for groups
217
  {
218
  $discounted_price = Mage::getResourceModel('catalogrule/rule')->getRulePrice(
219
  Mage::app()->getLocale()->storeTimeStamp($product->getStoreId()),
220
  Mage::app()->getStore($product->getStoreId())->getWebsiteId(),
221
- $group_id,
222
- $product->getId());
 
223
 
224
  if ($discounted_price !== false)
225
  $special_price = $discounted_price;
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
226
  }
227
  else // If fetch default special price
 
228
  $special_price = (double) $product->getFinalPrice();
 
229
 
230
- if ($special_price && $special_price !== $customData['price'][$key])
231
  {
232
- $customData['special_price_from_date'][$key] = strtotime($product->getSpecialFromDate());
233
- $customData['special_price_to_date'][$key] = strtotime($product->getSpecialToDate());
234
 
235
- $customData['special_price'][$key] = (double) $special_price;
236
- $customData['special_price_with_tax'][$key] = (double) Mage::helper('tax')->getPrice($product, $special_price, true, null, null, null, null, false);
237
 
238
- $customData['special_price_formated'][$key] = $product->getStore()->formatPrice($customData['special_price'][$key], false);
239
- $customData['special_price_with_tax_formated'][$key] = $product->getStore()->formatPrice($customData['special_price_with_tax'][$key], false);
 
240
  }
241
- else
 
242
  {
243
- /**
244
- * In case of partial updates set back to empty so that it get updated
245
- */
246
- $customData['special_price'][$key] = '';
247
- $customData['special_price_with_tax'][$key] = '';
248
- }
249
 
250
- $customData['price_formated'][$key] = $product->getStore()->formatPrice($customData['price'][$key], false);
251
- $customData['price_with_tax_formated'][$key] = $product->getStore()->formatPrice($customData['price_with_tax'][$key], false);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
252
  }
253
 
254
  public function getObject(Mage_Catalog_Model_Product $product)
@@ -270,34 +387,21 @@ class Algolia_Algoliasearch_Helper_Entity_Producthelper extends Algolia_Algolias
270
  );
271
 
272
  $additionalAttributes = $this->config->getProductAdditionalAttributes($product->getStoreId());
 
273
 
274
  if ($this->isAttributeEnabled($additionalAttributes, 'description'))
275
  $customData['description'] = $product->getDescription();
276
 
277
-
278
- foreach (array('price', 'price_with_tax', 'special_price_from_date', 'special_price_to_date', 'special_price'
279
- ,'special_price_with_tax', 'special_price_formated', 'special_price_with_tax_formated'
280
- ,'price_formated', 'price_with_tax_formated') as $price)
281
- $customData[$price] = array();
282
-
283
- $this->handlePrice($product, $customData);
284
-
285
- if ($this->config->isCustomerGroupsEnabled())
286
- {
287
- foreach ($groups = Mage::getModel('customer/group')->getCollection() as $group)
288
- {
289
- $group_id = (int)$group->getData('customer_group_id');
290
- $this->handlePrice($product, $customData, $group_id);
291
- }
292
- }
293
-
294
  $categories = array();
295
  $categories_with_path = array();
296
 
297
- foreach ($this->getProductActiveCategories($product, $product->getStoreId()) as $categoryId)
298
- {
299
- $category = Mage::getModel('catalog/category')->load($categoryId);
 
300
 
 
 
301
  $categoryName = $category->getName();
302
 
303
  if ($categoryName)
@@ -316,6 +420,8 @@ class Algolia_Algoliasearch_Helper_Entity_Producthelper extends Algolia_Algolias
316
  $categories_with_path[] = $path;
317
  }
318
 
 
 
319
  foreach ($categories_with_path as $result)
320
  {
321
  for ($i = count($result) - 1; $i > 0; $i--)
@@ -368,17 +474,21 @@ class Algolia_Algoliasearch_Helper_Entity_Producthelper extends Algolia_Algolias
368
  {
369
  try
370
  {
371
- $customData['image_url'] = $product->getImageUrl();
372
  $customData['image_url'] = str_replace(array('https://', 'http://'), '//', $customData['image_url']);
373
  }
374
  catch (\Exception $e) {}
375
 
376
- $product->load('media_gallery');
377
 
378
- $customData['images'] = array();
 
 
 
 
379
 
380
- foreach ($product->getMediaGalleryImages() as $image)
381
- $customData['images'][] = str_replace(array('https://', 'http://'), '//', $image->getUrl());
 
382
  }
383
 
384
  $sub_products = null;
@@ -386,87 +496,26 @@ class Algolia_Algoliasearch_Helper_Entity_Producthelper extends Algolia_Algolias
386
 
387
  if ($product->getTypeId() == 'configurable' || $product->getTypeId() == 'grouped' || $product->getTypeId() == 'bundle')
388
  {
389
- $min = PHP_INT_MAX;
390
- $max = 0;
391
-
392
- $min_with_tax = PHP_INT_MAX;
393
- $max_with_tax = 0;
394
-
395
  if ($product->getTypeId() == 'bundle')
396
  {
397
-
398
- $_priceModel = $product->getPriceModel();
399
-
400
- list($min, $max) = $_priceModel->getTotalPrices($product, null, null, false);
401
- list($min_with_tax, $max_with_tax) = $_priceModel->getTotalPrices($product, null, true, false);
402
-
403
  $ids = array();
404
 
405
  $selection = $product->getTypeInstance(true)->getSelectionsCollection($product->getTypeInstance(true)->getOptionsIds($product), $product);
406
 
407
- foreach($selection as $option)
408
  $ids[] = $option->product_id;
409
  }
410
 
411
- if ($product->getTypeId() == 'grouped')
412
- $sub_products = $product->getTypeInstance(true)->getAssociatedProducts($product);
413
-
414
- if ($product->getTypeId() == 'configurable')
415
- $sub_products = $product->getTypeInstance(true)->getUsedProducts(null, $product);
416
-
417
- if ($product->getTypeId() == 'grouped' || $product->getTypeId() == 'configurable')
418
- {
419
- $ids = array_map(function ($product)
420
- {
421
- return $product->getId();
422
- }, $sub_products);
423
- }
424
-
425
- if (count($ids)) {
426
- $sub_products = $this->getProductCollectionQuery($product->getStoreId(), $ids, false)->load();
427
- }
428
- else {
429
- $sub_products = array();
430
- }
431
 
432
- if ($product->getTypeId() == 'grouped' || $product->getTypeId() == 'configurable')
433
  {
434
- foreach ($sub_products as $sub_product)
435
- {
436
- $price = $sub_product->getPrice();
437
- $price_with_tax = Mage::helper('tax')->getPrice($sub_product, $price, true, null, null, null, null, false);
438
-
439
- $min = min($min, $price);
440
- $max = max($max, $price);
441
-
442
- $min_with_tax = min($min_with_tax, $price_with_tax);
443
- $max_with_tax = max($max_with_tax, $price_with_tax);
444
- }
445
- }
446
-
447
- $customData['min_formated'] = array();
448
- $customData['max_formated'] = array();
449
- $customData['min_with_tax_formated'] = array();
450
- $customData['max_with_tax_formated'] = array();
451
-
452
- $customData['min_formated']['default'] = $product->getStore()->formatPrice($min, false);
453
- $customData['max_formated']['default'] = $product->getStore()->formatPrice($max, false);
454
- $customData['min_with_tax_formated']['default'] = $product->getStore()->formatPrice($min_with_tax, false);
455
- $customData['max_with_tax_formated']['default'] = $product->getStore()->formatPrice($max_with_tax, false);
456
-
457
- if ($this->config->isCustomerGroupsEnabled($product->getStoreId()))
458
  {
459
- foreach ($groups = Mage::getModel('customer/group')->getCollection() as $group)
460
- {
461
- $group_id = (int)$group->getData('customer_group_id');
462
-
463
- $customData['min_formated']['group_' . $group_id] = $product->getStore()->formatPrice($min, false);
464
- $customData['max_formated']['group_' . $group_id] = $product->getStore()->formatPrice($max, false);
465
- $customData['min_with_tax_formated']['group_' . $group_id] = $product->getStore()->formatPrice($min_with_tax, false);
466
- $customData['max_with_tax_formated']['group_' . $group_id] = $product->getStore()->formatPrice($max_with_tax, false);
467
- }
468
  }
469
-
470
  }
471
 
472
  if (false === isset($defaultData['in_stock']))
@@ -477,64 +526,15 @@ class Algolia_Algoliasearch_Helper_Entity_Producthelper extends Algolia_Algolias
477
  }
478
 
479
  // skip default calculation if we have provided these attributes via the observer in $defaultData
480
- if (false === isset($defaultData['ordered_qty']) && false === isset($defaultData['stock_qty']))
481
- {
482
- $query = Mage::getResourceModel('sales/order_item_collection');
483
- $query->getSelect()->reset(Zend_Db_Select::COLUMNS)
484
- ->columns(array('sku','SUM(qty_ordered) as ordered_qty'))
485
- ->group(array('sku'))
486
- ->where('sku = ?',array($product->getSku()))
487
- ->limit(1);
488
-
489
- $ordered_qty = (int) $query->getFirstItem()->ordered_qty;
490
-
491
- $customData['ordered_qty'] = (int) $ordered_qty;
492
- $customData['stock_qty'] = (int) Mage::getModel('cataloginventory/stock_item')->loadByProduct($product)->getQty();
493
-
494
- if ($product->getTypeId() == 'configurable' || $product->getTypeId() == 'grouped' || $product->getTypeId() == 'bundle')
495
- {
496
- $ordered_qty = 0;
497
- $stock_qty = 0;
498
-
499
- foreach ($sub_products as $sub_product)
500
- {
501
- $stock_qty += (int)Mage::getModel('cataloginventory/stock_item')->loadByProduct($sub_product)->getQty();
502
-
503
- $query = Mage::getResourceModel('sales/order_item_collection');
504
- $query->getSelect()->reset(Zend_Db_Select::COLUMNS)
505
- ->columns(array('sku','SUM(qty_ordered) as ordered_qty'))
506
- ->group(array('sku'))
507
- ->where('sku = ?',array($sub_product->getSku()))
508
- ->limit(1);
509
-
510
- $ordered_qty += (int) $query->getFirstItem()->ordered_qty;
511
- }
512
-
513
- $customData['ordered_qty'] = $ordered_qty;
514
- $customData['stock_qty'] = $stock_qty;
515
- }
516
-
517
-
518
- if ($this->isAttributeEnabled($additionalAttributes, 'ordered_qty') === false)
519
- unset($customData['ordered_qty']);
520
-
521
- if ($this->isAttributeEnabled($additionalAttributes, 'stock_qty') === false)
522
- unset($customData['stock_qty']);
523
- }
524
 
 
 
525
 
526
  if (Mage::helper('core')->isModuleEnabled('Mage_Review'))
527
- {
528
  if ($this->isAttributeEnabled($additionalAttributes, 'rating_summary'))
529
- {
530
- $summaryData = Mage::getModel('review/review_summary')
531
- ->setStoreId($product->getStoreId())
532
- ->load($product->getId());
533
-
534
- if ($summaryData['rating_summary'])
535
- $customData['rating_summary'] = $summaryData['rating_summary'];
536
- }
537
- }
538
 
539
  foreach ($additionalAttributes as $attribute)
540
  {
@@ -602,6 +602,19 @@ class Algolia_Algoliasearch_Helper_Entity_Producthelper extends Algolia_Algolias
602
  }
603
  }
604
 
 
 
 
 
 
 
 
 
 
 
 
 
 
605
  $transport = new Varien_Object($customData);
606
  Mage::dispatchEvent('algolia_subproducts_index', array('custom_data' => $transport, 'sub_products' => $sub_products));
607
  $customData = $transport->getData();
22
 
23
  $allAttributes = $config->getEntityAttributeCodes('catalog_product');
24
 
25
+ $productAttributes = array_merge(array('name', 'path', 'categories', 'categories_without_path', 'description', 'ordered_qty', 'stock_qty', 'price', 'rating_summary', 'media_gallery'), $allAttributes);
26
 
27
  $excludedAttributes = array(
28
  'all_children', 'available_sort_by', 'children', 'children_count', 'custom_apply_to_products',
53
  protected function isAttributeEnabled($additionalAttributes, $attr_name)
54
  {
55
  foreach ($additionalAttributes as $attr)
56
+ if ($attr['attribute'] === $attr_name)
57
  return true;
58
 
59
  return false;
60
  }
61
 
62
+ public function getProductCollectionQuery($storeId, $productIds = null, $only_visible = true, $additional_attributes = true)
63
  {
64
  /** @var $products Mage_Catalog_Model_Resource_Eav_Mysql4_Product_Collection */
65
  $products = Mage::getResourceModel('catalog/product_collection');
77
 
78
  $additionalAttr = $this->config->getProductAdditionalAttributes($storeId);
79
 
80
+ if ($additional_attributes)
81
+ {
82
+ foreach ($additionalAttr as &$attr)
83
+ $attr = $attr['attribute'];
84
 
85
+ $products = $products->addAttributeToSelect(array_values(array_merge(static::$_predefinedProductAttributes, $additionalAttr)));
86
+ }
87
 
88
  if ($productIds && count($productIds) > 0)
89
  $products = $products->addAttributeToFilter('entity_id', array('in' => $productIds));
120
  $facets = $this->config->getFacets();
121
 
122
  foreach($facets as $facet)
123
+ {
124
+ if ($facet['attribute'] === 'price')
125
+ {
126
+ $facet['attribute'] = 'price.default';
127
+
128
+ if ($this->config->isCustomerGroupsEnabled($storeId))
129
+ {
130
+ foreach ($groups = Mage::getModel('customer/group')->getCollection() as $group)
131
+ {
132
+ $group_id = (int)$group->getData('customer_group_id');
133
+
134
+ $attributesForFaceting[] = 'price.group_' . $group_id;
135
+ }
136
+ }
137
+ }
138
+
139
  $attributesForFaceting[] = $facet['attribute'];
140
+ }
141
+
142
 
143
  foreach ($customRankings as $ranking)
144
  $customRankingsArr[] = $ranking['order'] . '(' . $ranking['attribute'] . ')';
174
  {
175
  if ($this->config->isCustomerGroupsEnabled($storeId))
176
  {
177
+ if ($values['attribute'] === 'price')
178
  {
179
  foreach ($groups = Mage::getModel('customer/group')->getCollection() as $group)
180
  {
182
 
183
  $suffix_index_name = 'group_' . $group_id;
184
 
185
+ $slaves[] = $this->getIndexName($storeId) . '_' .$values['attribute'].'_' . $suffix_index_name . '_' . $values['sort'];
186
  }
187
  }
188
  }
189
  else
190
  {
191
+ if ($values['attribute'] === 'price')
192
+ $slaves[] = $this->getIndexName($storeId) . '_' .$values['attribute']. '_default_' . $values['sort'];
193
+ else
194
+ $slaves[] = $this->getIndexName($storeId) . '_' .$values['attribute']. '_' . $values['sort'];
195
  }
196
  }
197
 
207
  {
208
  $group_id = (int)$group->getData('customer_group_id');
209
 
210
+ $suffix_index_name = 'group_' . $group_id;
211
+
212
+ $sort_attribute = strpos($values['attribute'], 'price') !== false ? $values['attribute'].'.'.$suffix_index_name : $values['attribute'];
213
 
 
214
  $mergeSettings['ranking'] = array($values['sort'].'('.$sort_attribute.')', 'typo', 'geo', 'words', 'proximity', 'attribute', 'exact', 'custom');
215
 
216
+ $this->algolia_helper->setSettings($this->getIndexName($storeId).'_'.$values['attribute'].'_'. $suffix_index_name .'_'.$values['sort'], $mergeSettings);
217
  }
218
  }
219
  }
223
 
224
  $mergeSettings['ranking'] = array($values['sort'].'('.$sort_attribute.')', 'typo', 'geo', 'words', 'proximity', 'attribute', 'exact', 'custom');
225
 
226
+ $this->algolia_helper->setSettings($this->getIndexName($storeId) . '_' .$values['attribute'].'_' . 'default' . '_'.$values['sort'], $mergeSettings);
227
  }
228
  }
229
  }
230
  }
231
 
232
+ private function handlePrice(&$product, $sub_products, &$customData, $groups = array(), $current_group_id = null)
233
  {
234
+ $customData['price'] = array();
235
+
236
+ $customData['price']['default'] = (double) Mage::helper('tax')->getPrice($product, $product->getPrice(), null, null, null, null, $product->getStore(), null);
237
+ $customData['price']['default_formated'] = $product->getStore()->formatPrice($customData['price']['default'], false);
238
+
239
+ if ($this->config->isCustomerGroupsEnabled($product->getStoreId()))
240
+ {
241
+ foreach ($groups as $group)
242
+ {
243
+ $group_id = (int)$group->getData('customer_group_id');
244
 
245
+ $customData['price']['group_' . $group_id] = $customData['price']['default'];
246
+ $customData['price']['group_' . $group_id . '_formated'] = $customData['price']['default_formated'];
247
+ }
248
+ }
249
 
250
  $special_price = null;
251
 
252
+ if ($current_group_id !== null) // If fetch special price for groups
253
  {
254
  $discounted_price = Mage::getResourceModel('catalogrule/rule')->getRulePrice(
255
  Mage::app()->getLocale()->storeTimeStamp($product->getStoreId()),
256
  Mage::app()->getStore($product->getStoreId())->getWebsiteId(),
257
+ $current_group_id,
258
+ $product->getId()
259
+ );
260
 
261
  if ($discounted_price !== false)
262
  $special_price = $discounted_price;
263
+
264
+ if ($this->config->isCustomerGroupsEnabled($product->getStoreId()))
265
+ {
266
+ foreach ($groups as $group)
267
+ {
268
+ $group_id = (int)$group->getData('customer_group_id');
269
+
270
+ $discounted_price = Mage::getResourceModel('catalogrule/rule')->getRulePrice(
271
+ Mage::app()->getLocale()->storeTimeStamp($product->getStoreId()),
272
+ Mage::app()->getStore($product->getStoreId())->getWebsiteId(),
273
+ $group_id,
274
+ $product->getId()
275
+ );
276
+
277
+ if ($discounted_price !== false)
278
+ {
279
+ $customData['price']['group_' . $group_id] = (double) Mage::helper('tax')->getPrice($product, $discounted_price, null, null, null, null, $product->getStore(), null);
280
+ $customData['price']['group_' . $group_id . '_formated'] = $product->getStore()->formatPrice($customData['price']['group_' . $group_id], false);
281
+ }
282
+ }
283
+ }
284
+
285
  }
286
  else // If fetch default special price
287
+ {
288
  $special_price = (double) $product->getFinalPrice();
289
+ }
290
 
291
+ if ($special_price && $special_price !== $customData['price']['default'])
292
  {
293
+ $customData['price']['special_from_date'] = strtotime($product->getSpecialFromDate());
294
+ $customData['price']['special_to_date'] = strtotime($product->getSpecialToDate());
295
 
296
+ $customData['price']['default_original_formated'] = $customData['price']['default'.'_formated'];
 
297
 
298
+ $special_price = (double) Mage::helper('tax')->getPrice($product, $special_price, null, null, null, null, $product->getStore(), null);
299
+ $customData['price']['default'] = $special_price;
300
+ $customData['price']['default_formated'] = $product->getStore()->formatPrice($special_price, false);
301
  }
302
+
303
+ if ($product->getTypeId() == 'configurable' || $product->getTypeId() == 'grouped' || $product->getTypeId() == 'bundle')
304
  {
305
+ $min = PHP_INT_MAX;
306
+ $max = 0;
307
+
308
+ if ($product->getTypeId() == 'bundle')
309
+ {
310
+ $_priceModel = $product->getPriceModel();
311
 
312
+ list($min, $max) = $_priceModel->getTotalPrices($product, null, null, true);
313
+ }
314
+
315
+ if ($product->getTypeId() == 'grouped' || $product->getTypeId() == 'configurable')
316
+ {
317
+ foreach ($sub_products as $sub_product)
318
+ {
319
+ $price = (double) Mage::helper('tax')->getPrice($sub_product, $sub_product->getFinalPrice(), null, null, null, null, $product->getStore(), null);
320
+
321
+ $min = min($min, $price);
322
+ $max = max($max, $price);
323
+ }
324
+ }
325
+
326
+ if ($min != $max)
327
+ {
328
+ $customData['price']['default_formated'] = $product->getStore()->formatPrice($min, false) . ' - ' . $product->getStore()->formatPrice($max, false);
329
+
330
+ if ($this->config->isCustomerGroupsEnabled($product->getStoreId()))
331
+ {
332
+ foreach ($groups as $group)
333
+ {
334
+ $group_id = (int)$group->getData('customer_group_id');
335
+
336
+ $customData['price']['group_' . $group_id] = 0;
337
+ $customData['price']['group_' . $group_id . '_formated'] = $product->getStore()->formatPrice($min, false) . ' - ' . $product->getStore()->formatPrice($max, false);
338
+ }
339
+ }
340
+
341
+ //// Do not keep special price that is already taken into account in min max
342
+ unset($customData['price']['special_from_date']);
343
+ unset($customData['price']['special_to_date']);
344
+ unset($customData['price']['default_original_formated']);
345
+
346
+ $customData['price']['default'] = 0; // will be reset just after
347
+ }
348
+
349
+ if ($customData['price']['default'] == 0)
350
+ {
351
+ $customData['price']['default'] = $min;
352
+
353
+ if ($min === $max)
354
+ $customData['price']['default_formated'] = $product->getStore()->formatPrice($min, false);
355
+
356
+ if ($this->config->isCustomerGroupsEnabled($product->getStoreId()))
357
+ {
358
+ foreach ($groups as $group)
359
+ {
360
+ $group_id = (int)$group->getData('customer_group_id');
361
+ $customData['price']['group_' . $group_id] = $min;
362
+
363
+ if ($min === $max)
364
+ $customData['price']['group_' . $group_id] = $product->getStore()->formatPrice($min, false);
365
+ }
366
+ }
367
+ }
368
+ }
369
  }
370
 
371
  public function getObject(Mage_Catalog_Model_Product $product)
387
  );
388
 
389
  $additionalAttributes = $this->config->getProductAdditionalAttributes($product->getStoreId());
390
+ $groups = null;
391
 
392
  if ($this->isAttributeEnabled($additionalAttributes, 'description'))
393
  $customData['description'] = $product->getDescription();
394
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
395
  $categories = array();
396
  $categories_with_path = array();
397
 
398
+ $categoryCollection = Mage::getResourceModel('catalog/category_collection')
399
+ ->addAttributeToSelect('name')
400
+ ->addAttributeToFilter('entity_id', $product->getCategoryIds())
401
+ ->addIsActiveFilter();
402
 
403
+ foreach ($categoryCollection as $category)
404
+ {
405
  $categoryName = $category->getName();
406
 
407
  if ($categoryName)
420
  $categories_with_path[] = $path;
421
  }
422
 
423
+
424
+
425
  foreach ($categories_with_path as $result)
426
  {
427
  for ($i = count($result) - 1; $i > 0; $i--)
474
  {
475
  try
476
  {
477
+ $customData['image_url'] = Mage::getModel('catalog/product_media_config')->getMediaUrl($product->getImage());
478
  $customData['image_url'] = str_replace(array('https://', 'http://'), '//', $customData['image_url']);
479
  }
480
  catch (\Exception $e) {}
481
 
 
482
 
483
+ if ($this->isAttributeEnabled($additionalAttributes, 'media_gallery'))
484
+ {
485
+ $product->load('media_gallery');
486
+
487
+ $customData['media_gallery'] = array();
488
 
489
+ foreach ($product->getMediaGalleryImages() as $image)
490
+ $customData['media_gallery'][] = str_replace(array('https://', 'http://'), '//', $image->getUrl());
491
+ }
492
  }
493
 
494
  $sub_products = null;
496
 
497
  if ($product->getTypeId() == 'configurable' || $product->getTypeId() == 'grouped' || $product->getTypeId() == 'bundle')
498
  {
 
 
 
 
 
 
499
  if ($product->getTypeId() == 'bundle')
500
  {
 
 
 
 
 
 
501
  $ids = array();
502
 
503
  $selection = $product->getTypeInstance(true)->getSelectionsCollection($product->getTypeInstance(true)->getOptionsIds($product), $product);
504
 
505
+ foreach ($selection as $option)
506
  $ids[] = $option->product_id;
507
  }
508
 
509
+ if ($product->getTypeId() == 'configurable' || $product->getTypeId() == 'grouped')
510
+ $ids = $product->getTypeInstance(true)->getChildrenIds($product->getId());
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
511
 
512
+ if (count($ids))
513
  {
514
+ $sub_products = $this->getProductCollectionQuery($product->getStoreId(), $ids, false, false)->load();
515
+ } else
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
516
  {
517
+ $sub_products = array();
 
 
 
 
 
 
 
 
518
  }
 
519
  }
520
 
521
  if (false === isset($defaultData['in_stock']))
526
  }
527
 
528
  // skip default calculation if we have provided these attributes via the observer in $defaultData
529
+ if (false === isset($defaultData['ordered_qty']) && $this->isAttributeEnabled($additionalAttributes, 'ordered_qty'))
530
+ $customData['ordered_qty'] = (int) $product->getOrderedQty();
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
531
 
532
+ if (false === isset($defaultData['stock_qty']) && $this->isAttributeEnabled($additionalAttributes, 'stock_qty'))
533
+ $customData['stock_qty'] = (int) $product->getStockQty();
534
 
535
  if (Mage::helper('core')->isModuleEnabled('Mage_Review'))
 
536
  if ($this->isAttributeEnabled($additionalAttributes, 'rating_summary'))
537
+ $customData['rating_summary'] = $product->getRatingSummary();
 
 
 
 
 
 
 
 
538
 
539
  foreach ($additionalAttributes as $attribute)
540
  {
602
  }
603
  }
604
 
605
+ $this->handlePrice($product, $sub_products, $customData);
606
+
607
+ if ($this->config->isCustomerGroupsEnabled())
608
+ {
609
+ $groups = Mage::getModel('customer/group')->getCollection();
610
+
611
+ foreach ($groups as $group)
612
+ {
613
+ $group_id = (int)$group->getData('customer_group_id');
614
+ $this->handlePrice($product, $sub_products, $customData, $groups, $group_id);
615
+ }
616
+ }
617
+
618
  $transport = new Varien_Object($customData);
619
  Mage::dispatchEvent('algolia_subproducts_index', array('custom_data' => $transport, 'sub_products' => $sub_products));
620
  $customData = $transport->getData();
app/code/community/Algolia/Algoliasearch/Model/Indexer/Algolia.php CHANGED
@@ -60,7 +60,7 @@ class Algolia_Algoliasearch_Model_Indexer_Algolia extends Mage_Index_Model_Index
60
 
61
  public function getDescription()
62
  {
63
- return Mage::helper('algoliasearch')->__('Rebuild product, category indices.
64
  Please enable the queueing system to do it asynchronously (CRON) if you have a lot of products in System > Configuration > Algolia Search > Queue configuration');
65
  }
66
 
@@ -80,9 +80,6 @@ class Algolia_Algoliasearch_Model_Indexer_Algolia extends Mage_Index_Model_Index
80
  case Mage_Catalog_Model_Product::ENTITY:
81
  $this->_registerCatalogProductEvent($event);
82
  break;
83
- case Mage_Catalog_Model_Category::ENTITY:
84
- $this->_registerCatalogCategoryEvent($event);
85
- break;
86
  case Mage_Catalog_Model_Convert_Adapter_Product::ENTITY:
87
  $event->addNewData('algoliasearch_reindex_all', TRUE);
88
  break;
@@ -173,54 +170,6 @@ class Algolia_Algoliasearch_Model_Indexer_Algolia extends Mage_Index_Model_Index
173
  return $this;
174
  }
175
 
176
- protected function _registerCatalogCategoryEvent(Mage_Index_Model_Event $event)
177
- {
178
- switch ($event->getType()) {
179
- case Mage_Index_Model_Event::TYPE_SAVE:
180
-
181
- /** @var $category Mage_Catalog_Model_Category */
182
- $category = $event->getDataObject();
183
- $productIds = $category->getAffectedProductIds();
184
-
185
- if (! $category->getData('is_active'))
186
- {
187
- $event->addNewData('catalogsearch_delete_category_id', array_merge(array($category->getId()), $category->getAllChildren(TRUE)));
188
-
189
- if ($productIds)
190
- {
191
- $event->addNewData('catalogsearch_update_product_id', $productIds);
192
- }
193
-
194
- }
195
- elseif ($productIds)
196
- {
197
- $event->addNewData('catalogsearch_update_product_id', $productIds);
198
- $event->addNewData('catalogsearch_update_category_id', array($category->getId()));
199
- }
200
- elseif ($movedCategoryId = $category->getMovedCategoryId())
201
- {
202
- $event->addNewData('catalogsearch_update_category_id', array($movedCategoryId));
203
- }
204
- else
205
- {
206
- $event->addNewData('catalogsearch_update_category_id', array($category->getId()));
207
- }
208
-
209
- break;
210
-
211
- case Mage_Index_Model_Event::TYPE_DELETE:
212
-
213
- /** @var $category Mage_Catalog_Model_Category */
214
- $category = $event->getDataObject();
215
-
216
- $event->addNewData('catalogsearch_delete_category_id', $category->getId());
217
-
218
- break;
219
- }
220
-
221
- return $this;
222
- }
223
-
224
  protected function _isProductComposite($productId)
225
  {
226
  /** @var $product Mage_Catalog_Model_Product */
@@ -244,7 +193,7 @@ class Algolia_Algoliasearch_Model_Indexer_Algolia extends Mage_Index_Model_Index
244
  $data = $event->getNewData();
245
 
246
  /*
247
- * Reindex all products and all categories and update index settings
248
  */
249
  if ( ! empty($data['algoliasearch_reindex_all'])) {
250
  $process = $event->getProcess();
@@ -252,8 +201,7 @@ class Algolia_Algoliasearch_Model_Indexer_Algolia extends Mage_Index_Model_Index
252
  }
253
 
254
  /*
255
- * Clear index for the deleted product and update index for the related categories.
256
- * Categories must be reindexed after the product index is deleted if product count is indexed.
257
  */
258
  else if ( ! empty($data['catalogsearch_delete_product_id'])) {
259
  $productId = $data['catalogsearch_delete_product_id'];
@@ -268,33 +216,8 @@ class Algolia_Algoliasearch_Model_Indexer_Algolia extends Mage_Index_Model_Index
268
 
269
  $this->engine
270
  ->removeProducts(null, $productId);
271
- /*
272
- * Change indexer status as need to reindex related categories to update product count.
273
- * It's low priority so no need to automatically reindex all related categories after deleting each product.
274
- * Do not reindex all if affected categories are given or product count is not indexed.
275
- */
276
- if ( ! isset($data['catalogsearch_update_category_id'])) {
277
- $process = $event->getProcess();
278
- $process->changeStatus(Mage_Index_Model_Process::STATUS_REQUIRE_REINDEX);
279
- }
280
- }
281
- /*
282
- * Clear indexer for the deleted category including all children categories and update index for the related products.
283
- */
284
- else if ( ! empty($data['catalogsearch_delete_category_id'])) {
285
- $categoryIds = $data['catalogsearch_delete_category_id'];
286
- $this->engine
287
- ->removeCategories(null, $categoryIds);
288
- /*
289
- * Change indexer status as need to reindex related products to update the list of categories.
290
- * It's low priority so no need to automatically reindex all related products after deleting each category.
291
- * Do not reindex all if affected products are given or product count is not indexed.
292
- */
293
- if ( ! isset($data['catalogsearch_update_product_id'])) {
294
- $process = $event->getProcess();
295
- $process->changeStatus(Mage_Index_Model_Process::STATUS_REQUIRE_REINDEX);
296
- }
297
  }
 
298
  // Mass action
299
  else if ( ! empty($data['catalogsearch_product_ids'])) {
300
  $productIds = $data['catalogsearch_product_ids'];
@@ -329,9 +252,24 @@ class Algolia_Algoliasearch_Model_Indexer_Algolia extends Mage_Index_Model_Index
329
  }
330
  }
331
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
332
  /*
333
  * Reindex products.
334
- * The products are enabled and visible for search so no need to reindex related categories after reindexing products.
335
  */
336
  if ( ! empty($data['catalogsearch_update_product_id'])) {
337
  $updateProductIds = $data['catalogsearch_update_product_id'];
@@ -349,17 +287,6 @@ class Algolia_Algoliasearch_Model_Indexer_Algolia extends Mage_Index_Model_Index
349
  $this->engine
350
  ->rebuildProductIndex(null, $productIds);
351
  }
352
-
353
- /*
354
- * Reindex categories.
355
- * Category products are tracked separately. The specified categories are active. See _registerCatalogCategoryEvent().
356
- */
357
- if ( ! empty($data['catalogsearch_update_category_id'])) {
358
- $updateCategoryIds = $data['catalogsearch_update_category_id'];
359
- $updateCategoryIds = is_array($updateCategoryIds) ? $updateCategoryIds : array($updateCategoryIds);
360
- $this->engine
361
- ->rebuildCategoryIndex(null, $updateCategoryIds);
362
- }
363
  }
364
 
365
  /**
@@ -373,7 +300,7 @@ class Algolia_Algoliasearch_Model_Indexer_Algolia extends Mage_Index_Model_Index
373
  return;
374
  }
375
 
376
- $this->engine->rebuildProductsAndCategories();
377
 
378
  return $this;
379
  }
60
 
61
  public function getDescription()
62
  {
63
+ return Mage::helper('algoliasearch')->__('Rebuild product index.
64
  Please enable the queueing system to do it asynchronously (CRON) if you have a lot of products in System > Configuration > Algolia Search > Queue configuration');
65
  }
66
 
80
  case Mage_Catalog_Model_Product::ENTITY:
81
  $this->_registerCatalogProductEvent($event);
82
  break;
 
 
 
83
  case Mage_Catalog_Model_Convert_Adapter_Product::ENTITY:
84
  $event->addNewData('algoliasearch_reindex_all', TRUE);
85
  break;
170
  return $this;
171
  }
172
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
173
  protected function _isProductComposite($productId)
174
  {
175
  /** @var $product Mage_Catalog_Model_Product */
193
  $data = $event->getNewData();
194
 
195
  /*
196
+ * Reindex all products
197
  */
198
  if ( ! empty($data['algoliasearch_reindex_all'])) {
199
  $process = $event->getProcess();
201
  }
202
 
203
  /*
204
+ * Clear index for the deleted product.
 
205
  */
206
  else if ( ! empty($data['catalogsearch_delete_product_id'])) {
207
  $productId = $data['catalogsearch_delete_product_id'];
216
 
217
  $this->engine
218
  ->removeProducts(null, $productId);
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
219
  }
220
+
221
  // Mass action
222
  else if ( ! empty($data['catalogsearch_product_ids'])) {
223
  $productIds = $data['catalogsearch_product_ids'];
252
  }
253
  }
254
 
255
+ if ( ! empty($data['catalogsearch_update_category_id'])) {
256
+ $updateCategoryIds = $data['catalogsearch_update_category_id'];
257
+ $updateCategoryIds = is_array($updateCategoryIds) ? $updateCategoryIds : array($updateCategoryIds);
258
+
259
+ foreach ($updateCategoryIds as $id)
260
+ {
261
+ $categories = Mage::getModel('catalog/category')->getCategories($id);
262
+
263
+ foreach ($categories as $category)
264
+ $updateCategoryIds[] = $category->getId();
265
+ }
266
+
267
+ $this->engine
268
+ ->rebuildCategoryIndex(null, $updateCategoryIds);
269
+ }
270
+
271
  /*
272
  * Reindex products.
 
273
  */
274
  if ( ! empty($data['catalogsearch_update_product_id'])) {
275
  $updateProductIds = $data['catalogsearch_update_product_id'];
287
  $this->engine
288
  ->rebuildProductIndex(null, $productIds);
289
  }
 
 
 
 
 
 
 
 
 
 
 
290
  }
291
 
292
  /**
300
  return;
301
  }
302
 
303
+ $this->engine->rebuildProducts();
304
 
305
  return $this;
306
  }
app/code/community/Algolia/Algoliasearch/Model/Indexer/Algoliacategories.php ADDED
@@ -0,0 +1,200 @@
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
1
+ <?php
2
+
3
+ class Algolia_Algoliasearch_Model_Indexer_Algoliacategories extends Mage_Index_Model_Indexer_Abstract
4
+ {
5
+ const EVENT_MATCH_RESULT_KEY = 'algoliasearch_match_result';
6
+
7
+ /** @var Algolia_Algoliasearch_Model_Resource_Engine */
8
+ private $engine;
9
+ private $config;
10
+
11
+ public static $product_categories = array();
12
+ private static $credential_error = false;
13
+
14
+ public function __construct()
15
+ {
16
+ parent::__construct();
17
+
18
+ $this->engine = new Algolia_Algoliasearch_Model_Resource_Engine();
19
+ $this->config = Mage::helper('algoliasearch/config');
20
+ }
21
+
22
+ protected $_matchedEntities = array(
23
+ Mage_Catalog_Model_Category::ENTITY => array(
24
+ Mage_Index_Model_Event::TYPE_SAVE,
25
+ Mage_Index_Model_Event::TYPE_DELETE
26
+ )
27
+ );
28
+
29
+ protected function _getResource()
30
+ {
31
+ return Mage::getResourceSingleton('catalogsearch/indexer_fulltext');
32
+ }
33
+
34
+ public function getName()
35
+ {
36
+ return Mage::helper('algoliasearch')->__('Algolia Search Categories');
37
+ }
38
+
39
+ public function getDescription()
40
+ {
41
+ return Mage::helper('algoliasearch')->__('Rebuild category index.
42
+ Please enable the queueing system to do it asynchronously (CRON) if you have a lot of products in System > Configuration > Algolia Search > Queue configuration');
43
+ }
44
+
45
+ public function matchEvent(Mage_Index_Model_Event $event)
46
+ {
47
+ $result = true;
48
+
49
+ $event->addNewData(self::EVENT_MATCH_RESULT_KEY, $result);
50
+
51
+ return $result;
52
+ }
53
+
54
+ protected function _registerEvent(Mage_Index_Model_Event $event)
55
+ {
56
+ $event->addNewData(self::EVENT_MATCH_RESULT_KEY, TRUE);
57
+
58
+ switch ($event->getEntity()) {
59
+ case Mage_Catalog_Model_Category::ENTITY:
60
+ $this->_registerCatalogCategoryEvent($event);
61
+ break;
62
+ }
63
+ }
64
+
65
+ protected function _registerCatalogCategoryEvent(Mage_Index_Model_Event $event)
66
+ {
67
+ switch ($event->getType()) {
68
+ case Mage_Index_Model_Event::TYPE_SAVE:
69
+
70
+ /** @var $category Mage_Catalog_Model_Category */
71
+ $category = $event->getDataObject();
72
+ $productIds = $category->getAffectedProductIds();
73
+
74
+ if (! $category->getData('is_active'))
75
+ {
76
+ $event->addNewData('catalogsearch_delete_category_id', array_merge(array($category->getId()), $category->getAllChildren(TRUE)));
77
+
78
+ if ($productIds)
79
+ {
80
+ $event->addNewData('catalogsearch_update_product_id', $productIds);
81
+ }
82
+
83
+ }
84
+ elseif ($productIds)
85
+ {
86
+ $event->addNewData('catalogsearch_update_product_id', $productIds);
87
+ $event->addNewData('catalogsearch_update_category_id', array($category->getId()));
88
+ }
89
+ elseif ($movedCategoryId = $category->getMovedCategoryId())
90
+ {
91
+ $event->addNewData('catalogsearch_update_category_id', array($movedCategoryId));
92
+ }
93
+ else
94
+ {
95
+ $event->addNewData('catalogsearch_update_category_id', array($category->getId()));
96
+ }
97
+
98
+ break;
99
+
100
+ case Mage_Index_Model_Event::TYPE_DELETE:
101
+
102
+ /** @var $category Mage_Catalog_Model_Category */
103
+ $category = $event->getDataObject();
104
+
105
+ $event->addNewData('catalogsearch_delete_category_id', $category->getId());
106
+
107
+ break;
108
+ }
109
+
110
+ return $this;
111
+ }
112
+
113
+ protected function _isProductComposite($productId)
114
+ {
115
+ /** @var $product Mage_Catalog_Model_Product */
116
+ $product = Mage::getModel('catalog/product')->load($productId);
117
+ return $product->isComposite();
118
+ }
119
+
120
+ protected function _processEvent(Mage_Index_Model_Event $event)
121
+ {
122
+ if (! $this->config->getApplicationID() || ! $this->config->getAPIKey() || ! $this->config->getSearchOnlyAPIKey())
123
+ {
124
+ if (self::$credential_error === false)
125
+ {
126
+ Mage::getSingleton('adminhtml/session')->addError('Algolia indexing failed: You need to configure your Algolia credentials in System > Configuration > Algolia Search.');
127
+ self::$credential_error = true;
128
+ }
129
+
130
+ return;
131
+ }
132
+
133
+ $data = $event->getNewData();
134
+
135
+ /*
136
+ * Reindex all products and all categories and update index settings
137
+ */
138
+ if ( ! empty($data['algoliasearch_reindex_all'])) {
139
+ $process = $event->getProcess();
140
+ $process->changeStatus(Mage_Index_Model_Process::STATUS_REQUIRE_REINDEX);
141
+ }
142
+
143
+ /*
144
+ * Clear indexer for the deleted category including all children categories and update index for the related products.
145
+ */
146
+ else if ( ! empty($data['catalogsearch_delete_category_id'])) {
147
+ $categoryIds = $data['catalogsearch_delete_category_id'];
148
+ $this->engine
149
+ ->removeCategories(null, $categoryIds);
150
+ /*
151
+ * Change indexer status as need to reindex related products to update the list of categories.
152
+ * It's low priority so no need to automatically reindex all related products after deleting each category.
153
+ * Do not reindex all if affected products are given or product count is not indexed.
154
+ */
155
+ if ( ! isset($data['catalogsearch_update_product_id'])) {
156
+ $process = $event->getProcess();
157
+ $process->changeStatus(Mage_Index_Model_Process::STATUS_REQUIRE_REINDEX);
158
+ }
159
+ }
160
+
161
+ /*
162
+ * Reindex categories.
163
+ * Category products are tracked separately. The specified categories are active. See _registerCatalogCategoryEvent().
164
+ */
165
+ if ( ! empty($data['catalogsearch_update_category_id'])) {
166
+ $updateCategoryIds = $data['catalogsearch_update_category_id'];
167
+ $updateCategoryIds = is_array($updateCategoryIds) ? $updateCategoryIds : array($updateCategoryIds);
168
+
169
+ foreach ($updateCategoryIds as $id)
170
+ {
171
+ $categories = Mage::getModel('catalog/category')->getCategories($id);
172
+
173
+ foreach ($categories as $category)
174
+ $updateCategoryIds[] = $category->getId();
175
+ }
176
+
177
+ $this->engine
178
+ ->rebuildCategoryIndex(null, $updateCategoryIds);
179
+ }
180
+
181
+ $process_products = Mage::getSingleton('index/indexer')->getProcessByCode('algolia_search_indexer');
182
+ $process_products->changeStatus(Mage_Index_Model_Process::STATUS_REQUIRE_REINDEX);
183
+ }
184
+
185
+ /**
186
+ * Rebuild all index data
187
+ */
188
+ public function reindexAll()
189
+ {
190
+ if (! $this->config->getApplicationID() || ! $this->config->getAPIKey() || ! $this->config->getSearchOnlyAPIKey())
191
+ {
192
+ Mage::getSingleton('adminhtml/session')->addError('Algolia reindexing failed: You need to configure your Algolia credentials in System > Configuration > Algolia Search.');
193
+ return;
194
+ }
195
+
196
+ $this->engine->rebuildCategories();
197
+
198
+ return $this;
199
+ }
200
+ }
app/code/community/Algolia/Algoliasearch/Model/Observer.php CHANGED
@@ -95,11 +95,18 @@ class Algolia_Algoliasearch_Model_Observer
95
  $this->updateStock($product->getProductId());
96
  }
97
 
98
- public function deleteProductsAndCategoriesStoreIndices(Varien_Object $event)
99
  {
100
  $storeId = $event->getStoreId();
101
 
102
- $this->helper->deleteProductsAndCategoriesStoreIndices($storeId);
 
 
 
 
 
 
 
103
  }
104
 
105
  public function removeProducts(Varien_Object $event)
95
  $this->updateStock($product->getProductId());
96
  }
97
 
98
+ public function deleteProductsStoreIndices(Varien_Object $event)
99
  {
100
  $storeId = $event->getStoreId();
101
 
102
+ $this->helper->deleteProductsStoreIndices($storeId);
103
+ }
104
+
105
+ public function deleteCategoriesStoreIndices(Varien_Object $event)
106
+ {
107
+ $storeId = $event->getStoreId();
108
+
109
+ $this->helper->deleteCategoriesStoreIndices($storeId);
110
  }
111
 
112
  public function removeProducts(Varien_Object $event)
app/code/community/Algolia/Algoliasearch/Model/Resource/Engine.php CHANGED
@@ -128,7 +128,7 @@ class Algolia_Algoliasearch_Model_Resource_Engine extends Mage_CatalogSearch_Mod
128
  return $this;
129
  }
130
 
131
- public function rebuildProductsAndCategories()
132
  {
133
  Mage::getSingleton('algoliasearch/observer')->saveSettings();
134
 
@@ -137,12 +137,27 @@ class Algolia_Algoliasearch_Model_Resource_Engine extends Mage_CatalogSearch_Mod
137
  if ($store->getIsActive())
138
  {
139
  $this->_rebuildProductIndex($store->getId(), array());
 
 
 
 
 
 
 
140
 
 
 
 
 
 
 
 
 
141
  $this->addToQueue('algoliasearch/observer', 'rebuildCategoryIndex', array('store_id' => $store->getId(), 'category_ids' => array()), $this->config->getQueueMaxRetries());
142
  }
143
  else
144
  {
145
- $this->addToQueue('algoliasearch/observer', 'deleteProductsAndCategoriesStoreIndices', array('store_id' => $store->getId()), $this->config->getQueueMaxRetries());
146
  }
147
  }
148
  }
128
  return $this;
129
  }
130
 
131
+ public function rebuildProducts()
132
  {
133
  Mage::getSingleton('algoliasearch/observer')->saveSettings();
134
 
137
  if ($store->getIsActive())
138
  {
139
  $this->_rebuildProductIndex($store->getId(), array());
140
+ }
141
+ else
142
+ {
143
+ $this->addToQueue('algoliasearch/observer', 'deleteProductsStoreIndices', array('store_id' => $store->getId()), $this->config->getQueueMaxRetries());
144
+ }
145
+ }
146
+ }
147
 
148
+ public function rebuildCategories()
149
+ {
150
+ Mage::getSingleton('algoliasearch/observer')->saveSettings();
151
+
152
+ foreach (Mage::app()->getStores() as $store)
153
+ {
154
+ if ($store->getIsActive())
155
+ {
156
  $this->addToQueue('algoliasearch/observer', 'rebuildCategoryIndex', array('store_id' => $store->getId(), 'category_ids' => array()), $this->config->getQueueMaxRetries());
157
  }
158
  else
159
  {
160
+ $this->addToQueue('algoliasearch/observer', 'deleteCategoriesStoreIndices', array('store_id' => $store->getId()), $this->config->getQueueMaxRetries());
161
  }
162
  }
163
  }
app/code/community/Algolia/Algoliasearch/etc/config.xml CHANGED
@@ -135,6 +135,9 @@
135
  <algolia_search_indexer>
136
  <model>algoliasearch/indexer_algolia</model>
137
  </algolia_search_indexer>
 
 
 
138
  <algolia_search_indexer_pages>
139
  <model>algoliasearch/indexer_algoliapages</model>
140
  </algolia_search_indexer_pages>
@@ -170,40 +173,40 @@
170
  <is_instant_enabled>1</is_instant_enabled>
171
  </credentials>
172
  <products>
173
- <product_additional_attributes>a:13:{s:18:"_1427959997377_377";a:4:{s:9:"attribute";s:4:"name";s:10:"searchable";s:1:"1";s:11:"retrievable";s:1:"1";s:5:"order";s:7:"ordered";}s:18:"_1427960012597_597";a:4:{s:9:"attribute";s:4:"path";s:10:"searchable";s:1:"1";s:11:"retrievable";s:1:"1";s:5:"order";s:7:"ordered";}s:18:"_1427960251221_221";a:4:{s:9:"attribute";s:17:"short_description";s:10:"searchable";s:1:"1";s:11:"retrievable";s:1:"1";s:5:"order";s:9:"unordered";}s:18:"_1427961262735_735";a:4:{s:9:"attribute";s:10:"categories";s:10:"searchable";s:1:"1";s:11:"retrievable";s:1:"1";s:5:"order";s:7:"ordered";}s:18:"_1427961263735_735";a:4:{s:9:"attribute";s:10:"meta_title";s:10:"searchable";s:1:"1";s:11:"retrievable";s:1:"1";s:5:"order";s:7:"ordered";}s:18:"_1427961264377_377";a:4:{s:9:"attribute";s:12:"meta_keyword";s:10:"searchable";s:1:"1";s:11:"retrievable";s:1:"1";s:5:"order";s:7:"ordered";}s:18:"_1427961289908_908";a:4:{s:9:"attribute";s:16:"meta_description";s:10:"searchable";s:1:"1";s:11:"retrievable";s:1:"1";s:5:"order";s:9:"unordered";}s:18:"_1427961324936_936";a:4:{s:9:"attribute";s:3:"sku";s:10:"searchable";s:1:"1";s:11:"retrievable";s:1:"1";s:5:"order";s:7:"ordered";}s:18:"_1427962021621_621";a:4:{s:9:"attribute";s:14:"price_with_tax";s:10:"searchable";s:1:"0";s:11:"retrievable";s:1:"1";s:5:"order";s:7:"ordered";}s:18:"_1427977839554_554";a:4:{s:9:"attribute";s:11:"ordered_qty";s:10:"searchable";s:1:"0";s:11:"retrievable";s:1:"0";s:5:"order";s:7:"ordered";}s:18:"_1428566173508_508";a:4:{s:9:"attribute";s:9:"stock_qty";s:10:"searchable";s:1:"0";s:11:"retrievable";s:1:"0";s:5:"order";s:7:"ordered";}s:17:"_1433929490023_23";a:4:{s:9:"attribute";s:14:"rating_summary";s:10:"searchable";s:1:"0";s:11:"retrievable";s:1:"1";s:5:"order";s:7:"ordered";}s:18:"_1436178594492_492";a:4:{s:9:"attribute";s:10:"created_at";s:10:"searchable";s:1:"0";s:11:"retrievable";s:1:"0";s:5:"order";s:7:"ordered";}}</product_additional_attributes>
 
 
 
174
  <custom_ranking_product_attributes>a:1:{s:18:"_1427960305274_274";a:2:{s:9:"attribute";s:11:"ordered_qty";s:5:"order";s:4:"desc";}}</custom_ranking_product_attributes>
175
  <results_limit>1000</results_limit>
176
  </products>
177
  <instant>
178
  <replace_categories>1</replace_categories>
179
  <instant_selector>.main</instant_selector>
180
- <facets>a:2:{s:18:"_1432907948596_596";a:4:{s:9:"attribute";s:14:"price_with_tax";s:4:"type";s:6:"slider";s:10:"other_type";s:0:"";s:5:"label";s:5:"Price";}s:18:"_1432907963376_376";a:4:{s:9:"attribute";s:10:"categories";s:4:"type";s:11:"conjunctive";s:10:"other_type";s:0:"";s:5:"label";s:10:"Categories";}}</facets>
181
- <sorts>a:3:{s:18:"_1432908018844_844";a:3:{s:9:"attribute";s:14:"price_with_tax";s:4:"sort";s:3:"asc";s:5:"label";s:12:"Lowest price";}s:18:"_1432908022539_539";a:3:{s:9:"attribute";s:14:"price_with_tax";s:4:"sort";s:4:"desc";s:5:"label";s:13:"Highest price";}s:18:"_1433768597454_454";a:3:{s:9:"attribute";s:10:"created_at";s:4:"sort";s:4:"desc";s:5:"label";s:12:"Newest first";}}</sorts>
 
 
182
  </instant>
183
  <autocomplete>
184
  <additional_sections></additional_sections>
185
  </autocomplete>
186
  <categories>
 
187
  <category_additional_attributes2>a:7:{s:18:"_1427960339954_954";a:4:{s:9:"attribute";s:4:"name";s:10:"searchable";s:1:"1";s:11:"retrievable";s:1:"1";s:5:"order";s:7:"ordered";}s:18:"_1427960354437_437";a:4:{s:9:"attribute";s:4:"path";s:10:"searchable";s:1:"1";s:11:"retrievable";s:1:"1";s:5:"order";s:7:"ordered";}s:18:"_1427961004989_989";a:4:{s:9:"attribute";s:11:"description";s:10:"searchable";s:1:"1";s:11:"retrievable";s:1:"1";s:5:"order";s:9:"unordered";}s:18:"_1427961205511_511";a:4:{s:9:"attribute";s:10:"meta_title";s:10:"searchable";s:1:"1";s:11:"retrievable";s:1:"1";s:5:"order";s:7:"ordered";}s:18:"_1427961216134_134";a:4:{s:9:"attribute";s:13:"meta_keywords";s:10:"searchable";s:1:"1";s:11:"retrievable";s:1:"1";s:5:"order";s:7:"ordered";}s:18:"_1427961216916_916";a:4:{s:9:"attribute";s:16:"meta_description";s:10:"searchable";s:1:"1";s:11:"retrievable";s:1:"1";s:5:"order";s:9:"unordered";}s:18:"_1427977778338_338";a:4:{s:9:"attribute";s:13:"product_count";s:10:"searchable";s:1:"0";s:11:"retrievable";s:1:"1";s:5:"order";s:7:"ordered";}}</category_additional_attributes2>
188
  <custom_ranking_category_attributes>a:1:{s:18:"_1427961035192_192";a:2:{s:9:"attribute";s:13:"product_count";s:5:"order";s:4:"desc";}}</custom_ranking_category_attributes>
189
  </categories>
 
 
 
190
  <suggestions>
 
191
  <min_popularity>100000</min_popularity>
192
  <min_number_of_results>2</min_number_of_results>
193
  </suggestions>
194
  <relevance>
195
  <remove_words_if_no_result>None</remove_words_if_no_result>
196
  </relevance>
197
- <ui>
198
- <number_product_suggestions>3</number_product_suggestions>
199
- <number_product_results>9</number_product_results>
200
- <number_category_suggestions>5</number_category_suggestions>
201
- <number_page_suggestions>3</number_page_suggestions>
202
- <number_query_suggestions>0</number_query_suggestions>
203
- <max_values_per_facet>10</max_values_per_facet>
204
- <remove_branding>0</remove_branding>
205
- <add_to_cart_enable>1</add_to_cart_enable>
206
- </ui>
207
  <queue>
208
  <active>0</active>
209
  <retries>3</retries>
@@ -213,6 +216,7 @@
213
  </queue>
214
  <advanced>
215
  <partial_update>0</partial_update>
 
216
  </advanced>
217
  </algoliasearch>
218
  </default>
135
  <algolia_search_indexer>
136
  <model>algoliasearch/indexer_algolia</model>
137
  </algolia_search_indexer>
138
+ <algolia_search_indexer_cat>
139
+ <model>algoliasearch/indexer_algoliacategories</model>
140
+ </algolia_search_indexer_cat>
141
  <algolia_search_indexer_pages>
142
  <model>algoliasearch/indexer_algoliapages</model>
143
  </algolia_search_indexer_pages>
173
  <is_instant_enabled>1</is_instant_enabled>
174
  </credentials>
175
  <products>
176
+ <number_product_suggestions>3</number_product_suggestions>
177
+ <number_product_results>9</number_product_results>
178
+ <number_product_results_backend>9</number_product_results_backend>
179
+ <product_additional_attributes>a:13:{s:18:"_1427959997377_377";a:4:{s:9:"attribute";s:4:"name";s:10:"searchable";s:1:"1";s:11:"retrievable";s:1:"1";s:5:"order";s:7:"ordered";}s:18:"_1427960012597_597";a:4:{s:9:"attribute";s:4:"path";s:10:"searchable";s:1:"1";s:11:"retrievable";s:1:"1";s:5:"order";s:7:"ordered";}s:18:"_1427960251221_221";a:4:{s:9:"attribute";s:17:"short_description";s:10:"searchable";s:1:"1";s:11:"retrievable";s:1:"1";s:5:"order";s:9:"unordered";}s:18:"_1427961262735_735";a:4:{s:9:"attribute";s:10:"categories";s:10:"searchable";s:1:"1";s:11:"retrievable";s:1:"1";s:5:"order";s:7:"ordered";}s:18:"_1427961263735_735";a:4:{s:9:"attribute";s:10:"meta_title";s:10:"searchable";s:1:"1";s:11:"retrievable";s:1:"1";s:5:"order";s:7:"ordered";}s:18:"_1427961264377_377";a:4:{s:9:"attribute";s:12:"meta_keyword";s:10:"searchable";s:1:"1";s:11:"retrievable";s:1:"1";s:5:"order";s:7:"ordered";}s:18:"_1427961289908_908";a:4:{s:9:"attribute";s:16:"meta_description";s:10:"searchable";s:1:"1";s:11:"retrievable";s:1:"1";s:5:"order";s:9:"unordered";}s:18:"_1427961324936_936";a:4:{s:9:"attribute";s:3:"sku";s:10:"searchable";s:1:"1";s:11:"retrievable";s:1:"1";s:5:"order";s:7:"ordered";}s:18:"_1427962021621_621";a:4:{s:9:"attribute";s:5:"price";s:10:"searchable";s:1:"0";s:11:"retrievable";s:1:"1";s:5:"order";s:7:"ordered";}s:18:"_1427977839554_554";a:4:{s:9:"attribute";s:11:"ordered_qty";s:10:"searchable";s:1:"0";s:11:"retrievable";s:1:"0";s:5:"order";s:7:"ordered";}s:18:"_1428566173508_508";a:4:{s:9:"attribute";s:9:"stock_qty";s:10:"searchable";s:1:"0";s:11:"retrievable";s:1:"0";s:5:"order";s:7:"ordered";}s:17:"_1433929490023_23";a:4:{s:9:"attribute";s:14:"rating_summary";s:10:"searchable";s:1:"0";s:11:"retrievable";s:1:"1";s:5:"order";s:7:"ordered";}s:18:"_1436178594492_492";a:4:{s:9:"attribute";s:10:"created_at";s:10:"searchable";s:1:"0";s:11:"retrievable";s:1:"0";s:5:"order";s:7:"ordered";}}</product_additional_attributes>
180
  <custom_ranking_product_attributes>a:1:{s:18:"_1427960305274_274";a:2:{s:9:"attribute";s:11:"ordered_qty";s:5:"order";s:4:"desc";}}</custom_ranking_product_attributes>
181
  <results_limit>1000</results_limit>
182
  </products>
183
  <instant>
184
  <replace_categories>1</replace_categories>
185
  <instant_selector>.main</instant_selector>
186
+ <facets>a:2:{s:18:"_1432907948596_596";a:4:{s:9:"attribute";s:5:"price";s:4:"type";s:6:"slider";s:10:"other_type";s:0:"";s:5:"label";s:5:"Price";}s:18:"_1432907963376_376";a:4:{s:9:"attribute";s:10:"categories";s:4:"type";s:11:"conjunctive";s:10:"other_type";s:0:"";s:5:"label";s:10:"Categories";}}</facets>
187
+ <max_values_per_facet>10</max_values_per_facet>
188
+ <sorts>a:3:{s:18:"_1432908018844_844";a:3:{s:9:"attribute";s:5:"price";s:4:"sort";s:3:"asc";s:5:"label";s:12:"Lowest price";}s:18:"_1432908022539_539";a:3:{s:9:"attribute";s:5:"price";s:4:"sort";s:4:"desc";s:5:"label";s:13:"Highest price";}s:18:"_1433768597454_454";a:3:{s:9:"attribute";s:10:"created_at";s:4:"sort";s:4:"desc";s:5:"label";s:12:"Newest first";}}</sorts>
189
+ <add_to_cart_enable>1</add_to_cart_enable>
190
  </instant>
191
  <autocomplete>
192
  <additional_sections></additional_sections>
193
  </autocomplete>
194
  <categories>
195
+ <number_category_suggestions>5</number_category_suggestions>
196
  <category_additional_attributes2>a:7:{s:18:"_1427960339954_954";a:4:{s:9:"attribute";s:4:"name";s:10:"searchable";s:1:"1";s:11:"retrievable";s:1:"1";s:5:"order";s:7:"ordered";}s:18:"_1427960354437_437";a:4:{s:9:"attribute";s:4:"path";s:10:"searchable";s:1:"1";s:11:"retrievable";s:1:"1";s:5:"order";s:7:"ordered";}s:18:"_1427961004989_989";a:4:{s:9:"attribute";s:11:"description";s:10:"searchable";s:1:"1";s:11:"retrievable";s:1:"1";s:5:"order";s:9:"unordered";}s:18:"_1427961205511_511";a:4:{s:9:"attribute";s:10:"meta_title";s:10:"searchable";s:1:"1";s:11:"retrievable";s:1:"1";s:5:"order";s:7:"ordered";}s:18:"_1427961216134_134";a:4:{s:9:"attribute";s:13:"meta_keywords";s:10:"searchable";s:1:"1";s:11:"retrievable";s:1:"1";s:5:"order";s:7:"ordered";}s:18:"_1427961216916_916";a:4:{s:9:"attribute";s:16:"meta_description";s:10:"searchable";s:1:"1";s:11:"retrievable";s:1:"1";s:5:"order";s:9:"unordered";}s:18:"_1427977778338_338";a:4:{s:9:"attribute";s:13:"product_count";s:10:"searchable";s:1:"0";s:11:"retrievable";s:1:"1";s:5:"order";s:7:"ordered";}}</category_additional_attributes2>
197
  <custom_ranking_category_attributes>a:1:{s:18:"_1427961035192_192";a:2:{s:9:"attribute";s:13:"product_count";s:5:"order";s:4:"desc";}}</custom_ranking_category_attributes>
198
  </categories>
199
+ <pages>
200
+ <number_page_suggestions>3</number_page_suggestions>
201
+ </pages>
202
  <suggestions>
203
+ <number_query_suggestions>0</number_query_suggestions>
204
  <min_popularity>100000</min_popularity>
205
  <min_number_of_results>2</min_number_of_results>
206
  </suggestions>
207
  <relevance>
208
  <remove_words_if_no_result>None</remove_words_if_no_result>
209
  </relevance>
 
 
 
 
 
 
 
 
 
 
210
  <queue>
211
  <active>0</active>
212
  <retries>3</retries>
216
  </queue>
217
  <advanced>
218
  <partial_update>0</partial_update>
219
+ <remove_branding>0</remove_branding>
220
  </advanced>
221
  </algoliasearch>
222
  </default>
app/code/community/Algolia/Algoliasearch/etc/system.xml CHANGED
@@ -4,7 +4,7 @@
4
  <algoliasearch translate="label" module="algoliasearch">
5
  <label>
6
  <![CDATA[
7
- Algolia Search 1.4.5
8
  <style>
9
  .algoliasearch-admin-menu span {
10
  padding-left: 38px !important;
@@ -123,11 +123,31 @@
123
  ]]>
124
  </comment>
125
  <fields>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
126
  <product_additional_attributes translate="label comment">
127
  <label>Attributes</label>
128
  <frontend_model>algoliasearch/system_config_form_field_customsortorderproduct</frontend_model>
129
  <backend_model>adminhtml/system_config_backend_serialized_array</backend_model>
130
- <sort_order>10</sort_order>
131
  <show_in_default>1</show_in_default>
132
  <show_in_website>1</show_in_website>
133
  <show_in_store>1</show_in_store>
@@ -142,7 +162,7 @@
142
  <label>Ranking</label>
143
  <frontend_model>algoliasearch/system_config_form_field_customrankingproduct</frontend_model>
144
  <backend_model>adminhtml/system_config_backend_serialized_array</backend_model>
145
- <sort_order>12</sort_order>
146
  <show_in_default>1</show_in_default>
147
  <show_in_website>1</show_in_website>
148
  <show_in_store>1</show_in_store>
@@ -189,26 +209,65 @@
189
  <show_in_store>1</show_in_store>
190
  <comment>Configure here the filtering options you want to display on your search results page. Choose Disjunctive to allow the selection of different values of a facet (e.g. hotels with 4 OR 5 stars). Choose Conjunctive to allow the selection of only one value of a facet (e.g. only "Size M").</comment>
191
  </facets>
 
 
 
 
 
 
 
 
 
 
192
  <sorts>
193
  <label>Sorts</label>
194
  <frontend_model>algoliasearch/system_config_form_field_sorts</frontend_model>
195
  <backend_model>adminhtml/system_config_backend_serialized_array</backend_model>
196
- <sort_order>40</sort_order>
197
  <show_in_default>1</show_in_default>
198
  <show_in_website>1</show_in_website>
199
  <show_in_store>1</show_in_store>
200
- <comment>Configure here the different sorting options you want to offer.</comment>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
201
  </sorts>
202
  <replace_categories translate="label comment">
203
  <label>Replace categories page</label>
204
  <frontend_type>select</frontend_type>
205
  <source_model>adminhtml/system_config_source_yesno</source_model>
206
- <sort_order>50</sort_order>
207
  <show_in_default>1</show_in_default>
208
  <show_in_website>1</show_in_website>
209
  <show_in_store>1</show_in_store>
210
  <comment>Choose here if you want the default Magento category pages to be replaced by an instant-search results page when a category is selected either in the menu of categories or in the drop-down menu.</comment>
211
  </replace_categories>
 
 
 
 
 
 
 
 
 
 
212
  </fields>
213
  </instant>
214
  <categories translate="label">
@@ -226,6 +285,16 @@
226
  ]]>
227
  </comment>
228
  <fields>
 
 
 
 
 
 
 
 
 
 
229
  <category_additional_attributes2 translate="label comment">
230
  <label>Attributes</label>
231
  <frontend_model>algoliasearch/system_config_form_field_customsortordercategory</frontend_model>
@@ -273,6 +342,16 @@
273
  ]]>
274
  </comment>
275
  <fields>
 
 
 
 
 
 
 
 
 
 
276
  <excluded_pages translate="label comment">
277
  <label>Excluded Pages</label>
278
  <frontend_model>algoliasearch/system_config_form_field_custompages</frontend_model>
@@ -305,6 +384,16 @@
305
  ]]>
306
  </comment>
307
  <fields>
 
 
 
 
 
 
 
 
 
 
308
  <min_popularity translate="label comment">
309
  <label>Min popularity</label>
310
  <frontend_type>text</frontend_type>
@@ -385,103 +474,6 @@
385
  </remove_words_if_no_result>
386
  </fields>
387
  </relevance>
388
- <ui translate="label">
389
- <label>UI Configuration</label>
390
- <frontend_type>text</frontend_type>
391
- <sort_order>60</sort_order>
392
- <show_in_default>1</show_in_default>
393
- <show_in_website>1</show_in_website>
394
- <show_in_store>1</show_in_store>
395
- <expanded>1</expanded>
396
- <comment>
397
- <![CDATA[
398
- <font size="2"> Watch the <a href="https://youtu.be/DUuv9ALS5cM?t=911" target="_blank"><font color="#0066cc">Tutorial</font></a><br /n>
399
- </font>
400
- ]]>
401
- </comment>
402
- <fields>
403
- <number_product_suggestions translate="label comment">
404
- <label>Number of product suggestions</label>
405
- <frontend_type>text</frontend_type>
406
- <validate>validate-digits</validate>
407
- <sort_order>10</sort_order>
408
- <show_in_default>1</show_in_default>
409
- <show_in_website>1</show_in_website>
410
- <show_in_store>1</show_in_store>
411
- <comment>The number of product results displayed in the drop-down menu. Default value is 3. Set the value to 0 if you do not want to display the products section in the menu.</comment>
412
- </number_product_suggestions>
413
- <number_product_results translate="label comment">
414
- <label>Number of products per page</label>
415
- <frontend_type>text</frontend_type>
416
- <validate>validate-digits</validate>
417
- <sort_order>50</sort_order>
418
- <show_in_default>1</show_in_default>
419
- <show_in_website>1</show_in_website>
420
- <show_in_store>1</show_in_store>
421
- <comment>The number of products displayed on the search results page. Default value is 9.</comment>
422
- </number_product_results>
423
- <number_category_suggestions translate="label comment">
424
- <label>Number of category suggestions</label>
425
- <frontend_type>text</frontend_type>
426
- <validate>validate-digits</validate>
427
- <sort_order>20</sort_order>
428
- <show_in_default>1</show_in_default>
429
- <show_in_website>1</show_in_website>
430
- <show_in_store>1</show_in_store>
431
- <comment>The number of category results displayed in the drop-down menu. Default value is 5. Set the value to 0 if you do not want to display the categories section in the menu.</comment>
432
- </number_category_suggestions>
433
- <number_page_suggestions translate="label comment">
434
- <label>Number of page suggestions</label>
435
- <frontend_type>text</frontend_type>
436
- <validate>validate-digits</validate>
437
- <sort_order>40</sort_order>
438
- <show_in_default>1</show_in_default>
439
- <show_in_website>1</show_in_website>
440
- <show_in_store>1</show_in_store>
441
- <comment>The number of page suggestions displayed in the drop-down menu. Default value is 3. Set the value to 0 if you do not want to display the pages section in the menu.</comment>
442
- </number_page_suggestions>
443
- <number_query_suggestions translate="label comment">
444
- <label>Number of query suggestions</label>
445
- <frontend_type>text</frontend_type>
446
- <validate>validate-digits</validate>
447
- <sort_order>30</sort_order>
448
- <show_in_default>1</show_in_default>
449
- <show_in_website>1</show_in_website>
450
- <show_in_store>1</show_in_store>
451
- <comment>The number of query suggestions displayed in the drop-down menu. Default value is 0.</comment>
452
- </number_query_suggestions>
453
- <max_values_per_facet translate="label comment">
454
- <label>Number of values per facet</label>
455
- <frontend_type>text</frontend_type>
456
- <validate>validate-digits</validate>
457
- <sort_order>60</sort_order>
458
- <show_in_default>1</show_in_default>
459
- <show_in_website>1</show_in_website>
460
- <show_in_store>1</show_in_store>
461
- <comment>The number of values each facet can display. Default value is 10.</comment>
462
- </max_values_per_facet>
463
- <remove_branding translate="label comment">
464
- <label>Remove branding logo</label>
465
- <frontend_type>select</frontend_type>
466
- <source_model>adminhtml/system_config_source_yesno</source_model>
467
- <sort_order>70</sort_order>
468
- <show_in_default>1</show_in_default>
469
- <show_in_website>1</show_in_website>
470
- <show_in_store>1</show_in_store>
471
- <comment>Choose here if the algolia logo is added to the drop-down template.</comment>
472
- </remove_branding>
473
- <add_to_cart_enable translate="label comment">
474
- <label>Add to Cart</label>
475
- <frontend_type>select</frontend_type>
476
- <source_model>adminhtml/system_config_source_yesno</source_model>
477
- <sort_order>80</sort_order>
478
- <show_in_default>1</show_in_default>
479
- <show_in_website>1</show_in_website>
480
- <show_in_store>1</show_in_store>
481
- <comment>Choose here if you want to add an "add to cart" button in the template.</comment>
482
- </add_to_cart_enable>
483
- </fields>
484
- </ui>
485
  <queue translate="label">
486
  <label>Queue Configuration</label>
487
  <expanded>1</expanded>
@@ -588,6 +580,16 @@
588
  ]]>
589
  </comment>
590
  </customer_groups_enable>
 
 
 
 
 
 
 
 
 
 
591
  </fields>
592
  </advanced>
593
  </groups>
4
  <algoliasearch translate="label" module="algoliasearch">
5
  <label>
6
  <![CDATA[
7
+ Algolia Search 1.4.6
8
  <style>
9
  .algoliasearch-admin-menu span {
10
  padding-left: 38px !important;
123
  ]]>
124
  </comment>
125
  <fields>
126
+ <number_product_suggestions translate="label comment">
127
+ <label>Number of product suggestions in the dropdown menu</label>
128
+ <frontend_type>text</frontend_type>
129
+ <validate>validate-digits</validate>
130
+ <sort_order>0</sort_order>
131
+ <show_in_default>1</show_in_default>
132
+ <show_in_website>1</show_in_website>
133
+ <show_in_store>1</show_in_store>
134
+ <comment>The number of product results displayed in the drop-down menu. Default value is 3. Set the value to 0 if you do not want to display the products section in the menu.</comment>
135
+ </number_product_suggestions>
136
+ <number_product_results translate="label comment">
137
+ <label>Number of products per page in the instant result page</label>
138
+ <frontend_type>text</frontend_type>
139
+ <validate>validate-digits</validate>
140
+ <sort_order>10</sort_order>
141
+ <show_in_default>1</show_in_default>
142
+ <show_in_website>1</show_in_website>
143
+ <show_in_store>1</show_in_store>
144
+ <comment>The number of products displayed on the instant search results page. Default value is 9.</comment>
145
+ </number_product_results>
146
  <product_additional_attributes translate="label comment">
147
  <label>Attributes</label>
148
  <frontend_model>algoliasearch/system_config_form_field_customsortorderproduct</frontend_model>
149
  <backend_model>adminhtml/system_config_backend_serialized_array</backend_model>
150
+ <sort_order>30</sort_order>
151
  <show_in_default>1</show_in_default>
152
  <show_in_website>1</show_in_website>
153
  <show_in_store>1</show_in_store>
162
  <label>Ranking</label>
163
  <frontend_model>algoliasearch/system_config_form_field_customrankingproduct</frontend_model>
164
  <backend_model>adminhtml/system_config_backend_serialized_array</backend_model>
165
+ <sort_order>40</sort_order>
166
  <show_in_default>1</show_in_default>
167
  <show_in_website>1</show_in_website>
168
  <show_in_store>1</show_in_store>
209
  <show_in_store>1</show_in_store>
210
  <comment>Configure here the filtering options you want to display on your search results page. Choose Disjunctive to allow the selection of different values of a facet (e.g. hotels with 4 OR 5 stars). Choose Conjunctive to allow the selection of only one value of a facet (e.g. only "Size M").</comment>
211
  </facets>
212
+ <max_values_per_facet translate="label comment">
213
+ <label>Number of values per facet</label>
214
+ <frontend_type>text</frontend_type>
215
+ <validate>validate-digits</validate>
216
+ <sort_order>40</sort_order>
217
+ <show_in_default>1</show_in_default>
218
+ <show_in_website>1</show_in_website>
219
+ <show_in_store>1</show_in_store>
220
+ <comment>The number of values each facet can display. Default value is 10.</comment>
221
+ </max_values_per_facet>
222
  <sorts>
223
  <label>Sorts</label>
224
  <frontend_model>algoliasearch/system_config_form_field_sorts</frontend_model>
225
  <backend_model>adminhtml/system_config_backend_serialized_array</backend_model>
226
+ <sort_order>50</sort_order>
227
  <show_in_default>1</show_in_default>
228
  <show_in_website>1</show_in_website>
229
  <show_in_store>1</show_in_store>
230
+ <comment>
231
+ Configure here the different sorting options you want to offer.
232
+
233
+ <![CDATA[
234
+ <br /><br />
235
+ The extension will create :<br />
236
+ - 1 index/store<br />
237
+ - 1 index/store/sort<br /><br />
238
+ Which means that for a store with:<br />
239
+
240
+ - 2 store (2 languages for example)<br />
241
+ - 100 products<br />
242
+ - 2 sorts on price (asc, desc)<br />
243
+ - 2 sorts on date (asc, desc)<br /><br />
244
+
245
+ You have 100 * 2 + 100 * 4 * 2 = 1000 product records
246
+
247
+ You can reduce the number of records by removing some sort
248
+ ]]>
249
+ </comment>
250
  </sorts>
251
  <replace_categories translate="label comment">
252
  <label>Replace categories page</label>
253
  <frontend_type>select</frontend_type>
254
  <source_model>adminhtml/system_config_source_yesno</source_model>
255
+ <sort_order>60</sort_order>
256
  <show_in_default>1</show_in_default>
257
  <show_in_website>1</show_in_website>
258
  <show_in_store>1</show_in_store>
259
  <comment>Choose here if you want the default Magento category pages to be replaced by an instant-search results page when a category is selected either in the menu of categories or in the drop-down menu.</comment>
260
  </replace_categories>
261
+ <add_to_cart_enable translate="label comment">
262
+ <label>Add to Cart</label>
263
+ <frontend_type>select</frontend_type>
264
+ <source_model>adminhtml/system_config_source_yesno</source_model>
265
+ <sort_order>70</sort_order>
266
+ <show_in_default>1</show_in_default>
267
+ <show_in_website>1</show_in_website>
268
+ <show_in_store>1</show_in_store>
269
+ <comment>Choose here if you want to add an "add to cart" button in the template.</comment>
270
+ </add_to_cart_enable>
271
  </fields>
272
  </instant>
273
  <categories translate="label">
285
  ]]>
286
  </comment>
287
  <fields>
288
+ <number_category_suggestions translate="label comment">
289
+ <label>Number of category suggestions</label>
290
+ <frontend_type>text</frontend_type>
291
+ <validate>validate-digits</validate>
292
+ <sort_order>0</sort_order>
293
+ <show_in_default>1</show_in_default>
294
+ <show_in_website>1</show_in_website>
295
+ <show_in_store>1</show_in_store>
296
+ <comment>The number of category results displayed in the drop-down menu. Default value is 5. Set the value to 0 if you do not want to display the categories section in the menu.</comment>
297
+ </number_category_suggestions>
298
  <category_additional_attributes2 translate="label comment">
299
  <label>Attributes</label>
300
  <frontend_model>algoliasearch/system_config_form_field_customsortordercategory</frontend_model>
342
  ]]>
343
  </comment>
344
  <fields>
345
+ <number_page_suggestions translate="label comment">
346
+ <label>Number of page suggestions</label>
347
+ <frontend_type>text</frontend_type>
348
+ <validate>validate-digits</validate>
349
+ <sort_order>0</sort_order>
350
+ <show_in_default>1</show_in_default>
351
+ <show_in_website>1</show_in_website>
352
+ <show_in_store>1</show_in_store>
353
+ <comment>The number of page suggestions displayed in the drop-down menu. Default value is 3. Set the value to 0 if you do not want to display the pages section in the menu.</comment>
354
+ </number_page_suggestions>
355
  <excluded_pages translate="label comment">
356
  <label>Excluded Pages</label>
357
  <frontend_model>algoliasearch/system_config_form_field_custompages</frontend_model>
384
  ]]>
385
  </comment>
386
  <fields>
387
+ <number_query_suggestions translate="label comment">
388
+ <label>Number of query suggestions</label>
389
+ <frontend_type>text</frontend_type>
390
+ <validate>validate-digits</validate>
391
+ <sort_order>0</sort_order>
392
+ <show_in_default>1</show_in_default>
393
+ <show_in_website>1</show_in_website>
394
+ <show_in_store>1</show_in_store>
395
+ <comment>The number of query suggestions displayed in the drop-down menu. Default value is 0.</comment>
396
+ </number_query_suggestions>
397
  <min_popularity translate="label comment">
398
  <label>Min popularity</label>
399
  <frontend_type>text</frontend_type>
474
  </remove_words_if_no_result>
475
  </fields>
476
  </relevance>
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
477
  <queue translate="label">
478
  <label>Queue Configuration</label>
479
  <expanded>1</expanded>
580
  ]]>
581
  </comment>
582
  </customer_groups_enable>
583
+ <remove_branding translate="label comment">
584
+ <label>Remove branding logo</label>
585
+ <frontend_type>select</frontend_type>
586
+ <source_model>adminhtml/system_config_source_yesno</source_model>
587
+ <sort_order>30</sort_order>
588
+ <show_in_default>1</show_in_default>
589
+ <show_in_website>1</show_in_website>
590
+ <show_in_store>1</show_in_store>
591
+ <comment>Choose here if the algolia logo is added to the drop-down template.</comment>
592
+ </remove_branding>
593
  </fields>
594
  </advanced>
595
  </groups>
app/design/frontend/base/default/template/algoliasearch/topsearch.phtml CHANGED
@@ -15,7 +15,7 @@ $price_key = '.default';
15
 
16
  if ($config->isCustomerGroupsEnabled(Mage::app()->getStore()->getStoreId()))
17
  {
18
- $price_key = '.'.$group_id;
19
  }
20
 
21
  $title = '';
@@ -169,30 +169,18 @@ $class = $isSearchPage ? 'search-page' : '';
169
  {{#thumbnail_url}}
170
  <div class="thumb"><img src="{{thumbnail_url}}" /></div>
171
  {{/thumbnail_url}}
172
- {{#price_with_tax<?php echo $price_key; ?>}}
173
  <div class="algoliasearch-autocomplete-price">
174
- {{#special_price_with_tax<?php echo $price_key; ?>}}
175
- <div class="after_special">
176
- {{special_price_with_tax_formated<?php echo $price_key; ?>}}
177
- </div>
178
- {{/special_price_with_tax<?php echo $price_key; ?>}}
179
- <div {{#special_price_with_tax<?php echo $price_key; ?>}}class="before_special"{{/special_price_with_tax<?php echo $price_key; ?>}}>
180
- {{price_with_tax_formated<?php echo $price_key; ?>}}
181
- </div>
 
182
  </div>
183
- {{/price_with_tax<?php echo $price_key; ?>}}
184
-
185
- {{^price_with_tax<?php echo $price_key; ?>}}
186
- <div class="algoliasearch-autocomplete-price">
187
- <div class="after_special">
188
- {{#min_with_tax_formated<?php echo $price_key; ?>}}
189
- {{min_with_tax_formated<?php echo $price_key; ?>}} - {{max_with_tax_formated<?php echo $price_key; ?>}}
190
- {{/min_with_tax_formated<?php echo $price_key; ?>}}
191
- {{^min_with_tax_formated<?php echo $price_key; ?>}}-{{/min_with_tax_formated<?php echo $price_key; ?>}}
192
- </div>
193
- </div>
194
- {{/price_with_tax<?php echo $price_key; ?>}}
195
-
196
 
197
  <div class="info">
198
  {{{_highlightResult.name.value}}}
@@ -385,28 +373,15 @@ $class = $isSearchPage ? 'search-page' : '';
385
  <div class="price">
386
  <div class="algoliasearch-autocomplete-price">
387
  <div>
388
- {{#special_price_with_tax<?php echo $price_key; ?>}}
389
  <span class="after_special">
390
- {{special_price_with_tax_formated<?php echo $price_key; ?>}}
391
- </span>
392
- {{/special_price_with_tax<?php echo $price_key; ?>}}
393
-
394
- {{#special_price_with_tax<?php echo $price_key; ?>}}
395
- <span class="before_special">
396
- {{/special_price_with_tax<?php echo $price_key; ?>}}
397
-
398
- {{#price_with_tax<?php echo $price_key; ?>}}{{price_with_tax_formated<?php echo $price_key; ?>}}{{/price_with_tax<?php echo $price_key; ?>}}
399
- {{^price_with_tax<?php echo $price_key; ?>}}
400
- {{#min_with_tax_formated<?php echo $price_key; ?>}}
401
- {{min_with_tax_formated<?php echo $price_key; ?>}} - {{max_with_tax_formated<?php echo $price_key; ?>}}
402
- {{/min_with_tax_formated<?php echo $price_key; ?>}}
403
- {{^min_with_tax_formated<?php echo $price_key; ?>}}-{{/min_with_tax_formated<?php echo $price_key; ?>}}
404
- {{/price_with_tax<?php echo $price_key; ?>}}
405
-
406
- {{#special_price_with_tax<?php echo $price_key; ?>}}
407
  </span>
408
- {{/special_price_with_tax<?php echo $price_key; ?>}}
409
 
 
 
 
 
 
410
  </div>
411
  </div>
412
  </div>
@@ -652,7 +627,6 @@ $class = $isSearchPage ? 'search-page' : '';
652
 
653
  if (algoliaConfig.facets[i].type == "hierarchical")
654
  {
655
-
656
  var hierarchical_levels = [];
657
 
658
  for (var l = 0; l < 10; l++)
@@ -1374,6 +1348,14 @@ $class = $isSearchPage ? 'search-page' : '';
1374
  delete content.hits[i].special_price_formated;
1375
  delete content.hits[i].special_price_with_tax_formated;
1376
  }
 
 
 
 
 
 
 
 
1377
  }
1378
 
1379
  /**
15
 
16
  if ($config->isCustomerGroupsEnabled(Mage::app()->getStore()->getStoreId()))
17
  {
18
+ $price_key = '.group_'.$group_id;
19
  }
20
 
21
  $title = '';
169
  {{#thumbnail_url}}
170
  <div class="thumb"><img src="{{thumbnail_url}}" /></div>
171
  {{/thumbnail_url}}
172
+
173
  <div class="algoliasearch-autocomplete-price">
174
+ <span class="after_special">
175
+ {{price<?php echo $price_key; ?>_formated}}
176
+ </span>
177
+
178
+ {{#price<?php echo $price_key; ?>_original_formated}}
179
+ <span class="before_special">
180
+ {{price<?php echo $price_key; ?>_original_formated}}
181
+ </span>
182
+ {{/price<?php echo $price_key; ?>_original_formated}}
183
  </div>
 
 
 
 
 
 
 
 
 
 
 
 
 
184
 
185
  <div class="info">
186
  {{{_highlightResult.name.value}}}
373
  <div class="price">
374
  <div class="algoliasearch-autocomplete-price">
375
  <div>
 
376
  <span class="after_special">
377
+ {{price<?php echo $price_key; ?>_formated}}
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
378
  </span>
 
379
 
380
+ {{#price<?php echo $price_key; ?>_original_formated}}
381
+ <span class="before_special">
382
+ {{price<?php echo $price_key; ?>_original_formated}}
383
+ </span>
384
+ {{/price<?php echo $price_key; ?>_original_formated}}
385
  </div>
386
  </div>
387
  </div>
627
 
628
  if (algoliaConfig.facets[i].type == "hierarchical")
629
  {
 
630
  var hierarchical_levels = [];
631
 
632
  for (var l = 0; l < 10; l++)
1348
  delete content.hits[i].special_price_formated;
1349
  delete content.hits[i].special_price_with_tax_formated;
1350
  }
1351
+
1352
+ if (content.hits[i].min_formated !== undefined)
1353
+ {
1354
+ delete content.hits[i].price;
1355
+ delete content.hits[i].price_formated;
1356
+ delete content.hits[i].price_with_tax;
1357
+ delete content.hits[i].price_with_tax_formated;
1358
+ }
1359
  }
1360
 
1361
  /**
package.xml CHANGED
@@ -1,7 +1,7 @@
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>algoliasearch</name>
4
- <version>1.4.5</version>
5
  <stability>stable</stability>
6
  <license uri="https://github.com/algolia/algoliasearch-magento/blob/master/LICENSE.txt">MIT</license>
7
  <channel>community</channel>
@@ -11,12 +11,14 @@
11
  &#xD;
12
  This extension replaces Magento's FullText Search module and provide an as-you-type auto-completion menu in your searchbar.&#xD;
13
  </description>
14
- <notes>- FIX: Improve performance issue when backend-search&#xD;
15
- - FIX: Various small improvements</notes>
 
 
16
  <authors><author><name>Algolia Team</name><user>algolia</user><email>support@algolia.com</email></author></authors>
17
- <date>2015-09-21</date>
18
- <time>07:30:36</time>
19
- <contents><target name="mageetc"><dir name="modules"><file name="Algolia_Algoliasearch.xml" hash="17a1452f533423291332642969b41a53"/></dir></target><target name="magecommunity"><dir name="Algolia"><dir name="Algoliasearch"><dir name="Block"><dir name="System"><dir name="Config"><dir name="Form"><dir name="Field"><file name="Additionalsections.php" hash="b2514910e3b56745e66239d5ee916331"/><file name="Custompages.php" hash="f87a9cf7b5559717cd9d6570374dcda7"/><file name="Customrankingcategory.php" hash="6d9575c12dbaecf9054de1cf12736025"/><file name="Customrankingproduct.php" hash="6d1b145e37c4f22d5b56f5783ac47511"/><file name="Customsortorder.php" hash="786c8f8fca2e4b41b8732f5fe270491b"/><file name="Customsortordercategory.php" hash="9908ea7f463138d3047c51b98591db9c"/><file name="Customsortorderproduct.php" hash="ee62901a3911bb7784467e1ca5cd8e84"/><file name="Facets.php" hash="097998767edeee986958f421979ea141"/><file name="Select.php" hash="6e3cb4c1798775048bebbdc878e90aa9"/><file name="Sorts.php" hash="fede73c4ecbe39bf0344fbf6de46ed95"/></dir></dir></dir></dir></dir><dir name="Helper"><file name="Algoliahelper.php" hash="ff48a4929fffd913da57868457ace02f"/><file name="Config.php" hash="2c4ccdf65066df3be068d87b4bbe3871"/><file name="Data.php" hash="791485161a9137bde154e17733dea674"/><dir name="Entity"><file name="Additionalsectionshelper.php" hash="5d20d805b31b7dec4feb943c5e6a96ef"/><file name="Categoryhelper.php" hash="0ec97836a0c1de3e3e22ce462fc756c7"/><file name="Helper.php" hash="3b6025b96ac4e41af10953f012abb77a"/><file name="Pagehelper.php" hash="7a0dcb237f6720d1637c48fc05a7d45e"/><file name="Producthelper.php" hash="6368487459472f135172e1a822115f84"/><file name="Suggestionhelper.php" hash="52f709b27a94c66aa9f7af8648dcb30a"/></dir></dir><dir name="Model"><dir name="Indexer"><file name="Algolia.php" hash="d0de03ed94ee19495fbb8703151c95f4"/><file name="Algoliaadditionalsections.php" hash="3113413441afccba3b8e79aa9fd8cdb1"/><file name="Algoliapages.php" hash="26ea3afee58d07b721c5cd74b3d6c4e3"/><file name="Algoliasuggestions.php" hash="7020d40bae60469d0acc7138ee72a419"/></dir><file name="Observer.php" hash="ebc42a95ceb718ff8dc7ed3e30c16e93"/><file name="Queue.php" hash="4e0c7559dd15b4cbd75cf41ab90f5bdf"/><dir name="Resource"><file name="Engine.php" hash="9322be8fe132f14a03540c4eb4cb5986"/><dir name="Fulltext"><file name="Collection.php" hash="66e8b9af58384bc3a99ee1464cbd3537"/></dir><file name="Fulltext.php" hash="64e54ab51992d455cce9f266db5b8802"/></dir><dir name="System"><file name="Removewords.php" hash="69c9727a324b657f7cfdf7f5d06e3cbc"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="ea4176ed43885e531f90d1f5369f29ee"/><file name="config.xml" hash="40c7c9ffb5140a758fd52723741fccf2"/><file name="system.xml" hash="677b7c93b67bf3372dc15920858cf2f4"/></dir><dir name="sql"><dir name="algoliasearch_setup"><file name="mysql4-install-0.1.0.php" hash="fffd964f9c60be7909ec216260c37ba0"/></dir></dir></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="algoliasearch.xml" hash="f0df0b6ed09d186da4429577aefd346d"/></dir><dir name="template"><dir name="algoliasearch"><file name="topsearch.phtml" hash="27c656b0bc4d9ac9d1fbf12ef8cd9c8b"/></dir></dir></dir></dir></dir></target><target name="mageskin"><dir name="frontend"><dir name="base"><dir name="default"><dir name="algoliasearch"><file name="algolia-admin-menu.png" hash="9202a559c30a43d4d4bbc2f9ee774fd9"/><file name="algolia-logo.png" hash="190884b3e8652f3517754ae15bca31de"/><file name="algoliasearch.css" hash="1b85791da996184de93f54e54feca9c3"/><file name="bundle.css" hash="10df17cf0f50b56246a2ba017adcdae3"/><dir name="images"><file name="ui-bg_diagonals-thick_18_b81900_40x40.png" hash="62568c006bb1066f40fd5f9cfe4489be"/><file name="ui-bg_diagonals-thick_20_666666_40x40.png" hash="406541454ec466d93217826588335194"/><file name="ui-bg_flat_10_000000_40x100.png" hash="85243ed808c91ae60d33bda3a6bdee3c"/><file name="ui-bg_glass_100_f6f6f6_1x400.png" hash="f912ffca9b1919ab26c64cf1332c5322"/><file name="ui-bg_glass_100_fdf5ce_1x400.png" hash="a9b41e3f4db0fb9be1cd2c649deb253f"/><file name="ui-bg_glass_65_ffffff_1x400.png" hash="ff9e9b45e03f11808144324fd5350612"/><file name="ui-bg_gloss-wave_35_f6a828_500x100.png" hash="08ece8908c07b1c0d18b8db076ff50fc"/><file name="ui-bg_highlight-soft_100_eeeeee_1x100.png" hash="72fe4b0e1bbb83dfd6787989d3583fbe"/><file name="ui-bg_highlight-soft_75_ffe45c_1x100.png" hash="81262299ac7f591fd1763c1ccee0691f"/><file name="ui-icons_222222_256x240.png" hash="3a3c5468f484f07ac4a320d9e22acb8c"/><file name="ui-icons_228ef1_256x240.png" hash="92b29683b6a48eae7de7eb4b1cfa039c"/><file name="ui-icons_ef8c08_256x240.png" hash="f492970693640894fb54166c75dd2925"/><file name="ui-icons_ffd27a_256x240.png" hash="dda1b6f694b0d196aefc66a1d6d758f6"/><file name="ui-icons_ffffff_256x240.png" hash="41612b0f4a034424f8321c9f824a94da"/></dir></dir></dir></dir></dir></target><target name="mage"><dir name="js"><dir name="algoliasearch"><file name="bundle.min.js" hash="50dc171cb2cbd89fda2a18a4b64e6e4c"/></dir></dir><dir name="lib"><dir name="AlgoliaSearch"><file name="AlgoliaException.php" hash="4acaa7c9142e19d1084295a3b8ba18e2"/><file name="Client.php" hash="11ad687a9868a9f574ae6a069800dd2c"/><file name="ClientContext.php" hash="77d2449636d263162460a7ccaea4e6b6"/><file name="Index.php" hash="5c1eacc54cd503bff296e9bbbd402895"/><file name="Version.php" hash="0c37eb6324361991364e0efd2696e56d"/><dir name="resources"><file name="ca-bundle.crt" hash="47961e7ef15667c93cd99be01b51f00a"/></dir></dir></dir></target></contents>
20
  <compatible/>
21
  <dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies>
22
  </package>
1
  <?xml version="1.0"?>
2
  <package>
3
  <name>algoliasearch</name>
4
+ <version>1.4.6</version>
5
  <stability>stable</stability>
6
  <license uri="https://github.com/algolia/algoliasearch-magento/blob/master/LICENSE.txt">MIT</license>
7
  <channel>community</channel>
11
  &#xD;
12
  This extension replaces Magento's FullText Search module and provide an as-you-type auto-completion menu in your searchbar.&#xD;
13
  </description>
14
+ <notes>- UPDATED: Price handling, no template update required anymore + correct handling of special price + correct handling of tax&#xD;
15
+ - UPDATED: indexing process has been optimized&#xD;
16
+ - FIX: add emulation for pages to have correct urls&#xD;
17
+ - UPDATED: Separate category and product indexer</notes>
18
  <authors><author><name>Algolia Team</name><user>algolia</user><email>support@algolia.com</email></author></authors>
19
+ <date>2015-09-25</date>
20
+ <time>15:08:07</time>
21
+ <contents><target name="mageetc"><dir name="modules"><file name="Algolia_Algoliasearch.xml" hash="17a1452f533423291332642969b41a53"/></dir></target><target name="magecommunity"><dir name="Algolia"><dir name="Algoliasearch"><dir name="Block"><dir name="System"><dir name="Config"><dir name="Form"><dir name="Field"><file name="Additionalsections.php" hash="b2514910e3b56745e66239d5ee916331"/><file name="Custompages.php" hash="f87a9cf7b5559717cd9d6570374dcda7"/><file name="Customrankingcategory.php" hash="6d9575c12dbaecf9054de1cf12736025"/><file name="Customrankingproduct.php" hash="6d1b145e37c4f22d5b56f5783ac47511"/><file name="Customsortorder.php" hash="786c8f8fca2e4b41b8732f5fe270491b"/><file name="Customsortordercategory.php" hash="9908ea7f463138d3047c51b98591db9c"/><file name="Customsortorderproduct.php" hash="ee62901a3911bb7784467e1ca5cd8e84"/><file name="Facets.php" hash="097998767edeee986958f421979ea141"/><file name="Select.php" hash="6e3cb4c1798775048bebbdc878e90aa9"/><file name="Sorts.php" hash="fede73c4ecbe39bf0344fbf6de46ed95"/></dir></dir></dir></dir></dir><dir name="Helper"><file name="Algoliahelper.php" hash="ff48a4929fffd913da57868457ace02f"/><file name="Config.php" hash="fd857266017bf9cad31542b97946a44f"/><file name="Data.php" hash="5e40a0798f9b7daba8890b231e3148d7"/><dir name="Entity"><file name="Additionalsectionshelper.php" hash="5d20d805b31b7dec4feb943c5e6a96ef"/><file name="Categoryhelper.php" hash="0ec97836a0c1de3e3e22ce462fc756c7"/><file name="Helper.php" hash="e27363827198000e822e14c83e56145e"/><file name="Pagehelper.php" hash="7a0dcb237f6720d1637c48fc05a7d45e"/><file name="Producthelper.php" hash="e7164205971f5468abe8e6ac32b92c6f"/><file name="Suggestionhelper.php" hash="52f709b27a94c66aa9f7af8648dcb30a"/></dir></dir><dir name="Model"><dir name="Indexer"><file name="Algolia.php" hash="a3d5fae92e3fccdee6e50e9a45abe06b"/><file name="Algoliaadditionalsections.php" hash="3113413441afccba3b8e79aa9fd8cdb1"/><file name="Algoliacategories.php" hash="ec552d5cd1492a8d5850b41d2f478a9e"/><file name="Algoliapages.php" hash="26ea3afee58d07b721c5cd74b3d6c4e3"/><file name="Algoliasuggestions.php" hash="7020d40bae60469d0acc7138ee72a419"/></dir><file name="Observer.php" hash="c8cda0056667c096eb1bb1eb2ad38ca9"/><file name="Queue.php" hash="4e0c7559dd15b4cbd75cf41ab90f5bdf"/><dir name="Resource"><file name="Engine.php" hash="ce90cd668327514b77aaea876e18ca99"/><dir name="Fulltext"><file name="Collection.php" hash="66e8b9af58384bc3a99ee1464cbd3537"/></dir><file name="Fulltext.php" hash="64e54ab51992d455cce9f266db5b8802"/></dir><dir name="System"><file name="Removewords.php" hash="69c9727a324b657f7cfdf7f5d06e3cbc"/></dir></dir><dir name="etc"><file name="adminhtml.xml" hash="ea4176ed43885e531f90d1f5369f29ee"/><file name="config.xml" hash="72f70288cf5ad61d42a5c9fa7592510e"/><file name="system.xml" hash="154c0c2147174b3180fbc2cc9f787deb"/></dir><dir name="sql"><dir name="algoliasearch_setup"><file name="mysql4-install-0.1.0.php" hash="fffd964f9c60be7909ec216260c37ba0"/></dir></dir></dir></dir></target><target name="magedesign"><dir name="frontend"><dir name="base"><dir name="default"><dir name="layout"><file name="algoliasearch.xml" hash="f0df0b6ed09d186da4429577aefd346d"/></dir><dir name="template"><dir name="algoliasearch"><file name="topsearch.phtml" hash="4036781635e58d71b8ac242214d067ff"/></dir></dir></dir></dir></dir></target><target name="mageskin"><dir name="frontend"><dir name="base"><dir name="default"><dir name="algoliasearch"><file name="algolia-admin-menu.png" hash="9202a559c30a43d4d4bbc2f9ee774fd9"/><file name="algolia-logo.png" hash="190884b3e8652f3517754ae15bca31de"/><file name="algoliasearch.css" hash="1b85791da996184de93f54e54feca9c3"/><file name="bundle.css" hash="10df17cf0f50b56246a2ba017adcdae3"/><dir name="images"><file name="ui-bg_diagonals-thick_18_b81900_40x40.png" hash="62568c006bb1066f40fd5f9cfe4489be"/><file name="ui-bg_diagonals-thick_20_666666_40x40.png" hash="406541454ec466d93217826588335194"/><file name="ui-bg_flat_10_000000_40x100.png" hash="85243ed808c91ae60d33bda3a6bdee3c"/><file name="ui-bg_glass_100_f6f6f6_1x400.png" hash="f912ffca9b1919ab26c64cf1332c5322"/><file name="ui-bg_glass_100_fdf5ce_1x400.png" hash="a9b41e3f4db0fb9be1cd2c649deb253f"/><file name="ui-bg_glass_65_ffffff_1x400.png" hash="ff9e9b45e03f11808144324fd5350612"/><file name="ui-bg_gloss-wave_35_f6a828_500x100.png" hash="08ece8908c07b1c0d18b8db076ff50fc"/><file name="ui-bg_highlight-soft_100_eeeeee_1x100.png" hash="72fe4b0e1bbb83dfd6787989d3583fbe"/><file name="ui-bg_highlight-soft_75_ffe45c_1x100.png" hash="81262299ac7f591fd1763c1ccee0691f"/><file name="ui-icons_222222_256x240.png" hash="3a3c5468f484f07ac4a320d9e22acb8c"/><file name="ui-icons_228ef1_256x240.png" hash="92b29683b6a48eae7de7eb4b1cfa039c"/><file name="ui-icons_ef8c08_256x240.png" hash="f492970693640894fb54166c75dd2925"/><file name="ui-icons_ffd27a_256x240.png" hash="dda1b6f694b0d196aefc66a1d6d758f6"/><file name="ui-icons_ffffff_256x240.png" hash="41612b0f4a034424f8321c9f824a94da"/></dir></dir></dir></dir></dir></target><target name="mage"><dir name="js"><dir name="algoliasearch"><file name="bundle.min.js" hash="50dc171cb2cbd89fda2a18a4b64e6e4c"/></dir></dir><dir name="lib"><dir name="AlgoliaSearch"><file name="AlgoliaException.php" hash="4acaa7c9142e19d1084295a3b8ba18e2"/><file name="Client.php" hash="11ad687a9868a9f574ae6a069800dd2c"/><file name="ClientContext.php" hash="77d2449636d263162460a7ccaea4e6b6"/><file name="Index.php" hash="5c1eacc54cd503bff296e9bbbd402895"/><file name="Version.php" hash="0c37eb6324361991364e0efd2696e56d"/><dir name="resources"><file name="ca-bundle.crt" hash="47961e7ef15667c93cd99be01b51f00a"/></dir></dir></dir></target></contents>
22
  <compatible/>
23
  <dependencies><required><php><min>5.2.0</min><max>6.0.0</max></php></required></dependencies>
24
  </package>