Skip to content

Commit

Permalink
Merge branch '2.4-develop' of https://github.com/mage-os/mirror-magento2
Browse files Browse the repository at this point in the history
 into 2.4-develop
  • Loading branch information
mage-os-ci committed Oct 4, 2023
2 parents e8ebdf2 + 7f58418 commit 7dd3691
Show file tree
Hide file tree
Showing 42 changed files with 1,723 additions and 158 deletions.
16 changes: 12 additions & 4 deletions app/code/Magento/AwsS3/Driver/AwsS3.php
Original file line number Diff line number Diff line change
Expand Up @@ -893,16 +893,24 @@ public function fileClose($resource): bool
*/
public function fileOpen($path, $mode)
{
$_mode = str_replace(['b', '+'], '', strtolower($mode));
if (!in_array($_mode, ['r', 'w', 'a'], true)) {
throw new FileSystemException(new Phrase('Invalid file open mode "%1".', [$mode]));
}
$path = $this->normalizeRelativePath($path, true);

if (!isset($this->streams[$path])) {
$this->streams[$path] = tmpfile();
try {
if ($this->adapter->fileExists($path)) {
//phpcs:ignore Magento2.Functions.DiscouragedFunction
fwrite($this->streams[$path], $this->adapter->read($path));
//phpcs:ignore Magento2.Functions.DiscouragedFunction
rewind($this->streams[$path]);
if ($_mode !== 'w') {
//phpcs:ignore Magento2.Functions.DiscouragedFunction
fwrite($this->streams[$path], $this->adapter->read($path));
//phpcs:ignore Magento2.Functions.DiscouragedFunction
if ($_mode !== 'a') {
rewind($this->streams[$path]);
}
}
}
} catch (FlysystemFilesystemException $e) {
$this->logger->error($e->getMessage());
Expand Down
38 changes: 38 additions & 0 deletions app/code/Magento/AwsS3/Test/Unit/Driver/AwsS3Test.php
Original file line number Diff line number Diff line change
Expand Up @@ -537,4 +537,42 @@ public function testFileCloseShouldReturnFalseIfTheArgumentIsNotAResource(): voi
$this->assertEquals(false, $this->driver->fileClose(null));
$this->assertEquals(false, $this->driver->fileClose(false));
}

/**
* @dataProvider fileOpenModesDataProvider
*/
public function testFileOppenedMode($mode, $expected): void
{
$this->adapterMock->method('fileExists')->willReturn(true);
if ($mode !== 'w') {
$this->adapterMock->expects($this->once())->method('read')->willReturn('aaa');
} else {
$this->adapterMock->expects($this->never())->method('read');
}
$resource = $this->driver->fileOpen('test/path', $mode);
$this->assertEquals($expected, ftell($resource));
}

/**
* Data provider for testFileOppenedMode
*
* @return array[]
*/
public function fileOpenModesDataProvider(): array
{
return [
[
"mode" => "a",
"expected" => 3
],
[
"mode" => "r",
"expected" => 0
],
[
"mode" => "w",
"expected" => 0
]
];
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -9,11 +9,12 @@
use Magento\Catalog\Model\Product;
use Magento\Eav\Setup\EavSetup;
use Magento\Eav\Setup\EavSetupFactory;
use Magento\Framework\Exception\LocalizedException;
use Magento\Framework\DB\Adapter\AdapterInterface;
use Magento\Framework\Setup\ModuleDataSetupInterface;
use Magento\Framework\Setup\Patch\DataPatchInterface;
use Magento\Framework\Setup\Patch\NonTransactionableInterface;

class UpdateMultiselectAttributesBackendTypes implements DataPatchInterface
class UpdateMultiselectAttributesBackendTypes implements DataPatchInterface, NonTransactionableInterface
{
/**
* @var ModuleDataSetupInterface
Expand All @@ -24,6 +25,11 @@ class UpdateMultiselectAttributesBackendTypes implements DataPatchInterface
*/
private $eavSetupFactory;

/**
* @var array
*/
private $triggersRestoreQueries = [];

/**
* MigrateMultiselectAttributesData constructor.
* @param ModuleDataSetupInterface $dataSetup
Expand Down Expand Up @@ -61,6 +67,7 @@ public function apply()
$this->dataSetup->startSetup();
$setup = $this->dataSetup;
$connection = $setup->getConnection();
$this->triggersRestoreQueries = [];

$attributeTable = $setup->getTable('eav_attribute');
/** @var EavSetup $eavSetup */
Expand All @@ -74,26 +81,31 @@ public function apply()
->where('backend_type = ?', 'varchar')
->where('frontend_input = ?', 'multiselect')
);
$attributesToMigrate = array_map('intval', $attributesToMigrate);

$varcharTable = $setup->getTable('catalog_product_entity_varchar');
$textTable = $setup->getTable('catalog_product_entity_text');
$varcharTableDataSql = $connection
->select()
->from($varcharTable)
->where('attribute_id in (?)', $attributesToMigrate);

$columns = $connection->describeTable($varcharTable);
unset($columns['value_id']);
$connection->query(
$connection->insertFromSelect(
$connection->select()
->from($varcharTable, array_keys($columns))
->where('attribute_id in (?)', $attributesToMigrate),
$textTable,
array_keys($columns)
)
);
$connection->query($connection->deleteFromSelect($varcharTableDataSql, $varcharTable));
$this->dropTriggers($textTable);
$this->dropTriggers($varcharTable);
try {
$connection->query(
$connection->insertFromSelect(
$connection->select()
->from($varcharTable, array_keys($columns))
->where('attribute_id in (?)', $attributesToMigrate, \Zend_Db::INT_TYPE),
$textTable,
array_keys($columns),
AdapterInterface::INSERT_ON_DUPLICATE
)
);
$connection->delete($varcharTable, ['attribute_id IN (?)' => $attributesToMigrate]);
} finally {
$this->restoreTriggers($textTable);
$this->restoreTriggers($varcharTable);
}

foreach ($attributesToMigrate as $attributeId) {
$eavSetup->updateAttribute($entityTypeId, $attributeId, 'backend_type', 'text');
Expand All @@ -103,4 +115,48 @@ public function apply()

return $this;
}

/**
* Drop table triggers
*
* @param string $tableName
* @return void
* @throws \Zend_Db_Statement_Exception
*/
private function dropTriggers(string $tableName): void
{
$triggers = $this->dataSetup->getConnection()
->query('SHOW TRIGGERS LIKE \''. $tableName . '\'')
->fetchAll();

if (!$triggers) {
return;
}

foreach ($triggers as $trigger) {
$triggerData = $this->dataSetup->getConnection()
->query('SHOW CREATE TRIGGER '. $trigger['Trigger'])
->fetch();
$this->triggersRestoreQueries[$tableName][] =
preg_replace('/DEFINER=[^\s]*/', '', $triggerData['SQL Original Statement']);
// phpcs:ignore Magento2.SQL.RawQuery.FoundRawSql
$this->dataSetup->getConnection()->query('DROP TRIGGER IF EXISTS ' . $trigger['Trigger']);
}
}

/**
* Restore table triggers.
*
* @param string $tableName
* @return void
* @throws \Zend_Db_Statement_Exception
*/
private function restoreTriggers(string $tableName): void
{
if (array_key_exists($tableName, $this->triggersRestoreQueries)) {
foreach ($this->triggersRestoreQueries[$tableName] as $query) {
$this->dataSetup->getConnection()->multiQuery($query);
}
}
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,8 @@ public function testApply(): void
$select1 = $this->createMock(Select::class);
$select2 = $this->createMock(Select::class);
$select3 = $this->createMock(Select::class);
$statement = $this->createMock(\Zend_Db_Statement_Interface::class);

$this->eavSetupFactory->method('create')
->willReturn($eavSetup);
$this->dataSetup->method('getConnection')
Expand All @@ -65,7 +67,7 @@ public function testApply(): void
[$entityTypeId, 3, 'backend_type', 'text'],
[$entityTypeId, 7, 'backend_type', 'text']
);
$connection->expects($this->exactly(3))
$connection->expects($this->exactly(2))
->method('select')
->willReturnOnConsecutiveCalls($select1, $select2, $select3);
$connection->method('describeTable')
Expand All @@ -78,6 +80,10 @@ public function testApply(): void
'row_id' => [],
]
);
$connection->method('query')
->willReturn($statement);
$connection->method('fetchAll')
->willReturn([]);
$connection->method('fetchCol')
->with($select1)
->willReturn($attributeIds);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -18,7 +18,9 @@
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\Search\Request\Config as SearchConfig;

/**
* Build search criteria
Expand Down Expand Up @@ -46,6 +48,7 @@ class SearchCriteriaBuilder
* @var Builder
*/
private $builder;

/**
* @var Visibility
*/
Expand All @@ -61,14 +64,20 @@ class SearchCriteriaBuilder
*/
private Config $eavConfig;

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

/**
* @param Builder $builder
* @param ScopeConfigInterface $scopeConfig
* @param FilterBuilder $filterBuilder
* @param FilterGroupBuilder $filterGroupBuilder
* @param Visibility $visibility
* @param SortOrderBuilder $sortOrderBuilder
* @param Config $eavConfig
* @param SortOrderBuilder|null $sortOrderBuilder
* @param Config|null $eavConfig
* @param SearchConfig|null $searchConfig
*/
public function __construct(
Builder $builder,
Expand All @@ -77,7 +86,8 @@ public function __construct(
FilterGroupBuilder $filterGroupBuilder,
Visibility $visibility,
SortOrderBuilder $sortOrderBuilder = null,
Config $eavConfig = null
Config $eavConfig = null,
SearchConfig $searchConfig = null
) {
$this->scopeConfig = $scopeConfig;
$this->filterBuilder = $filterBuilder;
Expand All @@ -86,6 +96,7 @@ public function __construct(
$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);
}

/**
Expand All @@ -94,9 +105,15 @@ public function __construct(
* @param array $args
* @param bool $includeAggregation
* @return SearchCriteriaInterface
* @throws LocalizedException
*/
public function build(array $args, bool $includeAggregation): SearchCriteriaInterface
{
$partialMatchFilters = [];
if (isset($args['filter'])) {
$partialMatchFilters = $this->getPartialMatchFilters($args);
$args = $this->removeMatchTypeFromArguments($args);
}
$searchCriteria = $this->builder->build('products', $args);
$isSearch = isset($args['search']);
$this->updateRangeFilters($searchCriteria);
Expand All @@ -113,6 +130,10 @@ public function build(array $args, bool $includeAggregation): SearchCriteriaInte
}
$searchCriteria->setRequestName($requestName);

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

if ($isSearch) {
$this->addFilter($searchCriteria, 'search_term', $args['search']);
}
Expand All @@ -130,6 +151,63 @@ public function build(array $args, bool $includeAggregation): SearchCriteriaInte
return $searchCriteria;
}

/**
* Update dynamically the search match type based on requested params
*
* @param string $requestName
* @param array $partialMatchFilters
*
* @return void
*/
private function updateMatchTypeRequestConfig(string $requestName, array $partialMatchFilters): void
{
$data = $this->searchConfig->get($requestName);
foreach ($data['queries'] as $queryName => $query) {
foreach ($query['match'] ?? [] as $index => $matchItem) {
if (in_array($matchItem['field'] ?? null, $partialMatchFilters, true)) {
$data['queries'][$queryName]['match'][$index]['matchCondition'] = 'match_phrase_prefix';
}
}
}
$this->searchConfig->merge([$requestName => $data]);
}

/**
* Check if and what type of match_type value was requested
*
* @param array $args
*
* @return array
*/
private function getPartialMatchFilters(array $args): array
{
$partialMatchFilters = [];
foreach ($args['filter'] as $fieldName => $conditions) {
if (isset($conditions['match_type']) && $conditions['match_type'] === 'PARTIAL') {
$partialMatchFilters[] = $fieldName;
}
}
return $partialMatchFilters;
}

/**
* Remove the match_type to avoid search criteria containing it
*
* @param array $args
*
* @return array
*/
private function removeMatchTypeFromArguments(array $args): array
{
foreach ($args['filter'] as &$conditions) {
if (isset($conditions['match_type'])) {
unset($conditions['match_type']);
}
}

return $args;
}

/**
* Add filter by visibility
*
Expand Down
Loading

0 comments on commit 7dd3691

Please sign in to comment.