Skip to content

Commit

Permalink
Merge pull request #9288 from adobe-commerce-tier-4/PR-10-04-24
Browse files Browse the repository at this point in the history
[Support Tier-4 horytsky] 10-04-2024 Regular delivery of bugfixes and improvements
  • Loading branch information
dhorytskyi authored Oct 7, 2024
2 parents 581b7ef + c8d9f7f commit a4cf5e6
Show file tree
Hide file tree
Showing 41 changed files with 1,629 additions and 820 deletions.
14 changes: 12 additions & 2 deletions app/code/Magento/Analytics/Model/ExportDataHandler.php
Original file line number Diff line number Diff line change
Expand Up @@ -90,7 +90,7 @@ public function __construct(
public function prepareExportData()
{
try {
$tmpDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::TMP);
$tmpDirectory = $this->filesystem->getDirectoryWrite(DirectoryList::SYS_TMP);
$this->prepareDirectory($tmpDirectory, $this->getTmpFilesDirRelativePath());
$this->reportWriter->write($tmpDirectory, $this->getTmpFilesDirRelativePath());

Expand Down Expand Up @@ -122,7 +122,17 @@ public function prepareExportData()
*/
private function getTmpFilesDirRelativePath()
{
return $this->subdirectoryPath . 'tmp/';
return $this->subdirectoryPath . 'tmp/' . $this->getInstanceIdentifier() . '/';
}

/**
* Return unique identifier for an instance.
*
* @return string
*/
private function getInstanceIdentifier()
{
return hash('sha256', BP);
}

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -112,13 +112,23 @@ protected function setUp(): void
);
}

/**
* Return unique identifier for an instance.
*
* @return string
*/
private function getInstanceIdentifier()
{
return hash('sha256', BP);
}

