Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
17 commits
Select commit Hold shift + click to select a range
fc7700d
MC-37477: Advanced Search on Elasticsearch returns Configurable Produ…
SmVladyslav Sep 10, 2020
09b1d2d
Merge remote-tracking branch 'origin/2.4-develop' into MC-37477
SmVladyslav Sep 11, 2020
844c946
Merge remote-tracking branch 'origin/2.4-develop' into MC-37477
SmVladyslav Sep 11, 2020
8d3f33e
MC-37477: Advanced Search on Elasticsearch returns Configurable Produ…
SmVladyslav Sep 11, 2020
d4f121e
Merge remote-tracking branch 'origin/2.4-develop' into MC-37477
SmVladyslav Sep 14, 2020
3420575
MC-37477: Advanced Search on Elasticsearch returns Configurable Produ…
SmVladyslav Sep 14, 2020
0b600a0
MC-37477: Advanced Search on Elasticsearch returns Configurable Produ…
SmVladyslav Sep 15, 2020
2ddb35c
Merge remote-tracking branch 'origin/2.4-develop' into MC-37477
SmVladyslav Sep 21, 2020
f943701
MC-37477: Advanced Search on Elasticsearch returns Configurable Produ…
SmVladyslav Sep 21, 2020
3cd43db
Merge remote-tracking branch 'origin/2.4-develop' into MC-37477
SmVladyslav Sep 21, 2020
35ed78d
Merge remote-tracking branch 'origin/2.4-develop' into 2.4-develop-pr88
SeruyV Sep 23, 2020
9c4c3bb
MC-23978: Indexer:reindex return wrong status code
SeruyV Sep 23, 2020
a9ccae0
Merge remote-tracking branch 'origin/2.4-develop' into MC-23978
SeruyV Sep 24, 2020
61e8149
Merge branch 'MC-23978' into 2.4-develop-pr88
OlgaVasyltsun Sep 24, 2020
4570b1e
Merge remote-tracking branch 'origin/2.4-develop' into 2.4-develop-pr88
zakdma Sep 25, 2020
af7a2e4
Merge remote-tracking branch 'origin/2.4-develop' into 2.4-develop-pr88
zakdma Sep 26, 2020
97191ce
Merge pull request #6173 from magento-tsg/2.4-develop-pr88
zakdma Sep 27, 2020
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -6,27 +6,30 @@

namespace Magento\CatalogSearch\Model\ResourceModel\Advanced;

use Magento\Catalog\Model\Category;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Model\ResourceModel\Product\Collection\ProductLimitationFactory;
use Magento\CatalogSearch\Model\ResourceModel\Advanced;
use Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection\DefaultFilterStrategyApplyChecker;
use Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection\DefaultFilterStrategyApplyCheckerInterface;
use Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection\SearchCriteriaResolverFactory;
use Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection\SearchCriteriaResolverInterface;
use Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection\SearchResultApplierFactory;
use Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection\SearchResultApplierInterface;
use Magento\Framework\Search\EngineResolverInterface;
use Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection\TotalRecordsResolverInterface;
use Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection\TotalRecordsResolverFactory;
use Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection\TotalRecordsResolverInterface;
use Magento\Eav\Model\Entity\Attribute\AbstractAttribute;
use Magento\Framework\Api\FilterBuilder;
use Magento\Framework\DB\Select;
use Magento\Framework\Api\Search\SearchCriteriaBuilder;
use Magento\Framework\Api\Search\SearchResultFactory;
use Magento\Framework\Api\Search\SearchResultInterface;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\DB\Select;
use Magento\Framework\EntityManager\MetadataPool;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\Search\EngineResolverInterface;
use Magento\Framework\Search\Request\EmptyRequestDataException;
use Magento\Framework\Search\Request\NonExistingRequestNameException;
use Magento\Catalog\Model\ResourceModel\Product\Collection\ProductLimitationFactory;
use Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection\SearchCriteriaResolverFactory;
use Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection\SearchResultApplierFactory;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Api\Search\SearchResultInterface;

/**
* Advanced search collection
Expand Down Expand Up @@ -106,6 +109,11 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection
*/
private $defaultFilterStrategyApplyChecker;

