Skip to content

Commit

Permalink
Merge pull request #8523 from magento-l3/PR_06_SEP_2023
Browse files Browse the repository at this point in the history
L3 Bugfix delivery
  • Loading branch information
internal-magento-queue-manager[bot] committed Oct 15, 2023
2 parents ea257d6 + 16922f5 commit 2b3ad2e
Show file tree
Hide file tree
Showing 13 changed files with 324 additions and 102 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -311,15 +311,14 @@ private function reindexByBatchWithDimensions(
if (!empty($entityIds)) {
$this->dimensionTableMaintainer->createMainTmpTable($dimensions);
$temporaryTable = $this->dimensionTableMaintainer->getMainTmpTable($dimensions);
$this->_emptyTable($temporaryTable);

$priceIndexer->executeByDimensions($dimensions, \SplFixedArray::fromArray($entityIds, false));

// Sync data from temp table to index table
$this->_insertFromTable(
$temporaryTable,
$this->dimensionTableMaintainer->getMainReplicaTable($dimensions)
);
$this->_defaultIndexerResource->getConnection()->dropTable($temporaryTable);
}
}

Expand Down Expand Up @@ -354,7 +353,6 @@ private function reindexBatch(PriceInterface $priceIndexer, Select $batch): void
if (!empty($entityIds)) {
// Temporary table will created if not exists
$idxTableName = $this->_defaultIndexerResource->getIdxTable();
$this->_emptyTable($idxTableName);

if ($priceIndexer->getIsComposite()) {
$this->_copyRelationIndexData($entityIds);
Expand Down Expand Up @@ -489,6 +487,7 @@ private function moveDataFromReplicaTableToReplicaTables(array $dimensions): voi
* Retrieves the index table that should be used
*
* @deprecated 102.0.6
* @see only used in another deprecated method: _copyRelationIndexData
*/
protected function getIndexTargetTable(): string
{
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -122,8 +122,8 @@ public function modifyPrice(IndexTableStructure $priceTable, array $entityIds =
$query = $select->crossUpdateFromSelect(['i' => $finalPriceTable]);
$connection->query($query);

$connection->delete($coaTable);
$connection->delete($copTable);
$connection->dropTemporaryTable($coaTable);
$connection->dropTemporaryTable($copTable);
}

/**
Expand Down
25 changes: 14 additions & 11 deletions app/code/Magento/Catalog/Test/Fixture/Attribute.php
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@

namespace Magento\Catalog\Test\Fixture;

use Magento\Catalog\Api\Data\ProductAttributeInterface;
use Magento\Catalog\Api\ProductAttributeManagementInterface;
use Magento\Catalog\Api\ProductAttributeRepositoryInterface;
use Magento\Catalog\Model\Product;
Expand Down Expand Up @@ -96,6 +95,11 @@ class Attribute implements RevertibleDataFixtureInterface
*/
private ResourceModelAttribute $resourceModelAttribute;

/**
* @var ProductAttributeRepositoryInterface
*/
private ProductAttributeRepositoryInterface $productAttributeRepository;

/**
* @param ServiceFactory $serviceFactory
* @param ProcessorInterface $dataProcessor
Expand All @@ -104,6 +108,7 @@ class Attribute implements RevertibleDataFixtureInterface
* @param AttributeFactory $attributeFactory
* @param DataMerger $dataMerger
* @param ResourceModelAttribute $resourceModelAttribute
* @param ProductAttributeRepositoryInterface $productAttributeRepository
*/
public function __construct(
ServiceFactory $serviceFactory,
Expand All @@ -112,7 +117,8 @@ public function __construct(
ProductAttributeManagementInterface $productAttributeManagement,
AttributeFactory $attributeFactory,
DataMerger $dataMerger,
ResourceModelAttribute $resourceModelAttribute
ResourceModelAttribute $resourceModelAttribute,
ProductAttributeRepositoryInterface $productAttributeRepository
) {
$this->serviceFactory = $serviceFactory;
$this->dataProcessor = $dataProcessor;
Expand All @@ -121,6 +127,7 @@ public function __construct(
$this->attributeFactory = $attributeFactory;
$this->dataMerger = $dataMerger;
$this->resourceModelAttribute = $resourceModelAttribute;
$this->productAttributeRepository = $productAttributeRepository;
}

/**
Expand All @@ -134,16 +141,11 @@ public function apply(array $data = []): ?DataObject
return $this->applyAttributeWithAdditionalData($data);
}

$service = $this->serviceFactory->create(ProductAttributeRepositoryInterface::class, 'save');

/**
* @var ProductAttributeInterface $attribute
*/
$attribute = $service->execute(
[
'attribute' => $this->prepareData(array_diff_key($data, self::DEFAULT_ATTRIBUTE_SET_DATA))
]
$attribute = $this->attributeFactory->createAttribute(
EavAttribute::class,
$this->prepareData(array_diff_key($data, self::DEFAULT_ATTRIBUTE_SET_DATA))
);
$attribute = $this->productAttributeRepository->save($attribute);

$attributeSetData = $this->prepareAttributeSetData(
array_intersect_key($data, self::DEFAULT_ATTRIBUTE_SET_DATA)
Expand Down Expand Up @@ -201,6 +203,7 @@ private function applyAttributeWithAdditionalData(array $data = []): ?DataObject
private function prepareData(array $data): array
{
$data = array_merge(self::DEFAULT_DATA, $data);
$data['frontend_label'] ??= $data['default_frontend_label'];

return $this->dataProcessor->process($this, $data);
}
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,109 @@
<?php
/**
* Copyright © Magento, Inc. All rights reserved.
* See COPYING.txt for license details.
*/
declare(strict_types=1);

namespace Magento\Catalog\Test\Unit\Model\Indexer\Product\Price;

use Magento\Catalog\Helper\Data;
use Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\CustomOptionPriceModifier;
use Magento\Catalog\Model\ResourceModel\Product\Indexer\Price\IndexTableStructure;
use Magento\Framework\App\ResourceConnection;
use Magento\Framework\DB\Adapter\AdapterInterface;
use Magento\Framework\DB\Select;
use Magento\Framework\DB\Sql\ColumnValueExpressionFactory;
use Magento\Framework\EntityManager\EntityMetadataInterface;
use Magento\Framework\EntityManager\MetadataPool;
use Magento\Framework\Indexer\Table\StrategyInterface;
use PHPUnit\Framework\MockObject\MockObject;
use PHPUnit\Framework\TestCase;

class CustomOptionPriceModifierTest extends TestCase
{
/**
* @var ResourceConnection|MockObject
*/
private ResourceConnection $resource;

/**
* @var MetadataPool|MockObject
*/
private MetadataPool $metadataPool;

/**
* @var ColumnValueExpressionFactory|MockObject
*/
private ColumnValueExpressionFactory $columnValueExpressionFactory;

/**
* @var Data|MockObject
*/
private Data $dataHelper;

/**
* @var StrategyInterface|MockObject
*/
private StrategyInterface $tableStrategy;

/**
* @var CustomOptionPriceModifier
*/
private CustomOptionPriceModifier $priceModifier;

/**
* @return void
*/
protected function setUp(): void
{
$this->resource = $this->createMock(ResourceConnection::class);
$this->metadataPool = $this->createMock(MetadataPool::class);
$this->columnValueExpressionFactory = $this->createMock(ColumnValueExpressionFactory::class);
$this->dataHelper = $this->createMock(Data::class);
$this->tableStrategy = $this->createMock(StrategyInterface::class);
$this->priceModifier = new CustomOptionPriceModifier(
$this->resource,
$this->metadataPool,
$this->columnValueExpressionFactory,
$this->dataHelper,
$this->tableStrategy
);

parent::setUp();
}

/**
* @return void
* @throws \Exception
*/
public function testModifyPrice(): void
{
$priceTable = $this->createMock(IndexTableStructure::class);
$priceTable->expects($this->exactly(2))->method('getTableName')->willReturn('temporary_table_name');

$select = $this->createMock(Select::class);
$select->expects($this->any())->method('from')->willReturn($select);
$select->expects($this->any())->method('join')->willReturn($select);
$select->expects($this->any())->method('group')->willReturn($select);
$select->expects($this->any())->method('columns')->willReturn($select);

$connection = $this->createMock(AdapterInterface::class);
$connection->expects($this->exactly(2))->method('delete');
$connection->expects($this->any())->method('select')->willReturn($select);
$connection->expects($this->any())->method('fetchRow')->willReturn(['exists']);
$connection->expects($this->exactly(4))->method('query');
$connection->expects($this->exactly(2))->method('dropTemporaryTable');
$this->resource->expects($this->any())->method('getConnection')->willReturn($connection);
$this->resource->expects($this->any())->method('getTableName')->willReturn('table');
$this->tableStrategy->expects($this->any())
->method('getTableName')
->willReturn('table_name');

$metadata = $this->createMock(EntityMetadataInterface::class);
$this->metadataPool->expects($this->any())->method('getMetadata')->willReturn($metadata);
$this->dataHelper->expects($this->once())->method('isPriceGlobal')->willReturn(true);

$this->priceModifier->modifyPrice($priceTable);
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,8 @@ public function getOptions(array $optionIds, ?int $storeId, array $attributeCode
'attribute_code' => 'a.attribute_code',
'attribute_label' => 'a.frontend_label',
'attribute_type' => 'a.frontend_input',
'position' => 'attribute_configuration.position'
'position' => 'attribute_configuration.position',
'is_filterable' => 'attribute_configuration.is_filterable',
]
)
->joinLeft(
Expand Down Expand Up @@ -107,7 +108,7 @@ public function getOptions(array $optionIds, ?int $storeId, array $attributeCode
'options.sort_order ' . Select::SQL_ASC
);

$select->where('option_value.option_id IN (?)', $optionIds);
$select->where('option_value.option_id IN (?) OR attribute_configuration.is_filterable = 2', $optionIds);

if (!empty($attributeCodes)) {
$select->orWhere(
Expand Down Expand Up @@ -136,10 +137,10 @@ private function formatResult(Select $select): array
$result[$option['attribute_code']] = [
'attribute_id' => $option['attribute_id'],
'attribute_code' => $option['attribute_code'],
'attribute_label' => $option['attribute_store_label']
? $option['attribute_store_label'] : $option['attribute_label'],
'attribute_label' => $option['attribute_store_label'] ?: $option['attribute_label'],
'attribute_type' => $option['attribute_type'],
'position' => $option['position'],
'is_filterable' => (int) $option['is_filterable'],
'options' => [],
];
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@ class Attribute implements LayerBuilderInterface
*/
private const CATEGORY_BUCKET = 'category_bucket';

private const ATTRIBUTE_OPTIONS_ONLY_WITH_RESULTS = 1;

/**
* @var AttributeOptionProvider
*/
Expand Down Expand Up @@ -91,23 +93,21 @@ public function build(AggregationInterface $aggregation, ?int $storeId): array

$result[$bucketName] = $this->layerFormatter->buildLayer(
$attribute['attribute_label'] ?? $bucketName,
\count($bucket->getValues()),
0,
$attribute['attribute_code'] ?? $bucketName,
isset($attribute['position']) ? $attribute['position'] : null
);

$options = $this->getSortedOptions(
$bucket,
isset($attribute['options']) ? $attribute['options'] : [],
($attribute['attribute_type']) ? $attribute['attribute_type']: ''
);
foreach ($options as $option) {
$result[$bucketName]['options'][] = $this->layerFormatter->buildItem(
$option['label'],
$option['value'],
$option['count']
$optionLabels = $attribute['attribute_type'] === 'boolean'
? $this->YesNo->toArray()
: $attribute['options'] ?? [];
$result[$bucketName]['options'] = $this->getSortedOptions($bucket, $optionLabels);
if (self::ATTRIBUTE_OPTIONS_ONLY_WITH_RESULTS === $attribute['is_filterable']) {
$result[$bucketName]['options'] = array_filter(
$result[$bucketName]['options'],
fn ($option) => $option['count']
);
}
$result[$bucketName]['count'] = count($result[$bucketName]['options']);
}

return $result;
Expand Down Expand Up @@ -181,38 +181,24 @@ function (AggregationValueInterface $value) {
*
* @param BucketInterface $bucket
* @param array $optionLabels
* @param string $attributeType
* @return array
* @SuppressWarnings(PHPMD.UnusedLocalVariable)
*/
private function getSortedOptions(BucketInterface $bucket, array $optionLabels, string $attributeType): array
private function getSortedOptions(BucketInterface $bucket, array $optionLabels): array
{
$options = [];
/**
* Option labels array has been sorted
*/
$options = $optionLabels;
foreach ($optionLabels as $optionId => $optionLabel) {
$options[$optionId] = $this->layerFormatter->buildItem($optionLabel, $optionId, 0);
}
foreach ($bucket->getValues() as $value) {
$metrics = $value->getMetrics();
$optionValue = $metrics['value'];
if (isset($optionLabels[$optionValue])) {
$optionLabel = $optionLabels[$optionValue];
$optionId = $metrics['value'];
if (isset($options[$optionId])) {
$options[$optionId]['count'] = $metrics['count'];
} else {
if ($attributeType === 'boolean') {
$yesNoOptions = $this->YesNo->toArray();
$optionLabel = $yesNoOptions[$optionValue];
} else {
$optionLabel = $optionValue;
}
}
$options[$optionValue] = $metrics + ['label' => $optionLabel];
}

/**
* Delete options without bucket values
*/
foreach ($options as $optionId => $option) {
if (!is_array($options[$optionId])) {
unset($options[$optionId]);
$options[$optionId] = $this->layerFormatter->buildItem($optionId, $optionId, $metrics['count']);
}
}

Expand Down
10 changes: 5 additions & 5 deletions app/code/Magento/Search/Model/ResourceModel/Query/Collection.php
Original file line number Diff line number Diff line change
Expand Up @@ -150,9 +150,9 @@ public function setPopularQueryFilter($storeIds = null)

$storeIds = $storeIds ?: $this->_storeManager->getStore()->getId();
$this->addStoreFilter($storeIds);
$this->getSelect()->where('num_results > 0');
$this->getSelect()->where('main_table.num_results > 0');

$this->getSelect()->order(['popularity desc']);
$this->getSelect()->order(['main_table.popularity desc']);

return $this;
}
Expand All @@ -174,8 +174,8 @@ public function isTopSearchResult(string $term, int $storeId, int $maxCountCache
$select->distinct(true);
$select->from(['main_table' => $this->getTable('search_query')], ['query_text']);
$select->where('main_table.store_id IN (?)', $storeId);
$select->where('num_results > 0');
$select->order(['popularity desc']);
$select->where('main_table.num_results > 0');
$select->order(['main_table.popularity desc']);

$select->limit($maxCountCacheableSearchTerms);

Expand Down Expand Up @@ -208,7 +208,7 @@ public function setRecentQueryFilter()
public function addStoreFilter($storeIds)
{
$condition = is_array($storeIds) ? 'main_table.store_id IN (?)' : 'main_table.store_id = ?';
$this->getSelect()->where($condition, $storeIds);
$this->getSelect()->where($condition, $storeIds, \Zend_Db::INT_TYPE);

return $this;
}
Expand Down
Loading

0 comments on commit 2b3ad2e

Please sign in to comment.