/**
* @param bool $isArchiveSourceDirectory
* @dataProvider prepareExportDataDataProvider
*/
public function testPrepareExportData($isArchiveSourceDirectory)
{
$tmpFilesDirectoryPath = $this->subdirectoryPath . 'tmp/';
$tmpFilesDirectoryPath = $this->subdirectoryPath . 'tmp/' . $this->getInstanceIdentifier() . '/';
$archiveRelativePath = $this->subdirectoryPath . $this->archiveName;

$archiveSource = $isArchiveSourceDirectory ? (__DIR__) : '/tmp/' . $tmpFilesDirectoryPath;
Expand All @@ -127,7 +137,7 @@ public function testPrepareExportData($isArchiveSourceDirectory)
$this->filesystemMock
->expects($this->once())
->method('getDirectoryWrite')
->with(DirectoryList::TMP)
->with(DirectoryList::SYS_TMP)
->willReturn($this->directoryMock);
$this->directoryMock
->expects($this->exactly(4))
Expand Down Expand Up @@ -210,13 +220,13 @@ public static function prepareExportDataDataProvider()
public function testPrepareExportDataWithLocalizedException()
{
$this->expectException('Magento\Framework\Exception\LocalizedException');
$tmpFilesDirectoryPath = $this->subdirectoryPath . 'tmp/';
$tmpFilesDirectoryPath = $this->subdirectoryPath . 'tmp/' . $this->getInstanceIdentifier() . '/';
$archivePath = $this->subdirectoryPath . $this->archiveName;

$this->filesystemMock
->expects($this->once())
->method('getDirectoryWrite')
->with(DirectoryList::TMP)
->with(DirectoryList::SYS_TMP)
->willReturn($this->directoryMock);
$this->reportWriterMock
->expects($this->once())
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -8,103 +8,50 @@
namespace Magento\CatalogGraphQl\DataProvider\Product;

use Magento\Catalog\Api\Data\EavAttributeInterface;
use Magento\Catalog\Model\Product;
use Magento\Catalog\Api\ProductAttributeRepositoryInterface;
use Magento\Catalog\Model\Product\Visibility;
use Magento\Eav\Model\Config;
use Magento\CatalogSearch\Model\ResourceModel\Fulltext\Collection\SearchCriteriaResolverFactory;
use Magento\Framework\Api\FilterBuilder;
use Magento\Framework\Api\Search\FilterGroupBuilder;
use Magento\Framework\Api\Search\SearchCriteriaInterface;
use Magento\Framework\Api\SortOrder;
use Magento\Framework\Api\SortOrderBuilder;
use Magento\Framework\App\Config\ScopeConfigInterface;
use Magento\Framework\App\ObjectManager;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\GraphQl\Query\Resolver\Argument\SearchCriteria\Builder;
use Magento\Framework\GraphQl\Query\Resolver\Argument\SearchCriteria\ArgumentApplierPool;
use Magento\Framework\Search\Request\Config as SearchConfig;

/**
* Build search criteria
* @SuppressWarnings(PHPMD.CouplingBetweenObjects)
*/

class SearchCriteriaBuilder
{
/**
* @var ScopeConfigInterface
*/
private $scopeConfig;

/**
* @var FilterBuilder
*/
private $filterBuilder;

/**
* @var FilterGroupBuilder
*/
private $filterGroupBuilder;

/**
* @var Builder
*/
private $builder;

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

/**
* @var SortOrderBuilder
*/
private $sortOrderBuilder;

/**
* @var Config
*/
private Config $eavConfig;

/**
* @var SearchConfig
*/
private SearchConfig $searchConfig;

/**
* @var RequestDataBuilder|mixed
*/
private RequestDataBuilder $localData;

/**
* @param Builder $builder
* @param ScopeConfigInterface $scopeConfig
* @param FilterBuilder $filterBuilder
* @param FilterGroupBuilder $filterGroupBuilder
* @param Visibility $visibility
* @param SortOrderBuilder|null $sortOrderBuilder
* @param Config|null $eavConfig
* @param SearchConfig|null $searchConfig
* @param RequestDataBuilder|null $localData
* @param SortOrderBuilder $sortOrderBuilder
* @param ProductAttributeRepositoryInterface $productAttributeRepository
* @param SearchConfig $searchConfig
* @param RequestDataBuilder $localData
* @param SearchCriteriaResolverFactory $criteriaResolverFactory
* @param ArgumentApplierPool $argumentApplierPool
* @SuppressWarnings(PHPMD.ExcessiveParameterList)
*/
public function __construct(
Builder $builder,
ScopeConfigInterface $scopeConfig,
FilterBuilder $filterBuilder,
FilterGroupBuilder $filterGroupBuilder,
Visibility $visibility,
SortOrderBuilder $sortOrderBuilder = null,
Config $eavConfig = null,
SearchConfig $searchConfig = null,
RequestDataBuilder $localData = null,
private readonly ScopeConfigInterface $scopeConfig,
private readonly FilterBuilder $filterBuilder,
private readonly FilterGroupBuilder $filterGroupBuilder,
private readonly Visibility $visibility,
private readonly SortOrderBuilder $sortOrderBuilder,
private readonly ProductAttributeRepositoryInterface $productAttributeRepository,
private readonly SearchConfig $searchConfig,
private readonly RequestDataBuilder $localData,
private readonly SearchCriteriaResolverFactory $criteriaResolverFactory,
private readonly ArgumentApplierPool $argumentApplierPool,
) {
$this->scopeConfig = $scopeConfig;
$this->filterBuilder = $filterBuilder;
$this->filterGroupBuilder = $filterGroupBuilder;
$this->builder = $builder;
$this->visibility = $visibility;
$this->sortOrderBuilder = $sortOrderBuilder ?? ObjectManager::getInstance()->get(SortOrderBuilder::class);
$this->eavConfig = $eavConfig ?? ObjectManager::getInstance()->get(Config::class);
$this->searchConfig = $searchConfig ?? ObjectManager::getInstance()->get(SearchConfig::class);
$this->localData = $localData ?? ObjectManager::getInstance()->get(RequestDataBuilder::class);
}

/**
Expand All @@ -117,45 +64,42 @@ public function __construct(
*/
public function build(array $args, bool $includeAggregation): SearchCriteriaInterface
{
$partialMatchFilters = [];
$isSearch = isset($args['search']);
$requestName = $includeAggregation ? 'graphql_product_search_with_aggregation' : 'graphql_product_search';

if (isset($args['filter'])) {
$partialMatchFilters = $this->getPartialMatchFilters($args);
if (count($partialMatchFilters)) {
$this->updateMatchTypeRequestConfig($requestName, $partialMatchFilters);
}
$args = $this->removeMatchTypeFromArguments($args);
}
$searchCriteria = $this->builder->build('products', $args);
$isSearch = isset($args['search']);
$this->updateRangeFilters($searchCriteria);
if ($includeAggregation) {
$attributeData = $this->eavConfig->getAttribute(Product::ENTITY, 'price');
$priceOptions = $attributeData->getData();

if ($priceOptions['is_filterable'] != 0) {
$this->preparePriceAggregation($searchCriteria);
$searchCriteria = $this->criteriaResolverFactory->create(
[
'searchRequestName' => $requestName,
'currentPage' => $args['currentPage'],
'size' => $args['pageSize'],
'orders' => null,
]
)->resolve();
foreach ($args as $argumentName => $argument) {
if ($this->argumentApplierPool->hasApplier($argumentName)) {
$argumentApplier = $this->argumentApplierPool->getApplier($argumentName);
$argumentApplier->applyArgument($searchCriteria, 'products', $argumentName, $argument);
}
$requestName = 'graphql_product_search_with_aggregation';
} else {
$requestName = 'graphql_product_search';
}
$searchCriteria->setRequestName($requestName);

if (count($partialMatchFilters)) {
$this->updateMatchTypeRequestConfig($requestName, $partialMatchFilters);
}

$this->updateRangeFilters($searchCriteria);
$this->preparePriceAggregation($searchCriteria, $includeAggregation);
if ($isSearch) {
$this->addFilter($searchCriteria, 'search_term', $args['search']);
}

if (!$searchCriteria->getSortOrders()) {
$this->addDefaultSortOrder($searchCriteria, $args, $isSearch);
}

$this->addEntityIdSort($searchCriteria);
$this->addVisibilityFilter($searchCriteria, $isSearch, !empty($args['filter']['category_id']));

$searchCriteria->setCurrentPage($args['currentPage']);
$searchCriteria->setPageSize($args['pageSize']);

return $searchCriteria;
}

Expand All @@ -164,7 +108,6 @@ public function build(array $args, bool $includeAggregation): SearchCriteriaInte
*
* @param string $requestName
* @param array $partialMatchFilters
*
* @return void
*/
private function updateMatchTypeRequestConfig(string $requestName, array $partialMatchFilters): void
Expand All @@ -184,7 +127,6 @@ private function updateMatchTypeRequestConfig(string $requestName, array $partia
* Check if and what type of match_type value was requested
*
* @param array $args
*
* @return array
*/
private function getPartialMatchFilters(array $args): array
Expand All @@ -202,7 +144,6 @@ private function getPartialMatchFilters(array $args): array
* Remove the match_type to avoid search criteria containing it
*
* @param array $args
*
* @return array
*/
private function removeMatchTypeFromArguments(array $args): array
Expand Down Expand Up @@ -254,7 +195,7 @@ private function addEntityIdSort(SearchCriteriaInterface $searchCriteria): void
}

$sortOrderArray[] = $this->sortOrderBuilder
->setField('_id')
->setField('entity_id')
->setDirection($sortDir)
->create();
$searchCriteria->setSortOrders($sortOrderArray);
Expand All @@ -264,10 +205,21 @@ private function addEntityIdSort(SearchCriteriaInterface $searchCriteria): void
* Prepare price aggregation algorithm
*
* @param SearchCriteriaInterface $searchCriteria
* @param bool $includeAggregation
* @return void
*/
private function preparePriceAggregation(SearchCriteriaInterface $searchCriteria): void
private function preparePriceAggregation(SearchCriteriaInterface $searchCriteria, bool $includeAggregation): void
{
if (!$includeAggregation) {
return;
}

$attributeData = $this->productAttributeRepository->get('price');
$priceOptions = $attributeData->getData();
if ((int) $priceOptions['is_filterable'] === 0) {
return;
}

$priceRangeCalculation = $this->scopeConfig->getValue(
\Magento\Catalog\Model\Layer\Filter\Dynamic\AlgorithmFactory::XML_PATH_RANGE_CALCULATION,
\Magento\Store\Model\ScopeInterface::SCOPE_STORE
Expand Down Expand Up @@ -319,7 +271,7 @@ private function addDefaultSortOrder(SearchCriteriaInterface $searchCriteria, ar
->setDirection(SortOrder::SORT_DESC)
->create();
} else {
$categoryIdFilter = isset($args['filter']['category_id']) ? $args['filter']['category_id'] : false;
$categoryIdFilter = $args['filter']['category_id'] ?? false;
if ($categoryIdFilter) {
if (!is_array($categoryIdFilter[array_key_first($categoryIdFilter)])
|| count($categoryIdFilter[array_key_first($categoryIdFilter)]) <= 1
Expand Down
Loading

0 comments on commit a4cf5e6

Please sign in to comment.