Skip to content

Commit 6549de5

Browse files
authored
Merge pull request #1031 from algolia/develop
Develop
2 parents 5b1d47f + 79987d5 commit 6549de5

File tree

32 files changed

+1067
-148
lines changed

32 files changed

+1067
-148
lines changed

.styleci.yml

Lines changed: 0 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,5 @@
11
preset: PSR2
22

3-
linting: true
4-
53
enabled:
64
- long_array_syntax
75

.travis.yml

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@ install:
1717
- composer install --no-scripts
1818

1919
before_script:
20-
- wget http://api-key-dealer.herokuapp.com/clients/algolia-keys && chmod +x algolia-keys
20+
- wget https://alg.li/algolia-keys && chmod +x algolia-keys
2121

2222
script:
2323
- eval $(./algolia-keys export) && dev/runTests.sh -a $ALGOLIA_APPLICATION_ID -k $ALGOLIA_API_KEY -s $ALGOLIA_SEARCH_API_KEY -b http://magento.local -p TRAVIS_M1_ -v 193

CHANGELOG.md

Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,34 @@
11
# CHANGE LOG
22

3+
## 1.14.0
4+
5+
### FEATURES
6+
- [Click & Conversion analytics](https://www.algolia.com/doc/guides/analytics/click-analytics/) (#1027) - [Documentation](https://community.algolia.com/magento/doc/m1/click-analytics/)
7+
- Facet query rules (#1025)
8+
- Add option to index empty categories (#992)
9+
- Search for facet values (#1020)
10+
11+
12+
### UPDATES
13+
- Show longest attribute when the record is skipped (#976)
14+
- Add CSS classes to InstantSearch widget containers (#977 )
15+
- Hide the instant-search selector on algoliaConfig variable (#981)
16+
- Escape JS suggestions in autocomplete menu (#984)
17+
- Never index SID in URL (#985)
18+
- Skip rebuilding CMS page(s) when the extension has not been configured (#1000)
19+
- Add "filters" rule to ranking formula (#1005)
20+
- Display default price when customer group is 0 (#1011)
21+
- Automatically delete unused replica indices (#1019)
22+
- Remove category from indexes of all store views (#1028)
23+
24+
### FIXES
25+
- Fix configurable products' prices (#978)
26+
- Fix bug #979 (#980)
27+
- Fix expired special prices (#988)
28+
- Fix special price with customer groups (#997)
29+
- Fix buggy behavior on iOS (#1009)
30+
31+
332
## 1.13.0
433

534
### FEATURES

README.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,7 +1,7 @@
11
Algolia Search for Magento 1.6+
22
==================
33

4-
![Latest version](https://img.shields.io/badge/latest-1.13.0-green.svg)
4+
![Latest version](https://img.shields.io/badge/latest-1.14.0-green.svg)
55

66
[![Build Status](https://travis-ci.org/algolia/algoliasearch-magento.svg?branch=master)](https://travis-ci.org/algolia/algoliasearch-magento)
77
![PHP >= 5.3](https://img.shields.io/badge/php-%3E=5.3-green.svg)

app/code/community/Algolia/Algoliasearch/Block/System/Config/Form/Field/Facets.php

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -41,6 +41,22 @@ public function __construct()
4141
'label' => 'Label',
4242
'style' => 'width: 100px;',
4343
),
44+
'searchable' => array(
45+
'label' => 'Searchable?',
46+
'options' => array(
47+
'1' => 'Yes',
48+
'2' => 'No'
49+
),
50+
'rowMethod' => 'getSearchable',
51+
),
52+
'create_rule' => array(
53+
'label' => 'Create Query rule?',
54+
'options' => array(
55+
'1' => 'Yes',
56+
'2' => 'No'
57+
),
58+
'rowMethod' => 'getCreateRule',
59+
),
4460
),
4561
'buttonLabel' => 'Add Facet',
4662
'addAfter' => false,

app/code/community/Algolia/Algoliasearch/Helper/Algoliahelper.php

Lines changed: 67 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,11 @@ public function resetCredentialsFromConfig()
4747
}
4848
}
4949

50+
public function getClient()
51+
{
52+
return $this->client;
53+
}
54+
5055
public function generateSearchSecuredApiKey($key, $params = array())
5156
{
5257
return $this->client->generateSecuredApiKey($key, $params);
@@ -116,12 +121,17 @@ public function moveIndex($tmpIndexName, $indexName)
116121
$this->lastTaskId = $res['taskID'];
117122
}
118123

124+
public function getSettings($indexName)
125+
{
126+
return $this->getIndex($indexName)->getSettings();
127+
}
128+
119129
public function mergeSettings($indexName, $settings)
120130
{
121131
$onlineSettings = array();
122132

123133
try {
124-
$onlineSettings = $this->getIndex($indexName)->getSettings();
134+
$onlineSettings = $this->getSettings($indexName);
125135
} catch (\Exception $e) {
126136
}
127137

@@ -261,13 +271,20 @@ public function copyQueryRules($fromIndexName, $toIndexName)
261271
$this->lastTaskId = $res['taskID'];
262272
}
263273

264-
public function waitLastTask()
274+
public function waitLastTask($lastUsedIndexName = null, $lastTaskId = null)
265275
{
266-
if (!isset($this->lastUsedIndexName) || !isset($this->lastTaskId)) {
276+
if ($lastUsedIndexName === null && isset($this->lastUsedIndexName)) {
277+
$lastUsedIndexName = $this->lastUsedIndexName;
278+
}
279+
280+
if ($lastTaskId === null && isset($this->lastTaskId)) {
281+
$lastTaskId = $this->lastTaskId;
282+
}
283+
if (!$lastUsedIndexName || !$lastTaskId) {
267284
return;
268285
}
269286

270-
$this->client->initIndex($this->lastUsedIndexName)->waitTask($this->lastTaskId);
287+
$this->client->initIndex($lastUsedIndexName)->waitTask($lastTaskId);
271288
}
272289

273290
private function prepareRecords(&$objects, $indexName)
@@ -282,26 +299,34 @@ private function prepareRecords(&$objects, $indexName)
282299

283300
$previousObject = $object;
284301

285-
$this->handleTooBigRecord($object);
286-
287-
if ($previousObject !== $object) {
288-
$modifiedIds[] = $indexName.' objectID('.$previousObject['objectID'].')';
289-
}
302+
$object = $this->handleTooBigRecord($object);
290303

291304
if ($object === false) {
305+
$longestAttribute = $this->getLongestAttribute($previousObject);
306+
$modifiedIds[] = $indexName.' - ID '.$previousObject['objectID'].' - skipped - longest attribute: '.$longestAttribute;
307+
292308
unset($objects[$key]);
293-
continue;
309+
} elseif ($previousObject !== $object) {
310+
$modifiedIds[] = $indexName.' - ID '.$previousObject['objectID'].' - truncated';
294311
}
295312
}
296313

297314
if (!empty($modifiedIds)) {
315+
$separator = php_sapi_name() === 'cli' ? "\n" : '<br>';
316+
317+
$errorMessage = 'Algolia reindexing: You have some records which are too big to be indexed in Algolia. They have either been truncated (removed attributes: '.implode(', ', $this->potentiallyLongAttributes).') or skipped completely: '.$separator.implode($separator, $modifiedIds);
318+
298319
/** @var Mage_Adminhtml_Model_Session $session */
299320
$session = Mage::getSingleton('adminhtml/session');
300-
$session->addWarning('Algolia reindexing : You have some records ('.implode(',', $modifiedIds).') that are too big. They have either been truncated or skipped.');
321+
$session->addWarning($errorMessage);
322+
323+
if (php_sapi_name() === 'cli') {
324+
echo $errorMessage . "\n";
325+
}
301326
}
302327
}
303328

304-
public function handleTooBigRecord(&$object)
329+
public function handleTooBigRecord($object)
305330
{
306331
$size = mb_strlen(json_encode($object));
307332

@@ -318,5 +343,35 @@ public function handleTooBigRecord(&$object)
318343
$object = false;
319344
}
320345
}
346+
347+
return $object;
348+
}
349+
350+
private function getLongestAttribute($object)
351+
{
352+
$maxLength = 0;
353+
$longestAttribute = '';
354+
355+
foreach ($object as $attribute => $value) {
356+
$attributeLenght = mb_strlen(json_encode($value));
357+
358+
if ($attributeLenght > $maxLength) {
359+
$longestAttribute = $attribute;
360+
361+
$maxLength = $attributeLenght;
362+
}
363+
}
364+
365+
return $longestAttribute;
366+
}
367+
368+
public function getLastIndexName()
369+
{
370+
return $this->lastUsedIndexName;
371+
}
372+
373+
public function getLastTaskId()
374+
{
375+
return $this->lastTaskId;
321376
}
322377
}

app/code/community/Algolia/Algoliasearch/Helper/Config.php

Lines changed: 40 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -47,6 +47,7 @@ class Algolia_Algoliasearch_Helper_Config extends Mage_Core_Helper_Abstract
4747
const INDEX_PRODUCT_COUNT = 'algoliasearch/categories/index_product_count';
4848
const CATEGORY_CUSTOM_RANKING = 'algoliasearch/categories/custom_ranking_category_attributes';
4949
const SHOW_CATS_NOT_INCLUDED_IN_NAVIGATION = 'algoliasearch/categories/show_cats_not_included_in_navigation';
50+
const INDEX_EMPTY_CATEGORIES = 'algoliasearch/categories/index_empty_categories';
5051

5152
const IS_ACTIVE = 'algoliasearch/queue/active';
5253
const NUMBER_OF_ELEMENT_BY_PAGE = 'algoliasearch/queue/number_of_element_by_page';
@@ -59,10 +60,15 @@ class Algolia_Algoliasearch_Helper_Config extends Mage_Core_Helper_Abstract
5960
const XML_PATH_IMAGE_HEIGHT = 'algoliasearch/image/height';
6061
const XML_PATH_IMAGE_TYPE = 'algoliasearch/image/type';
6162

62-
const ENABLE_ANALYTICS = 'algoliasearch/analytics/enable_analytics';
63-
const ANALYTICS_DELAY = 'algoliasearch/analytics/delay';
64-
const ANALYTICS_TRIGGER_ON_UI_INTERACTION = 'algoliasearch/analytics/trigger_on_ui_interaction';
65-
const ANALYTICS_PUSH_INITIAL_SEARCH = 'algoliasearch/analytics/push_initial_search';
63+
const GA_ENABLE = 'algoliasearch/analytics/enable';
64+
const GA_DELAY = 'algoliasearch/analytics/delay';
65+
const GA_TRIGGER_ON_UI_INTERACTION = 'algoliasearch/analytics/trigger_on_ui_interaction';
66+
const GA_PUSH_INITIAL_SEARCH = 'algoliasearch/analytics/push_initial_search';
67+
68+
const CC_ANALYTICS_ENABLE = 'algoliasearch/cc_analytics/enable';
69+
const CC_ANALYTICS_IS_SELECTOR = 'algoliasearch/cc_analytics/is_selector';
70+
const CC_CONVERSION_ANALYTICS_MODE = 'algoliasearch/cc_analytics/conversion_analytics_mode';
71+
const CC_ADD_TO_CART_SELECTOR = 'algoliasearch/cc_analytics/add_to_cart_selector';
6672

6773
const ENABLE_SYNONYMS = 'algoliasearch/synonyms/enable_synonyms';
6874
const SYNONYMS = 'algoliasearch/synonyms/synonyms';
@@ -113,6 +119,11 @@ public function showCatsNotIncludedInNavigation($storeId = null)
113119
return Mage::getStoreConfigFlag(self::SHOW_CATS_NOT_INCLUDED_IN_NAVIGATION, $storeId);
114120
}
115121

122+
public function shouldIndexEmptyCategories($storeId = null)
123+
{
124+
return Mage::getStoreConfigFlag(self::INDEX_EMPTY_CATEGORIES, $storeId);
125+
}
126+
116127
public function isDefaultSelector($storeId = null)
117128
{
118129
return '.algolia-search-input' === $this->getAutocompleteSelector($storeId);
@@ -465,6 +476,7 @@ public function getAttributesToRetrieve($group_id)
465476
$attributes[] = 'price.'.$currency.'.default_formated';
466477
$attributes[] = 'price.'.$currency.'.group_'.$group_id;
467478
$attributes[] = 'price.'.$currency.'.group_'.$group_id.'_formated';
479+
$attributes[] = 'price.'.$currency.'.group_'.$group_id.'_original_formated';
468480
$attributes[] = 'price.'.$currency.'.special_from_date';
469481
$attributes[] = 'price.'.$currency.'.special_to_date';
470482
}
@@ -588,22 +600,42 @@ public function getExtensionVersion()
588600

589601
public function isEnabledAnalytics($storeId = null)
590602
{
591-
return Mage::getStoreConfigFlag(self::ENABLE_ANALYTICS, $storeId);
603+
return Mage::getStoreConfigFlag(self::GA_ENABLE, $storeId);
592604
}
593605

594606
public function getAnalyticsDelay($storeId = null)
595607
{
596-
return (int) Mage::getStoreConfig(self::ANALYTICS_DELAY, $storeId);
608+
return (int) Mage::getStoreConfig(self::GA_DELAY, $storeId);
597609
}
598610

599611
public function getTriggerOnUIInteraction($storeId = null)
600612
{
601-
return Mage::getStoreConfigFlag(self::ANALYTICS_TRIGGER_ON_UI_INTERACTION, $storeId);
613+
return Mage::getStoreConfigFlag(self::GA_TRIGGER_ON_UI_INTERACTION, $storeId);
602614
}
603615

604616
public function getPushInitialSearch($storeId = null)
605617
{
606-
return Mage::getStoreConfigFlag(self::ANALYTICS_PUSH_INITIAL_SEARCH, $storeId);
618+
return Mage::getStoreConfigFlag(self::GA_PUSH_INITIAL_SEARCH, $storeId);
619+
}
620+
621+
public function isClickConversionAnalyticsEnabled($storeId = null)
622+
{
623+
return Mage::getStoreConfigFlag(self::CC_ANALYTICS_ENABLE, $storeId);
624+
}
625+
626+
public function getClickConversionAnalyticsISSelector($storeId = null)
627+
{
628+
return Mage::getStoreConfig(self::CC_ANALYTICS_IS_SELECTOR, $storeId);
629+
}
630+
631+
public function getConversionAnalyticsMode($storeId = null)
632+
{
633+
return Mage::getStoreConfig(self::CC_CONVERSION_ANALYTICS_MODE, $storeId);
634+
}
635+
636+
public function getConversionAnalyticsAddToCartSelector($storeId = null)
637+
{
638+
return Mage::getStoreConfig(self::CC_ADD_TO_CART_SELECTOR, $storeId);
607639
}
608640

609641
public function isEnabledSynonyms($storeId = null)

app/code/community/Algolia/Algoliasearch/Helper/Data.php

Lines changed: 36 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -416,7 +416,7 @@ public function rebuildStoreCategoryIndexPage($storeId, $collectionDefault, $pag
416416

417417
$categoryObject = $this->category_helper->getObject($category);
418418

419-
if ($categoryObject['product_count'] > 0) {
419+
if ($this->config->shouldIndexEmptyCategories($storeId) === true || $categoryObject['product_count'] > 0) {
420420
array_push($indexData, $categoryObject);
421421
}
422422
}
@@ -730,4 +730,39 @@ private function setExtraSettings($storeId, $saveToTmpIndicesToo)
730730
throw new \AlgoliaSearch\AlgoliaException('<br>'.implode('<br> ', $error));
731731
}
732732
}
733+
734+
public function deleteInactiveProducts($storeId)
735+
{
736+
$indexName = $this->product_helper->getIndexName($storeId);
737+
$index = $this->algolia_helper->getIndex($indexName);
738+
739+
$objectIds = array();
740+
$counter = 0;
741+
foreach ($index->browse('', array('attributesToRetrieve' => array('objectID'))) as $hit) {
742+
$objectIds[] = $hit['objectID'];
743+
$counter++;
744+
745+
if ($counter === 1000) {
746+
$this->deleteInactiveIds($storeId, $objectIds, $indexName);
747+
748+
$objectIds = array();
749+
$counter = 0;
750+
}
751+
}
752+
753+
if (!empty($objectIds)) {
754+
$this->deleteInactiveIds($storeId, $objectIds, $indexName);
755+
}
756+
}
757+
758+
private function deleteInactiveIds($storeId, $objectIds, $indexName)
759+
{
760+
$collection = $this->product_helper->getProductCollectionQuery($storeId, $objectIds);
761+
$dbIds = $collection->getAllIds();
762+
763+
$collection = null;
764+
765+
$idsToDeleteFromAlgolia = array_diff($objectIds, $dbIds);
766+
$this->algolia_helper->deleteObjects($idsToDeleteFromAlgolia, $indexName);
767+
}
733768
}

0 commit comments

Comments
 (0)