Skip to content

Commit 1197b1f

Browse files
authored
Merge pull request #1747 from algolia/release/3.16.0-dev
3.16.0-beta.1 release
2 parents 3ecbf4e + 0b75f3f commit 1197b1f

File tree

115 files changed

+7212
-2910
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

115 files changed

+7212
-2910
lines changed
Lines changed: 8 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,8 @@
1+
<?php
2+
3+
namespace Algolia\AlgoliaSearch\Api\Processor;
4+
5+
interface BatchQueueProcessorInterface
6+
{
7+
public function processBatch(int $storeId, ?array $entityIds = null): void;
8+
}

Api/Product/ReplicaManagerInterface.php

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,7 @@ public function syncReplicasToAlgolia(int $storeId, array $primaryIndexSettings)
3131
/**
3232
* Delete the replica indices on a store index
3333
* @param int $storeId
34-
* @param bool $unused Defaults to false - if true identifies any straggler indices and deletes those, otherwise deletes the replicas it knows aobut
34+
* @param bool $unused Defaults to false - if true identifies any straggler indices and deletes those, otherwise deletes the replicas it knows about
3535
* @return void
3636
*
3737
* @throws LocalizedException
Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,61 @@
1+
<?php
2+
3+
namespace Algolia\AlgoliaSearch\Block\Adminhtml\Reindex;
4+
5+
use Algolia\AlgoliaSearch\Helper\ConfigHelper;
6+
use Magento\Backend\Block\Widget\Context;
7+
use Magento\Framework\View\Element\UiComponent\Control\ButtonProviderInterface;
8+
9+
abstract class AbstractReindexAllButton implements ButtonProviderInterface
10+
{
11+
protected string $entity;
12+
13+
protected string $redirectPath;
14+
15+
public function __construct(
16+
protected Context $context,
17+
protected ConfigHelper $configHelper
18+
) {}
19+
20+
/**
21+
* @return string
22+
*/
23+
protected function getEntity(): string
24+
{
25+
return $this->entity;
26+
}
27+
28+
/**
29+
* @return string
30+
*/
31+
protected function getRedirectPath(): string
32+
{
33+
return $this->redirectPath;
34+
}
35+
36+
/**
37+
* @return array
38+
*/
39+
public function getButtonData(): array
40+
{
41+
$entity = $this->getEntity();
42+
$redirectPath = $this->getRedirectPath();
43+
44+
$message = "Are you sure you want to reindex all $entity to Algolia ?";
45+
46+
if (!$this->configHelper->isQueueActive() && $entity === 'products') {
47+
$message .= ' Warning : Your Indexing Queue is not activated. Depending on the size of the data you want to index, it may takes a lot of time and resources.';
48+
$message .= 'We highly suggest to turn it on if you\'re performing a full product reindexing with a large catalog.';
49+
}
50+
51+
$message = htmlentities(__($message));
52+
$url = $this->context->getUrlBuilder()->getUrl('algolia_algoliasearch/indexingmanager/reindex');
53+
54+
return [
55+
'label' => __('Reindex All ' . ucfirst($this->getEntity()) . ' to Algolia'),
56+
'class' => 'algolia_reindex_all',
57+
'on_click' => "deleteConfirm('{$message}', '{$url}', {data:{'entity':'{$entity}', 'redirect': '{$redirectPath}'}})",
58+
'sort_order' => 5,
59+
];
60+
}
61+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
namespace Algolia\AlgoliaSearch\Block\Adminhtml\Reindex\ReindexAll;
4+
5+
use Algolia\AlgoliaSearch\Block\Adminhtml\Reindex\AbstractReindexAllButton;
6+
7+
class Page extends AbstractReindexAllButton
8+
{
9+
protected string $entity = "pages";
10+
11+
protected string $redirectPath = "cms/page/index";
12+
}
Lines changed: 12 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,12 @@
1+
<?php
2+
3+
namespace Algolia\AlgoliaSearch\Block\Adminhtml\Reindex\ReindexAll;
4+
5+
use Algolia\AlgoliaSearch\Block\Adminhtml\Reindex\AbstractReindexAllButton;
6+
7+
class Product extends AbstractReindexAllButton
8+
{
9+
protected string $entity = "products";
10+
11+
protected string $redirectPath = "catalog/product/index";
12+
}
Lines changed: 93 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,93 @@
1+
<?php
2+
3+
namespace Algolia\AlgoliaSearch\Block\Adminhtml\System\Config\Form\Field;
4+
5+
use Magento\Config\Block\System\Config\Form\Field;
6+
use Magento\Framework\Data\Form\Element\AbstractElement;
7+
8+
class Checkboxes extends Field
9+
{
10+
protected function _getElementHtml(AbstractElement $element)
11+
{
12+
$elementId = $element->getHtmlId();
13+
14+
$html = $this->getCss($elementId);
15+
16+
$html .= sprintf('<div id="%s">', $elementId);
17+
$name = $element->getName();
18+
$options = $element->getValues();
19+
$values = empty($element->getValue()) ? [] : explode(',', $element->getValue()); // store as CSV in config
20+
21+
foreach ($options as $key => $option) {
22+
$value = $option['value'];
23+
$html .= $this->getCheckboxHtml(
24+
$elementId . '_' . $key,
25+
$name,
26+
$value,
27+
in_array($value, $values),
28+
$option['label'],
29+
array_key_exists('description', $option) ? $option['description'] : ''
30+
);
31+
}
32+
33+
$html .= '</div>';
34+
return $html;
35+
}
36+
37+
protected function getCss($elementId): string {
38+
return <<<CSS
39+
<style>
40+
#$elementId .form-group {
41+
display: grid;
42+
grid-template-columns: 24px 1fr;
43+
align-items: start;
44+
margin-bottom: 20px;
45+
}
46+
47+
#$elementId .form-group input[type="checkbox"] {
48+
margin-top: 2px;
49+
}
50+
#$elementId .form-content {
51+
display: flex;
52+
flex-direction: column;
53+
}
54+
#$elementId .form-content label {
55+
font-weight: bold;
56+
color: #333;
57+
}
58+
#$elementId .form-content .description {
59+
font-size: 0.9em;
60+
color: #666;
61+
margin-top: 2px;
62+
}
63+
</style>
64+
CSS;
65+
}
66+
67+
protected function getCheckboxHtml(
68+
string $id,
69+
string $name,
70+
string $value,
71+
bool $checked,
72+
?string $label = null,
73+
?string $description = null
74+
): string
75+
{
76+
$html = '<div class="form-group">';
77+
$html .= sprintf(
78+
'<input type="checkbox" id="%s" name="%s[]" value="%s" %s />',
79+
$id,
80+
$name,
81+
$value,
82+
$checked ? 'checked' : ''
83+
);
84+
$html .= '<div class="form-content">';
85+
$html .= sprintf('<label for="%s">%s</label>',$id, $label ?? $name);
86+
if ($description) {
87+
$html .= sprintf('<span class="description">%s</span>', $description);
88+
}
89+
$html .= '</div>';
90+
$html .= '</div>';
91+
return $html;
92+
}
93+
}