/**
* @var Advanced
*/
private $advancedSearchResource;

/**
* Collection constructor
*
Expand Down Expand Up @@ -141,6 +149,7 @@ class Collection extends \Magento\Catalog\Model\ResourceModel\Product\Collection
* @param TotalRecordsResolverFactory|null $totalRecordsResolverFactory
* @param EngineResolverInterface|null $engineResolver
* @param DefaultFilterStrategyApplyCheckerInterface|null $defaultFilterStrategyApplyChecker
* @param Advanced|null $advancedSearchResource
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
* @SuppressWarnings(PHPMD.UnusedFormalParameter)
*/
Expand Down Expand Up @@ -176,7 +185,8 @@ public function __construct(
SearchResultApplierFactory $searchResultApplierFactory = null,
TotalRecordsResolverFactory $totalRecordsResolverFactory = null,
EngineResolverInterface $engineResolver = null,
DefaultFilterStrategyApplyCheckerInterface $defaultFilterStrategyApplyChecker = null
DefaultFilterStrategyApplyCheckerInterface $defaultFilterStrategyApplyChecker = null,
Advanced $advancedSearchResource = null
) {
$this->searchRequestName = $searchRequestName;
if ($searchResultFactory === null) {
Expand All @@ -193,6 +203,8 @@ public function __construct(
->get(EngineResolverInterface::class);
$this->defaultFilterStrategyApplyChecker = $defaultFilterStrategyApplyChecker ?: ObjectManager::getInstance()
->get(DefaultFilterStrategyApplyChecker::class);
$this->advancedSearchResource = $advancedSearchResource ?: ObjectManager::getInstance()
->get(Advanced::class);
parent::__construct(
$entityFactory,
$logger,
Expand Down Expand Up @@ -258,14 +270,14 @@ public function setOrder($attribute, $dir = Select::SQL_DESC)
*/
public function addCategoryFilter(\Magento\Catalog\Model\Category $category)
{
$this->setAttributeFilterData(Category::ENTITY, 'category_ids', $category->getId());
/**
* This changes need in backward compatible reasons for support dynamic improved algorithm
* for price aggregation process.
*/
if ($this->defaultFilterStrategyApplyChecker->isApplicable()) {
parent::addCategoryFilter($category);
} else {
$this->addFieldToFilter('category_ids', $category->getId());
$this->_productLimitationPrice();
}

Expand All @@ -278,14 +290,13 @@ public function addCategoryFilter(\Magento\Catalog\Model\Category $category)
*/
public function setVisibility($visibility)
{
$this->setAttributeFilterData(Product::ENTITY, 'visibility', $visibility);
/**
* This changes need in backward compatible reasons for support dynamic improved algorithm
* for price aggregation process.
*/
if ($this->defaultFilterStrategyApplyChecker->isApplicable()) {
parent::setVisibility($visibility);
} else {
$this->addFieldToFilter('visibility', $visibility);
}

return $this;
Expand All @@ -306,6 +317,25 @@ private function setSearchOrder($field, $direction)
$this->searchOrders[$field] = $direction;
}

/**
* Prepare attribute data to filter.
*
* @param string $entityType
* @param string $attributeCode
* @param mixed $condition
* @return $this
*/
private function setAttributeFilterData(string $entityType, string $attributeCode, $condition): self
{
/** @var AbstractAttribute $attribute */
$attribute = $this->_eavConfig->getAttribute($entityType, $attributeCode);
$table = $attribute->getBackend()->getTable();
$condition = $this->advancedSearchResource->prepareCondition($attribute, $condition);
$this->addFieldsToFilter([$table => [$attributeCode => $condition]]);

return $this;
}

/**
* @inheritdoc
*/
Expand Down Expand Up @@ -377,7 +407,7 @@ public function _loadEntities($printQuery = false, $logQuery = false)
$query = $this->getSelect();
$rows = $this->_fetchAll($query);
} catch (\Exception $e) {
$this->printLogQuery(false, true, $query);
$this->printLogQuery(false, true, $query ?? null);
throw $e;
}

Expand Down
5 changes: 5 additions & 0 deletions app/code/Magento/CatalogSearch/etc/search_request.xml
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@
<queryReference clause="should" ref="sku_query"/>
<queryReference clause="should" ref="price_query"/>
<queryReference clause="should" ref="category_query"/>
<queryReference clause="must" ref="visibility_query"/>
</query>
<query name="sku_query" xsi:type="filteredQuery">
<filterReference clause="must" ref="sku_query_filter"/>
Expand All @@ -76,11 +77,15 @@
<query name="category_query" xsi:type="filteredQuery">
<filterReference clause="must" ref="category_filter"/>
</query>
<query name="visibility_query" xsi:type="filteredQuery">
<filterReference clause="must" ref="visibility_filter"/>
</query>
</queries>
<filters>
<filter xsi:type="wildcardFilter" name="sku_query_filter" field="sku" value="$sku$"/>
<filter xsi:type="rangeFilter" name="price_query_filter" field="price" from="$price.from$" to="$price.to$"/>
<filter xsi:type="termFilter" name="category_filter" field="category_ids" value="$category_ids$"/>
<filter xsi:type="termFilter" name="visibility_filter" field="visibility" value="$visibility$"/>
</filters>
<from>0</from>
<size>10000</size>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,9 +5,11 @@
*/
namespace Magento\Elasticsearch\Model\Advanced;

use Magento\Catalog\Model\ResourceModel\Product\Collection;
use Magento\Catalog\Model\Config;
use Magento\Catalog\Model\Product\Visibility;
use Magento\Catalog\Model\ResourceModel\Product\Collection;
use Magento\CatalogSearch\Model\Advanced\ProductCollectionPrepareStrategyInterface;
use Magento\Framework\App\ObjectManager;

/**
* Strategy interface for preparing product collection.
Expand All @@ -19,13 +21,22 @@ class ProductCollectionPrepareStrategy implements ProductCollectionPrepareStrate
*/
private $catalogConfig;

/**
* @var Visibility
*/
private $catalogProductVisibility;

/**
* @param Config $catalogConfig
* @param Visibility|null $catalogProductVisibility
*/
public function __construct(
Config $catalogConfig
Config $catalogConfig,
Visibility $catalogProductVisibility = null
) {
$this->catalogConfig = $catalogConfig;
$this->catalogProductVisibility = $catalogProductVisibility
?? ObjectManager::getInstance()->get(Visibility::class);
}

/**
Expand All @@ -36,6 +47,7 @@ public function prepare(Collection $collection)
$collection
->addAttributeToSelect($this->catalogConfig->getProductAttributes())
->addMinimalPrice()
->addTaxPercents();
->addTaxPercents()
->setVisibility($this->catalogProductVisibility->getVisibleInSearchIds());
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -74,7 +74,7 @@ protected function configure()
*/
protected function execute(InputInterface $input, OutputInterface $output)
{
$returnValue = Cli::RETURN_FAILURE;
$returnValue = Cli::RETURN_SUCCESS;
foreach ($this->getIndexers($input) as $indexer) {
try {
$this->validateIndexerStatus($indexer);
Expand All @@ -97,14 +97,15 @@ protected function execute(InputInterface $input, OutputInterface $output)
$output->writeln(
__('has been rebuilt successfully in %time', ['time' => gmdate('H:i:s', $resultTime)])
);
$returnValue = Cli::RETURN_SUCCESS;
} catch (LocalizedException $e) {
$output->writeln(__('exception: %message', ['message' => $e->getMessage()]));
$returnValue = Cli::RETURN_FAILURE;
} catch (\Exception $e) {
$output->writeln('process unknown error:');
$output->writeln($e->getMessage());

$output->writeln($e->getTraceAsString(), OutputInterface::VERBOSITY_DEBUG);
$returnValue = Cli::RETURN_FAILURE;
}
}

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,101 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\Elasticsearch\Model\CatalogSearch;

use Magento\Catalog\Api\ProductRepositoryInterface;
use Magento\CatalogSearch\Model\Advanced;
use Magento\Catalog\Model\Product\Visibility;
use Magento\Catalog\Api\Data\ProductInterface;
use Magento\Framework\ObjectManagerInterface;
use Magento\Framework\Registry;
use Magento\TestFramework\Helper\Bootstrap;
use PHPUnit\Framework\TestCase;

/**
* Check catalog Advanced Search process with Elasticsearch enabled.
*/
class AdvancedTest extends TestCase
{
/**
* @var ObjectManagerInterface
*/
private $objectManager;

/**
* @var Registry
*/
private $registry;

/**
* @var Visibility
*/
private $productVisibility;

/**
* @var ProductRepositoryInterface
*/
private $productRepository;

/**
* @inheritDoc
*/
protected function setUp(): void
{
parent::setUp();

$this->objectManager = Bootstrap::getObjectManager();
$this->registry = $this->objectManager->get(Registry::class);
$this->productVisibility = $this->objectManager->get(Visibility::class);
$this->productRepository = $this->objectManager->get(ProductRepositoryInterface::class);
}

/**
* Check that Advanced Search does NOT return products that do NOT have search visibility.
*
* @magentoDbIsolation disabled
* @magentoConfigFixture default/catalog/search/engine elasticsearch7
* @magentoDataFixture Magento/ConfigurableProduct/_files/configurable_product_with_two_child_products.php
* @return void
*/
public function testAddFilters(): void
{
$this->assertResultsAfterRequest(1);

/** @var ProductInterface $configurableProductOption */
$configurableProductOption = $this->productRepository->get('Simple option 1');
$configurableProductOption->setVisibility(Visibility::VISIBILITY_IN_SEARCH);
$this->productRepository->save($configurableProductOption);

$this->registry->unregister('advanced_search_conditions');
$this->assertResultsAfterRequest(2);
}

/**
* Do Elasticsearch query and assert results.
*
* @param int $count
* @return void
*/
private function assertResultsAfterRequest(int $count): void
{
/** @var Advanced $advancedSearch */
$advancedSearch = $this->objectManager->create(Advanced::class);
$advancedSearch->addFilters(['name' => 'Configurable']);

/** @var ProductInterface[] $itemsResult */
$itemsResult = $advancedSearch->getProductCollection()
->addAttributeToSelect(ProductInterface::VISIBILITY)
->getItems();

$this->assertCount($count, $itemsResult);
foreach ($itemsResult as $product) {
$this->assertStringContainsString('Configurable', $product->getName());
$this->assertContains((int)$product->getVisibility(), $this->productVisibility->getVisibleInSearchIds());
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,9 +7,11 @@

namespace Magento\Indexer\Console\Command;

use Magento\Framework\Console\Cli;
use Magento\Framework\ObjectManagerInterface;
use Magento\TestFramework\Helper\Bootstrap;
use PHPUnit\Framework\MockObject\MockObject as Mock;
use PHPUnit\Framework\TestCase;
use Symfony\Component\Console\Input\InputInterface;
use Symfony\Component\Console\Output\OutputInterface;

Expand All @@ -19,7 +21,7 @@
* @magentoDbIsolation disabled
* @magentoAppIsolation enabled
*/
class IndexerReindexCommandTest extends \PHPUnit\Framework\TestCase
class IndexerReindexCommandTest extends TestCase
{
/**
* @var ObjectManagerInterface
Expand Down Expand Up @@ -56,14 +58,23 @@ protected function setUp(): void

/**
* @magentoDataFixture Magento/Store/_files/second_store_group_with_second_website.php
* @return void
*/
public function testReindexAll()
public function testReindexAll(): void
{
$status = $this->command->run($this->inputMock, $this->outputMock);
$this->assertEquals(
\Magento\Framework\Console\Cli::RETURN_SUCCESS,
$status,
'Index wasn\'t success'
);
$this->assertEquals(Cli::RETURN_SUCCESS, $status, 'Index wasn\'t success');
}

/**
* Check that 'indexer:reindex' command return right code.
*
* @magentoDataFixture Magento/Indexer/_files/wrong_config_data.php
* @return void
*/
public function testReindexAllWhenSomethingIsWrong(): void
{
$status = $this->command->run($this->inputMock, $this->outputMock);
$this->assertEquals(Cli::RETURN_FAILURE, $status, 'Index didn\'t return failure code');
}
}
Loading