Block/Algolia.php

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
use Algolia\AlgoliaSearch\Helper\AlgoliaHelper;
66
use Algolia\AlgoliaSearch\Helper\ConfigHelper;
7+
use Algolia\AlgoliaSearch\Helper\Configuration\AutocompleteHelper;
8+
use Algolia\AlgoliaSearch\Helper\Configuration\InstantSearchHelper;
79
use Algolia\AlgoliaSearch\Helper\Configuration\PersonalizationHelper;
810
use Algolia\AlgoliaSearch\Helper\Data as CoreHelper;
911
use Algolia\AlgoliaSearch\Helper\Entity\CategoryHelper;
@@ -40,6 +42,9 @@ class Algolia extends Template implements CollectionDataSourceInterface
4042

4143
public function __construct(
4244
protected ConfigHelper $config,
45+
protected AutocompleteHelper $autocompleteConfig,
46+
protected InstantSearchHelper $instantSearchConfig,
47+
protected PersonalizationHelper $personalizationHelper,
4348
protected CatalogSearchHelper $catalogSearchHelper,
4449
protected ProductHelper $productHelper,
4550
protected Currency $currency,
@@ -53,7 +58,6 @@ public function __construct(
5358
protected CategoryHelper $categoryHelper,
5459
protected SuggestionHelper $suggestionHelper,
5560
protected LandingPageHelper $landingPageHelper,
56-
protected PersonalizationHelper $personalizationHelper,
5761
protected CheckoutSession $checkoutSession,
5862
protected DateTime $date,
5963
protected CurrentCategory $currentCategory,

Block/Configuration.php

Lines changed: 60 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,8 @@
44

55
use Algolia\AlgoliaSearch\Helper\ConfigHelper;
66
use Algolia\AlgoliaSearch\Helper\InsightsHelper;
7+
use Algolia\AlgoliaSearch\Model\Source\AutocompleteRedirectMode;
8+
use Algolia\AlgoliaSearch\Model\Source\InstantSearchRedirectOptions;
79
use Magento\Framework\App\Request\Http;
810
use Magento\Framework\Data\CollectionDataSourceInterface;
911
use Magento\Framework\DataObject;
@@ -185,32 +187,8 @@ public function getConfiguration()
185187

186188
$attributesToFilter = $config->getAttributesToFilter($customerGroupId);
187189
$algoliaJsConfig = [
188-
'instant' => [
189-
'enabled' => $config->isInstantEnabled(),
190-
'selector' => $config->getInstantSelector(),
191-
'isAddToCartEnabled' => $config->isAddToCartEnable(),
192-
'addToCartParams' => $addToCartParams,
193-
'infiniteScrollEnabled' => $config->isInfiniteScrollEnabled(),
194-
'urlTrackedParameters' => $this->getUrlTrackedParameters(),
195-
'isSearchBoxEnabled' => $config->isInstantSearchBoxEnabled(),
196-
'isVisualMerchEnabled' => $config->isVisualMerchEnabled(),
197-
'categorySeparator' => $config->getCategorySeparator(),
198-
'categoryPageIdAttribute' => $config->getCategoryPageIdAttributeName(),
199-
'isCategoryNavigationEnabled' => self::IS_CATEGORY_NAVIGATION_ENABLED,
200-
'hidePagination' => $config->hidePaginationInInstantSearchPage()
201-
],
202-
'autocomplete' => [
203-
'enabled' => $config->isAutoCompleteEnabled(),
204-
'selector' => $config->getAutocompleteSelector(),
205-
'sections' => $config->getAutocompleteSections(),
206-
'nbOfProductsSuggestions' => $config->getNumberOfProductsSuggestions(),
207-
'nbOfCategoriesSuggestions' => $config->getNumberOfCategoriesSuggestions(),
208-
'nbOfQueriesSuggestions' => $config->getNumberOfQueriesSuggestions(),
209-
'isDebugEnabled' => $config->isAutocompleteDebugEnabled(),
210-
'isNavigatorEnabled' => $config->isAutocompleteNavigatorEnabled(),
211-
'debounceMilliseconds' => $config->getAutocompleteDebounceMilliseconds(),
212-
'minimumCharacters' => $config->getAutocompleteMinimumCharacterLength()
213-
],
190+
'instant' => $this->getInstantSearchConfig($addToCartParams),
191+
'autocomplete' => $this->getAutocompleteConfiguration(),
214192
'landingPage' => [
215193
'query' => $this->getLandingPageQuery(),
216194
'configuration' => $this->getLandingPageConfiguration(),
@@ -244,7 +222,9 @@ public function getConfiguration()
244222
],
245223
'extensionVersion' => $config->getExtensionVersion(),
246224
'applicationId' => $config->getApplicationID(),
225+
// Legacy misnomer - retained for backward compatibility
247226
'indexName' => $coreHelper->getBaseIndexName(),
227+
'baseIndexName' => $coreHelper->getBaseIndexName(),
248228
'apiKey' => $algoliaHelper->generateSearchSecuredApiKey(
249229
$config->getSearchOnlyAPIKey(),
250230
$attributesToFilter,
@@ -368,6 +348,7 @@ public function getConfiguration()
368348
'products' => __('Products'),
369349
'suggestions' => __('Suggestions'),
370350
'searchBy' => __('Search by'),
351+
'redirectSearchPrompt' => __("Continue search for"),
371352
'searchForFacetValuesPlaceholder' => __('Search for other ...'),
372353
'showMore' => __('Show more products'),
373354
'searchTitle' => __('Search results for'),
@@ -381,6 +362,59 @@ public function getConfiguration()
381362
return $transport->getData();
382363
}
383364

365+
protected function getAutocompleteConfiguration(): array
366+
{
367+
$config = $this->autocompleteConfig;
368+
return [
369+
'enabled' => $config->isEnabled(),
370+
'selector' => $config->getDomSelector(),
371+
'sections' => $config->getAdditionalSections(),
372+
'nbOfProductsSuggestions' => $config->getNumberOfProductsSuggestions(),
373+
'nbOfCategoriesSuggestions' => $config->getNumberOfCategoriesSuggestions(),
374+
'nbOfQueriesSuggestions' => $config->getNumberOfQueriesSuggestions(),
375+
'isDebugEnabled' => $config->isDebugEnabled(),
376+
'isNavigatorEnabled' => $config->isKeyboardNavigationEnabled(),
377+
'debounceMilliseconds' => $config->getDebounceMilliseconds(),
378+
'minimumCharacters' => $config->getMinimumCharacterLength(),
379+
'redirects' => [
380+
'enabled' => $config->isRedirectEnabled(),
381+
'showSelectableRedirect' => $config->getRedirectMode() !== AutocompleteRedirectMode::SUBMIT_ONLY,
382+
'showHitsWithRedirect' => $config->getRedirectMode() !== AutocompleteRedirectMode::SELECTABLE_REDIRECT,
383+
'openInNewWindow' => $config->isRedirectInNewWindowEnabled()
384+
]
385+
];
386+
}
387+
388+
protected function getInstantSearchConfig(array $addToCartParams): array
389+
{
390+
$config = $this->instantSearchConfig;
391+
$redirectOptions = $config->getInstantRedirectOptions();
392+
$mainConfig = $this->config;
393+
394+
return [
395+
'enabled' => $config->isEnabled(),
396+
'selector' => $config->getDomSelector(),
397+
'isAddToCartEnabled' => $config->isAddToCartEnabled(),
398+
'addToCartParams' => $addToCartParams,
399+
'infiniteScrollEnabled' => $config->isInfiniteScrollEnabled(),
400+
'urlTrackedParameters' => $this->getUrlTrackedParameters(),
401+
'isSearchBoxEnabled' => $config->isSearchBoxEnabled(),
402+
'isVisualMerchEnabled' => $mainConfig->isVisualMerchEnabled(),
403+
'categorySeparator' => $mainConfig->getCategorySeparator(),
404+
'categoryPageIdAttribute' => $mainConfig->getCategoryPageIdAttributeName(),
405+
'isCategoryNavigationEnabled' => self::IS_CATEGORY_NAVIGATION_ENABLED,
406+
'hidePagination' => $config->shouldHidePagination(),
407+
'isDynamicFacetsEnabled' => $config->isDynamicFacetsEnabled(),
408+
'redirects' => [
409+
'enabled' => $config->isInstantRedirectEnabled(),
410+
'onPageLoad' => in_array(InstantSearchRedirectOptions::REDIRECT_ON_PAGE_LOAD, $redirectOptions),
411+
'onSearchAsYouType' => in_array(InstantSearchRedirectOptions::REDIRECT_ON_SEARCH_AS_YOU_TYPE, $redirectOptions),
412+
'showSelectableRedirect' => in_array(InstantSearchRedirectOptions::SELECTABLE_REDIRECT, $redirectOptions),
413+
'openInNewWindow' => in_array(InstantSearchRedirectOptions::OPEN_IN_NEW_WINDOW, $redirectOptions)
414+
]
415+
];
416+
}
417+
384418
protected function areCategoriesInFacets($facets)
385419
{
386420
return in_array('categories', array_column($facets, 'attribute'));

CHANGELOG.md

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

3+
## 3.16.0-beta.1
4+
5+
### Features
6+
7+
- Automatic full indexing has been deprecated in 3.16 - you can now opt out of Algolia initiating full reindexing from `indexer_reindex_all_invalid`.
8+
- Added an "Indexing Manager" section within the Algolia configuration which disables automatic full reindexing by default and allows users to reactivate if needed.
9+
- Added an "Indexing Manager" page which shows the created indices for main entities (products, categories and pages) and corresponding stores with a link to directly check them on the Algolia dashboard along with a form to reindex those entities directly from the Magento admin.
10+
- CLI commands are now provided to run explicit full reindex of all entities and stores.
11+
- Products and CMS pages can now be reindexed directly from Magento admin grids.
12+
- The indexing queue cron job can now be configured from the Magento admin.
13+
- Dynamic faceting through Algolia merchandsiing rules is now supported in Magento via an opt-in feature flag.
14+
- No code redirects via merchandising rules in Algolia are now supported in Magento for both Autocomplete and InstantSearch. Support is enabled by default for Autocomplete.
15+
- Integration tests and unit tests added
16+
17+
### Bug Fixes
18+
- Behavior of conjunctive vs disjunctive facets has been clarified.
19+
- Replica data patches and delete operations have been enhanced to handle potential latency when detaching from the primary index.
20+
- Prices are now indexed using store scoped currency codes.
21+
- Fixed WSOD error on invalid creds when using manual SKU indexer (also included in 3.15.1).
22+
23+
### Updates
24+
- `beforecontent.html` is no longer used and has been deprecated. If you're overriding or referencing this file, please update your layout and customizations accordingly.
25+
- An additional separate crontab is no longer needed to run the indexing queue. Enable via admin config to run the queue using Magento's built-in cron.
26+
- `BatchQueueProcessorInterface` has been introduced to decouple Algolia operations for core `Indexer` models.
27+
- Magento will set a default `renderingContent` based on its configured facets. Be sure that "Facet Display" is supported by your Algolia plan before attempting to use.
28+
- Auto full indexing is disabled by default in this release. If you require this legacy feature then it can be re-enabled via the Magento admin under Stores > Configuration > Algolia Search > Indexing Manager
29+
- InstantSearch has been refactored to support customization via JavaScript mixins.
30+
- A new front end hook called `beforeFacetInitialization` has been added which allows a user to extend the functionality by adding, removing or modifying "builder" functions which are used to define a facet config that will drive the rendering of facets.
31+
- Removed InstantSearch enablement dependency in Magento admin to prevent losing facet and sorting config when disabling the feature.
32+
- InstantSearch has been updated to v4.78.
33+
- Autocomplete has been updated to v1.18.1.
34+
- PHP API client has been pinned to 4.18.3 (also included in 3.15.1).
35+
336
## 3.15.0
437

538
### Features
@@ -33,6 +66,7 @@
3366
- Fixed a bug where categories highlighting didn't work as expected on PLP powered by InstantSearch
3467
- Fixed a bug where excluded websites weren't taken into account while indexing customer prices on products. (thanks @kamilszewczyk)
3568
- Fixed a bug where full page cache (FPC) didn't work on category pages
69+
- Fixed a bug where credentials errors weren't gracefully handled on the SKU reindexing form
3670

3771
### Breaking Changes
3872
- If you have customized your front end implementation based on the `algoliaBundle` you may need to shim your application accordingly (Full details are shared in [our documentation](https://www.algolia.com/doc/integration/magento-2/troubleshooting/front-end-issues/))

0 commit comments

Comments
 (0)